Commit Graph

5 Commits

Author SHA1 Message Date
Joona Aalto
6a3b059db9
Implement bounding volume intersections (#11439)
# Objective

#10946 added bounding volume types and an `IntersectsVolume` trait, but
didn't actually implement intersections between bounding volumes.

This PR implements AABB-AABB, circle-circle / sphere-sphere, and
AABB-circle / AABB-sphere intersections.

## Solution

Implement `IntersectsVolume` for bounding volume pairs. I also added
`closest_point` methods to return the closest point on the surface /
inside of bounding volumes. This is used for AABB-circle / AABB-sphere
intersections.

---------

Co-authored-by: IQuick 143 <IQuick143cz@gmail.com>
2024-01-22 17:55:59 +00:00
Doonv
0387331c12
Direction: Rename from_normalized to new_unchecked (#11425)
# Objective

`Direction2d::from_normalized` & `Direction3d::from_normalized` don't
emphasize that importance of the vector being normalized enough.

## Solution

Rename `from_normalized` to `new_unchecked` and add more documentation.

---

`Direction2d` and `Direction3d` were added somewhat recently in
https://github.com/bevyengine/bevy/pull/10466 (after 0.12), so I don't
think documenting the changelog and migration guide is necessary (Since
there is no major previous version to migrate from).

But here it is anyway in case it's needed:

## Changelog

- Renamed `Direction2d::from_normalized` and
`Direction3d::from_normalized` to `new_unchecked`.

## Migration Guide

- Renamed `Direction2d::from_normalized` and
`Direction3d::from_normalized` to `new_unchecked`.

---------

Co-authored-by: Tristan Guichaoua <33934311+tguichaoua@users.noreply.github.com>
Co-authored-by: Joona Aalto <jondolf.dev@gmail.com>
2024-01-20 21:52:09 +00:00
Joona Aalto
c31f3aa128
Add Aabb2d::new and Aabb3d::new constructors (#11433)
# Objective

Currently, the only way to create an AABB is to specify its `min` and
`max` coordinates. However, it's often more useful to use the center and
half-size instead.

## Solution

Add `new` constructors for `Aabb2d` and `Aabb3d`.

This:

```rust
let aabb = Aabb3d {
    min: center - half_size,
    max: center + half_size,
}
```

becomes this:

```rust
let aabb = Aabb3d::new(center, half_size);
```

I also made the usage of "half-extents" vs. "half-size" a bit more
consistent.
2024-01-20 20:12:20 +00:00
Joona Aalto
6337fb33ff
Improve Rectangle and Cuboid consistency (#11434)
# Objective

The `Rectangle` and `Cuboid` primitives currently use different
representations:

```rust
pub struct Rectangle {
    /// The half width of the rectangle
    pub half_width: f32,
    /// The half height of the rectangle
    pub half_height: f32,
}

pub struct Cuboid {
    /// Half of the width, height and depth of the cuboid
    pub half_extents: Vec3,
}
```

The property names and helpers are also inconsistent. `Cuboid` has
`half_extents`, but it also has a method called `from_size`. Most
existing code also uses "size" instead of "extents".

## Solution

Represent both `Rectangle` and `Cuboid` with `half_size` properties.
2024-01-20 18:03:47 +00:00
Joona Aalto
c62ad4b2c4
Implement bounding volumes for primitive shapes (#11336)
# Objective

Closes #10570.

#10946 added bounding volume types and traits, but didn't use them for
anything yet. This PR implements `Bounded2d` and `Bounded3d` for Bevy's
primitive shapes.

## Solution

Implement `Bounded2d` and `Bounded3d` for primitive shapes. This allows
computing AABBs and bounding circles/spheres for them.

For most shapes, there are several ways of implementing bounding
volumes. I took inspiration from [Parry's bounding
volumes](https://github.com/dimforge/parry/tree/master/src/bounding_volume),
[Inigo Quilez](http://iquilezles.org/articles/diskbbox/), and figured
out the rest myself using geometry. I tried to comment all slightly
non-trivial or unclear math to make it understandable.

Parry uses support mapping (finding the farthest point in some direction
for convex shapes) for some AABBs like cones, cylinders, and line
segments. This involves several quat operations and normalizations, so I
opted for the simpler and more efficient geometric approaches shown in
[Quilez's article](http://iquilezles.org/articles/diskbbox/).

Below you can see some of the bounding volumes working in 2D and 3D.
Note that I can't conveniently add these examples yet because they use
primitive shape meshing, which is still WIP.


https://github.com/bevyengine/bevy/assets/57632562/4465cbc6-285b-4c71-b62d-a2b3ee16f8b4


https://github.com/bevyengine/bevy/assets/57632562/94b4ac84-a092-46d7-b438-ce2e971496a4

---

## Changelog

- Implemented `Bounded2d`/`Bounded3d` for primitive shapes
- Added `from_point_cloud` method for bounding volumes (used by many
bounding implementations)
- Added `point_cloud_2d/3d_center` and `rotate_vec2` utility functions
- Added `RegularPolygon::vertices` method (used in regular polygon AABB
construction)
- Added `Triangle::circumcenter` method (used in triangle bounding
circle construction)
- Added bounding circle/sphere creation from AABBs and vice versa

## Extra

Do we want to implement `Bounded2d` for some "3D-ish" shapes too? For
example, capsules are sort of dimension-agnostic and useful for 2D, so I
think that would be good to implement. But a cylinder in 2D is just a
rectangle, and a cone is a triangle, so they wouldn't make as much sense
to me. A conical frustum would be an isosceles trapezoid, which could be
useful, but I'm not sure if computing the 2D AABB of a 3D frustum makes
semantic sense.
2024-01-18 15:55:36 +00:00