diff --git a/crates/bevy_gizmos/src/arcs.rs b/crates/bevy_gizmos/src/arcs.rs index 14c260dd30..1aa6b5c78a 100644 --- a/crates/bevy_gizmos/src/arcs.rs +++ b/crates/bevy_gizmos/src/arcs.rs @@ -6,8 +6,8 @@ use crate::circles::DEFAULT_CIRCLE_RESOLUTION; use crate::prelude::{GizmoConfigGroup, Gizmos}; use bevy_color::Color; -use bevy_math::{Quat, Vec2, Vec3}; -use std::f32::consts::TAU; +use bevy_math::{Isometry2d, Quat, Vec2, Vec3}; +use std::f32::consts::{FRAC_PI_2, TAU}; // === 2D === @@ -21,9 +21,9 @@ where /// This should be called for each frame the arc needs to be rendered. /// /// # Arguments - /// - `position` sets the center of this circle. - /// - `direction_angle` sets the counter-clockwise angle in radians between `Vec2::Y` and - /// the vector from `position` to the midpoint of the arc. + /// - `isometry` defines the translation and rotation of the arc. + /// - the translation specifies the center of the arc + /// - the rotation is counter-clockwise starting from `Vec2::Y` /// - `arc_angle` sets the length of this arc, in radians. /// - `radius` controls the distance from `position` to this arc, and thus its curvature. /// - `color` sets the color to draw the arc. @@ -32,15 +32,15 @@ where /// ``` /// # use bevy_gizmos::prelude::*; /// # use bevy_math::prelude::*; - /// # use std::f32::consts::PI; + /// # use std::f32::consts::FRAC_PI_4; /// # use bevy_color::palettes::basic::{GREEN, RED}; /// fn system(mut gizmos: Gizmos) { - /// gizmos.arc_2d(Vec2::ZERO, 0., PI / 4., 1., GREEN); + /// gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_4, 1., GREEN); /// /// // Arcs have 32 line-segments by default. /// // You may want to increase this for larger arcs. /// gizmos - /// .arc_2d(Vec2::ZERO, 0., PI / 4., 5., RED) + /// .arc_2d(Isometry2d::IDENTITY, FRAC_PI_4, 5., RED) /// .resolution(64); /// } /// # bevy_ecs::system::assert_is_system(system); @@ -48,16 +48,14 @@ where #[inline] pub fn arc_2d( &mut self, - position: Vec2, - direction_angle: f32, + isometry: Isometry2d, arc_angle: f32, radius: f32, color: impl Into, ) -> Arc2dBuilder<'_, 'w, 's, Config, Clear> { Arc2dBuilder { gizmos: self, - position, - direction_angle, + isometry, arc_angle, radius, color: color.into(), @@ -73,8 +71,7 @@ where Clear: 'static + Send + Sync, { gizmos: &'a mut Gizmos<'w, 's, Config, Clear>, - position: Vec2, - direction_angle: f32, + isometry: Isometry2d, arc_angle: f32, radius: f32, color: Color, @@ -107,31 +104,19 @@ where .resolution .unwrap_or_else(|| resolution_from_angle(self.arc_angle)); - let positions = arc_2d_inner( - self.direction_angle, - self.arc_angle, - self.radius, - resolution, - ) - .map(|vec2| (vec2 + self.position)); + let positions = + arc_2d_inner(self.arc_angle, self.radius, resolution).map(|vec2| self.isometry * vec2); self.gizmos.linestrip_2d(positions, self.color); } } -fn arc_2d_inner( - direction_angle: f32, - arc_angle: f32, - radius: f32, - resolution: u32, -) -> impl Iterator { - (0..resolution + 1).map(move |i| { - let start = direction_angle - arc_angle / 2.; - - let angle = - start + (i as f32 * (arc_angle / resolution as f32)) + std::f32::consts::FRAC_PI_2; - - Vec2::new(angle.cos(), angle.sin()) * radius - }) +fn arc_2d_inner(arc_angle: f32, radius: f32, resolution: u32) -> impl Iterator { + (0..=resolution) + .map(move |n| arc_angle * n as f32 / resolution as f32) + .map(|angle| angle + FRAC_PI_2) + .map(f32::sin_cos) + .map(|(sin, cos)| Vec2::new(cos, sin)) + .map(move |vec2| vec2 * radius) } // === 3D === diff --git a/crates/bevy_gizmos/src/primitives/dim2.rs b/crates/bevy_gizmos/src/primitives/dim2.rs index e05eaba645..f57904bb80 100644 --- a/crates/bevy_gizmos/src/primitives/dim2.rs +++ b/crates/bevy_gizmos/src/primitives/dim2.rs @@ -1,6 +1,6 @@ //! A module for rendering each of the 2D [`bevy_math::primitives`] with [`Gizmos`]. -use std::f32::consts::PI; +use std::f32::consts::{FRAC_PI_2, PI}; use super::helpers::*; @@ -10,7 +10,7 @@ use bevy_math::primitives::{ CircularSegment, Ellipse, Line2d, Plane2d, Polygon, Polyline2d, Primitive2d, Rectangle, RegularPolygon, Rhombus, Segment2d, Triangle2d, }; -use bevy_math::{Dir2, Mat2, Vec2}; +use bevy_math::{Dir2, Isometry2d, Mat2, Rot2, Vec2}; use crate::prelude::{GizmoConfigGroup, Gizmos}; @@ -86,8 +86,7 @@ where } self.arc_2d( - position, - angle, + Isometry2d::new(position, Rot2::radians(angle - primitive.half_angle)), primitive.half_angle * 2.0, primitive.radius, color, @@ -139,8 +138,7 @@ where // we need to draw the arc part of the sector, and the two lines connecting the arc and the center self.arc_2d( - position, - angle, + Isometry2d::new(position, Rot2::radians(angle - primitive.arc.half_angle)), primitive.arc.half_angle * 2.0, primitive.arc.radius, color, @@ -179,8 +177,7 @@ where // we need to draw the arc part of the segment, and the line connecting the two ends self.arc_2d( - position, - angle, + Isometry2d::new(position, Rot2::radians(angle - primitive.arc.half_angle)), primitive.arc.half_angle * 2.0, primitive.arc.radius, color, @@ -386,20 +383,18 @@ where self.line_2d(bottom_left, top_left, polymorphic_color); self.line_2d(bottom_right, top_right, polymorphic_color); - let start_angle_top = angle; - let start_angle_bottom = PI + angle; + let start_angle_top = angle - FRAC_PI_2; + let start_angle_bottom = angle + FRAC_PI_2; // draw arcs self.arc_2d( - top_center, - start_angle_top, + Isometry2d::new(top_center, Rot2::radians(start_angle_top)), PI, primitive.radius, polymorphic_color, ); self.arc_2d( - bottom_center, - start_angle_bottom, + Isometry2d::new(bottom_center, Rot2::radians(start_angle_bottom)), PI, primitive.radius, polymorphic_color, diff --git a/crates/bevy_math/src/lib.rs b/crates/bevy_math/src/lib.rs index b765a2759e..76ad5b06a7 100644 --- a/crates/bevy_math/src/lib.rs +++ b/crates/bevy_math/src/lib.rs @@ -57,9 +57,9 @@ pub mod prelude { }, direction::{Dir2, Dir3, Dir3A}, primitives::*, - BVec2, BVec3, BVec4, EulerRot, FloatExt, IRect, IVec2, IVec3, IVec4, Mat2, Mat3, Mat4, - Quat, Ray2d, Ray3d, Rect, Rot2, StableInterpolate, URect, UVec2, UVec3, UVec4, Vec2, - Vec2Swizzles, Vec3, Vec3Swizzles, Vec4, Vec4Swizzles, + BVec2, BVec3, BVec4, EulerRot, FloatExt, IRect, IVec2, IVec3, IVec4, Isometry2d, + Isometry3d, Mat2, Mat3, Mat4, Quat, Ray2d, Ray3d, Rect, Rot2, StableInterpolate, URect, + UVec2, UVec3, UVec4, Vec2, Vec2Swizzles, Vec3, Vec3Swizzles, Vec4, Vec4Swizzles, }; } diff --git a/examples/gizmos/2d_gizmos.rs b/examples/gizmos/2d_gizmos.rs index 830412e536..b935b2fb7a 100644 --- a/examples/gizmos/2d_gizmos.rs +++ b/examples/gizmos/2d_gizmos.rs @@ -1,8 +1,8 @@ //! This example demonstrates Bevy's immediate mode drawing API intended for visual debugging. -use std::f32::consts::{PI, TAU}; +use std::f32::consts::{FRAC_PI_2, PI, TAU}; -use bevy::{color::palettes::css::*, prelude::*}; +use bevy::{color::palettes::css::*, math::Isometry2d, prelude::*}; fn main() { App::new() @@ -87,7 +87,13 @@ fn draw_example_collection( // Arcs default resolution is linearly interpolated between // 1 and 32, using the arc length as scalar. - my_gizmos.arc_2d(Vec2::ZERO, sin / 10., PI / 2., 310., ORANGE_RED); + my_gizmos.arc_2d( + Isometry2d::from_rotation(Rot2::radians(sin / 10.)), + FRAC_PI_2, + 310., + ORANGE_RED, + ); + my_gizmos.arc_2d(Isometry2d::IDENTITY, FRAC_PI_2, 75.0, ORANGE_RED); gizmos.arrow_2d( Vec2::ZERO,