Skip to content
158 changes: 158 additions & 0 deletions crates/bevy_math/src/direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ impl Dir2 {
pub const NEG_Y: Self = Self(Vec2::NEG_Y);
/// The directional axes.
pub const AXES: [Self; 2] = [Self::X, Self::Y];
/// The cardinal directions.
pub const CARDINALS: [Self; 4] = [Self::X, Self::NEG_X, Self::Y, Self::NEG_Y];

/// The "north" direction, equivalent to [`Dir2::Y`].
pub const NORTH: Self = Self(Vec2::Y);
Expand All @@ -125,6 +127,25 @@ impl Dir2 {
/// The "south-west" direction, between [`Dir2::SOUTH`] and [`Dir2::WEST`].
pub const SOUTH_WEST: Self = Self(Vec2::new(-FRAC_1_SQRT_2, -FRAC_1_SQRT_2));

/// The diagonals between the cardinal directions.
pub const DIAGONALS: [Self; 4] = [
Self::NORTH_EAST,
Self::NORTH_WEST,
Self::SOUTH_EAST,
Self::SOUTH_WEST,
];
/// All neighbors of a tile on a square grid in a 3x3 neighborhood. A combination of [`Self::CARDINALS`] and [`Self::DIAGONALS`]
pub const ALL_NEIGHBORS: [Self; 8] = [
Self::X,
Self::NEG_X,
Self::Y,
Self::NEG_Y,
Self::NORTH_EAST,
Self::NORTH_WEST,
Self::SOUTH_EAST,
Self::SOUTH_WEST,
];

/// Create a direction from a finite, nonzero [`Vec2`], normalizing it.
///
/// Returns [`Err(InvalidDirectionError)`](InvalidDirectionError) if the length
Expand Down Expand Up @@ -395,6 +416,143 @@ impl Dir3 {
pub const NEG_Z: Self = Self(Vec3::NEG_Z);
/// The directional axes.
pub const AXES: [Self; 3] = [Self::X, Self::Y, Self::Z];
/// The cardinal directions.
pub const CARDINALS: [Self; 6] = [
Self::X,
Self::NEG_X,
Self::Y,
Self::NEG_Y,
Self::Z,
Self::NEG_Z,
];

// Adding this allow here to make sure that the precision in FRAC_1_SQRT_2
// and here is the same
#[expect(
clippy::excessive_precision,
reason = "compatibility with the unstable rust definition"
)]
/// Approximation of 1/sqrt(3) needed for the diagonals in 3D space
const FRAC_1_SQRT_3: f32 = 0.577350269189625764509148780501957456_f32;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit weird, since an f32 can't hold more than about 7 digits of precision, but I don't know if there's maybe another reason to want an extra-precise constant definition.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these excessively long definitions are copied from the rust std::f32::consts, but I'm unsure why they would be there in the first place

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i propose to keep this definition for now for the sake of consistency with the rust stdlib, so that when the FRAC_1_SQRT_3 gets stabilized we can just switch over to that and be certain that there's no weird behavior from unexpected changes

/// The directions pointing towards the vertices of a cube centered at the origin.
pub const ALL_VERTICES: [Self; 8] = [
Self(Vec3::new(
Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
-Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
-Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
-Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
-Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
)),
];
/// The directions towards centers of each edge of a cube
pub const ALL_EDGES: [Self; 12] = [
Self(Vec3::new(FRAC_1_SQRT_2, FRAC_1_SQRT_2, 0.)),
Self(Vec3::new(-FRAC_1_SQRT_2, FRAC_1_SQRT_2, 0.)),
Self(Vec3::new(FRAC_1_SQRT_2, -FRAC_1_SQRT_2, 0.)),
Self(Vec3::new(-FRAC_1_SQRT_2, -FRAC_1_SQRT_2, 0.)),
Self(Vec3::new(FRAC_1_SQRT_2, 0., FRAC_1_SQRT_2)),
Self(Vec3::new(-FRAC_1_SQRT_2, 0., FRAC_1_SQRT_2)),
Self(Vec3::new(FRAC_1_SQRT_2, 0., -FRAC_1_SQRT_2)),
Self(Vec3::new(-FRAC_1_SQRT_2, 0., -FRAC_1_SQRT_2)),
Self(Vec3::new(0., FRAC_1_SQRT_2, FRAC_1_SQRT_2)),
Self(Vec3::new(0., -FRAC_1_SQRT_2, FRAC_1_SQRT_2)),
Self(Vec3::new(0., FRAC_1_SQRT_2, -FRAC_1_SQRT_2)),
Self(Vec3::new(0., -FRAC_1_SQRT_2, -FRAC_1_SQRT_2)),
];
/// All neighbors of a tile on a cube grid a 3x3x3 neighborhood. A combination of [`Self::CARDINALS`], [`Self::ALL_EDGES`] and [`Self::ALL_VERTICES`]
pub const ALL_NEIGHBORS: [Self; 26] = [
Self::X,
Self::NEG_X,
Self::Y,
Self::NEG_Y,
Self::Z,
Self::NEG_Z,
Self(Vec3::new(FRAC_1_SQRT_2, FRAC_1_SQRT_2, 0.)),
Self(Vec3::new(-FRAC_1_SQRT_2, FRAC_1_SQRT_2, 0.)),
Self(Vec3::new(FRAC_1_SQRT_2, -FRAC_1_SQRT_2, 0.)),
Self(Vec3::new(-FRAC_1_SQRT_2, -FRAC_1_SQRT_2, 0.)),
Self(Vec3::new(FRAC_1_SQRT_2, 0., FRAC_1_SQRT_2)),
Self(Vec3::new(-FRAC_1_SQRT_2, 0., FRAC_1_SQRT_2)),
Self(Vec3::new(FRAC_1_SQRT_2, 0., -FRAC_1_SQRT_2)),
Self(Vec3::new(-FRAC_1_SQRT_2, 0., -FRAC_1_SQRT_2)),
Self(Vec3::new(0., FRAC_1_SQRT_2, FRAC_1_SQRT_2)),
Self(Vec3::new(0., -FRAC_1_SQRT_2, FRAC_1_SQRT_2)),
Self(Vec3::new(0., FRAC_1_SQRT_2, -FRAC_1_SQRT_2)),
Self(Vec3::new(0., -FRAC_1_SQRT_2, -FRAC_1_SQRT_2)),
Self(Vec3::new(
Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
-Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
-Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
-Self::FRAC_1_SQRT_3,
Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
)),
Self(Vec3::new(
-Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
-Self::FRAC_1_SQRT_3,
)),
];

/// Create a direction from a finite, nonzero [`Vec3`], normalizing it.
///
Expand Down