3个版本 (破坏性更新)

0.2.0 2024年7月8日
0.1.0 2024年3月6日
0.0.1 2023年11月16日

#347 in 游戏开发

Download history 67/week @ 2024-07-02 59/week @ 2024-07-09

每月125次下载

MIT/Apache

25KB
535

ploc-bvh

基于PLOC的包围体积分层。受Arsène Pérard-Gayot的一系列文章的启发

此包使用BoundingVolumeIntersectsVolume特性,这些特性来自bevy_math,以实现其大部分功能。由于bevy_math不依赖于bevy引擎的其他部分,因此它也可以用于非bevy项目。

可以使用实现bevy_mathBoundingVolumes和此包的BvhVolume的任何类型来构建BVH,提供了一些类型别名用于bevy_math的内置类型,这些可以在preludedim2/dim3模块中找到。可以使用实现bevy_mathIntersectsVolume的任何类型来遍历BVH,其中一些类型由bevy_math提供,包括用于内置体积之间的重叠、光线投射和体积投射。

入门

创建和遍历BVH可以完全使用Iterator来完成。

在这个例子中,我们为几个盒子创建AABB,并使用它们的索引作为键,然后遍历BVH

# use ploc_bvh::prelude::*;
use bevy_math::{bounding::{Aabb3d, RayCast3d}, prelude::{Dir3, Vec3}};

// We have some list of axis-aligned bounding boxes
let boxes = [
    Aabb3d::new(Vec3::ONE, Vec3::ONE),
    Aabb3d::new(Vec3::NEG_Y, Vec3::splat(2.)),
];

// We build a 3D BVH using the number of boxes, and an iterator of (T, Aabb3d).
// T can be whatever type we need, but it most likely includes some identifier,
// and maybe some information to filter results quickly.
let bvh = BvhAabb3d::new(
    boxes.len(),
    // We use the index of the box as our T here, so we can find it later
    boxes.iter().enumerate().map(|(i, aabb)| (i, *aabb)),
);

// Next we want to traverse the BVH, to do this we need a stack and an intersection test.

// We can create a stack, this type can be reused to save some allocs if necessary.
let mut stack = bvh.create_stack();

// We construct a bounding volume intersection test, a raycast in this case
let origin = Vec3::ZERO;
let direction = Dir3::Y;
let max_time_of_impact = 1.;
let ray_cast = RayCast3d::new(origin, direction, max_time_of_impact);

// Now we can iterate over the BVH using the `traverse` method
for &index in bvh.traverse(&mut stack, ray_cast) {
    // The value returned from `traverse` matches the T used when constructing the BVH
    println!("We hit box {}: {:?}", index, boxes[index]);
}

未来工作

  • 真正支持并行化

许可

此存储库中的所有代码都根据您的要求在以下两种许可协议下双许可

进行选择。

依赖关系

~4.5MB
~120K SLoC