What problem does this solve or what need does it fill?
Bounding volumes such as Axis-Aligned Bounding Boxes (AABBs) and bounding spheres are commonly used to speed up broad phase collision detection, spatial queries, and even rendering, and they are also used in Bounding Volume Hierarchies (BVHs). They are very lightweight primitives that can be used for quickly computing intersections.
Primitive shapes were just added in #10466, and it would be very useful to be able to compute bounding volumes for them. This would facilitate the usage of primitive shapes for a lot more things and help unify the engine's APIs.
What solution would you like?
Note: This is just my rough proposal for the API. Details can and should be changed for the final implementation.
Add Aabb2d and Aabb3d primitives:
#[derive(Clone, Copy, Debug)]
pub struct Aabb2d {
mins: Vec2,
maxs: Vec2,
}
#[derive(Clone, Copy, Debug)]
pub struct Aabb3d {
mins: Vec3,
maxs: Vec3,
}
There could also be bounding spheres/circles:
#[derive(Clone, Copy, Debug)]
pub struct BoundingCircle {
center: Vec2,
circle: Circle,
}
#[derive(Clone, Copy, Debug)]
pub struct BoundingSphere {
center: Vec3,
sphere: Sphere,
}
(Oriented Bounding Boxes, or OBBs, could also be added, but they are less common)
Notice how these store the actual coordinates too. They will be required pretty much everywhere where bounding volumes are used (e.g. BVHs), so I think it's sensible to include. Feel free to correct me!
There could be a BoundingVolume trait shared by them:
pub trait BoundingVolume {
type Position: Clone + Copy + PartialEq;
/// Returns the center of the bounding volume.
fn center(&self) -> Self::Position;
/// Computes the surface area of the bounding volume.
fn area(&self) -> f32;
/// Checks if this bounding volume intersects another one.
fn intersects(&self, other: &Self) -> bool;
/// Checks if this bounding volume contains another one.
fn contains(&self, other: &Self) -> bool;
/// Computes the smallest bounding volume that contains both `self` and `other`.
fn merged(&self, other: &Self) -> Self;
/// Increases the size of this bounding volume by the given amount.
fn padded(&self, amount: &Self) -> Self;
// Note: Not a good name, we should come up with a better one
/// Decreases the size of this bounding volume by the given amount.
fn shrunk(&self, amount: &Self) -> Self;
}
Now, each shape primitive should have methods for computing the bounding volumes:
let capsule = Capsule::new(2.0, 0.6);
// AABB from capsule at origin with no rotation
let aabb = capsule.aabb_2d(Vec2::ZERO, 0.0);
These methods could be in traits like Bounded2d and Bounded3d:
pub trait Bounded2d {
fn aabb_2d(&self, translation: Vec2, rotation: f32) -> Aabb2d;
fn bounding_circle(&self, translation: Vec2) -> BoundingCircle;
}
pub trait Bounded3d {
fn aabb_3d(&self, translation: Vec3, rotation: Quat) -> Aabb3d;
fn bounding_sphere(&self, translation: Vec3) -> BoundingSphere;
}
Potential use cases
These bounding volumes could be used for a wide variety of things:
- Bounding volume hierarchies
- Collision detection (broad phase)
- Raycasting and other spatial queries
- Rendering optimization
- Mesh AABBs
- Probably a lot more
While these are already possible, it is very useful to have a unified set of bounding volumes that can be used for all of them and can be computed from the existing set of primitive shapes.
What problem does this solve or what need does it fill?
Bounding volumes such as Axis-Aligned Bounding Boxes (AABBs) and bounding spheres are commonly used to speed up broad phase collision detection, spatial queries, and even rendering, and they are also used in Bounding Volume Hierarchies (BVHs). They are very lightweight primitives that can be used for quickly computing intersections.
Primitive shapes were just added in #10466, and it would be very useful to be able to compute bounding volumes for them. This would facilitate the usage of primitive shapes for a lot more things and help unify the engine's APIs.
What solution would you like?
Note: This is just my rough proposal for the API. Details can and should be changed for the final implementation.
Add
Aabb2dandAabb3dprimitives:There could also be bounding spheres/circles:
(Oriented Bounding Boxes, or OBBs, could also be added, but they are less common)
Notice how these store the actual coordinates too. They will be required pretty much everywhere where bounding volumes are used (e.g. BVHs), so I think it's sensible to include. Feel free to correct me!
There could be a
BoundingVolumetrait shared by them:Now, each shape primitive should have methods for computing the bounding volumes:
These methods could be in traits like
Bounded2dandBounded3d:Potential use cases
These bounding volumes could be used for a wide variety of things:
While these are already possible, it is very useful to have a unified set of bounding volumes that can be used for all of them and can be computed from the existing set of primitive shapes.