Implemented GizmoPrimitive2d for Arc2d, CircularSegment, CircularSector, and make arc_2d use counter-clockwise angle. (#13610)
# Objective Fixes #13606. Also Fixes #13614. ## Solution Added the missing trait impls, and made `gizmos.arc_2d()` work with a counter-clockwise angle. ## Testing - Updated the render_primitives example, and it works.
This commit is contained in:
parent
178959b53a
commit
4b996c75ab
@ -22,7 +22,7 @@ where
|
||||
///
|
||||
/// # Arguments
|
||||
/// - `position` sets the center of this circle.
|
||||
/// - `direction_angle` sets the clockwise angle in radians between `Vec2::Y` and
|
||||
/// - `direction_angle` sets the counter-clockwise angle in radians between `Vec2::Y` and
|
||||
/// the vector from `position` to the midpoint of the arc.
|
||||
/// - `arc_angle` sets the length of this arc, in radians.
|
||||
/// - `radius` controls the distance from `position` to this arc, and thus its curvature.
|
||||
@ -128,8 +128,10 @@ fn arc_2d_inner(
|
||||
(0..resolution + 1).map(move |i| {
|
||||
let start = direction_angle - arc_angle / 2.;
|
||||
|
||||
let angle = start + (i as f32 * (arc_angle / resolution as f32));
|
||||
Vec2::from(angle.sin_cos()) * radius
|
||||
let angle =
|
||||
start + (i as f32 * (arc_angle / resolution as f32)) + std::f32::consts::FRAC_PI_2;
|
||||
|
||||
Vec2::new(angle.cos(), angle.sin()) * radius
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -6,8 +6,9 @@ use super::helpers::*;
|
||||
|
||||
use bevy_color::Color;
|
||||
use bevy_math::primitives::{
|
||||
Annulus, BoxedPolygon, BoxedPolyline2d, Capsule2d, Circle, Ellipse, Line2d, Plane2d, Polygon,
|
||||
Polyline2d, Primitive2d, Rectangle, RegularPolygon, Rhombus, Segment2d, Triangle2d,
|
||||
Annulus, Arc2d, BoxedPolygon, BoxedPolyline2d, Capsule2d, Circle, CircularSector,
|
||||
CircularSegment, Ellipse, Line2d, Plane2d, Polygon, Polyline2d, Primitive2d, Rectangle,
|
||||
RegularPolygon, Rhombus, Segment2d, Triangle2d,
|
||||
};
|
||||
use bevy_math::{Dir2, Mat2, Vec2};
|
||||
|
||||
@ -64,6 +65,36 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// arc 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Arc2d> for Gizmos<'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a> = () where Self: 'a;
|
||||
|
||||
fn primitive_2d(
|
||||
&mut self,
|
||||
primitive: &Arc2d,
|
||||
position: Vec2,
|
||||
angle: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> Self::Output<'_> {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
self.arc_2d(
|
||||
position,
|
||||
angle,
|
||||
primitive.half_angle * 2.0,
|
||||
primitive.radius,
|
||||
color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// circle 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Circle> for Gizmos<'w, 's, Config, Clear>
|
||||
@ -88,6 +119,85 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// circular sector 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<CircularSector> for Gizmos<'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a> = () where Self: 'a;
|
||||
|
||||
fn primitive_2d(
|
||||
&mut self,
|
||||
primitive: &CircularSector,
|
||||
position: Vec2,
|
||||
angle: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> Self::Output<'_> {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
let color = color.into();
|
||||
|
||||
// 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,
|
||||
primitive.arc.half_angle * 2.0,
|
||||
primitive.arc.radius,
|
||||
color,
|
||||
);
|
||||
|
||||
let start = position
|
||||
+ primitive.arc.radius * Mat2::from_angle(angle - primitive.arc.half_angle) * Vec2::Y;
|
||||
let end = position
|
||||
+ primitive.arc.radius * Mat2::from_angle(angle + primitive.arc.half_angle) * Vec2::Y;
|
||||
self.line_2d(position, start, color);
|
||||
self.line_2d(position, end, color);
|
||||
}
|
||||
}
|
||||
|
||||
// circular segment 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<CircularSegment> for Gizmos<'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a> = () where Self: 'a;
|
||||
|
||||
fn primitive_2d(
|
||||
&mut self,
|
||||
primitive: &CircularSegment,
|
||||
position: Vec2,
|
||||
angle: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> Self::Output<'_> {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
let color = color.into();
|
||||
|
||||
// we need to draw the arc part of the segment, and the line connecting the two ends
|
||||
self.arc_2d(
|
||||
position,
|
||||
angle,
|
||||
primitive.arc.half_angle * 2.0,
|
||||
primitive.arc.radius,
|
||||
color,
|
||||
);
|
||||
|
||||
let start = position
|
||||
+ primitive.arc.radius * Mat2::from_angle(angle - primitive.arc.half_angle) * Vec2::Y;
|
||||
let end = position
|
||||
+ primitive.arc.radius * Mat2::from_angle(angle + primitive.arc.half_angle) * Vec2::Y;
|
||||
self.line_2d(end, start, color);
|
||||
}
|
||||
}
|
||||
|
||||
// ellipse 2d
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Ellipse> for Gizmos<'w, 's, Config, Clear>
|
||||
@ -192,8 +302,6 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
let rotation = Mat2::from_angle(angle);
|
||||
|
||||
// transform points from the reference unit square to capsule "rectangle"
|
||||
let [top_left, top_right, bottom_left, bottom_right, top_center, bottom_center] = [
|
||||
[-1.0, 1.0],
|
||||
@ -215,11 +323,8 @@ where
|
||||
self.line_2d(bottom_left, top_left, polymorphic_color);
|
||||
self.line_2d(bottom_right, top_right, polymorphic_color);
|
||||
|
||||
// if the capsule is rotated we have to start the arc at a different offset angle,
|
||||
// calculate that here
|
||||
let angle_offset = (rotation * Vec2::Y).angle_between(Vec2::Y);
|
||||
let start_angle_top = angle_offset;
|
||||
let start_angle_bottom = PI + angle_offset;
|
||||
let start_angle_top = angle;
|
||||
let start_angle_bottom = PI + angle;
|
||||
|
||||
// draw arcs
|
||||
self.arc_2d(
|
||||
|
||||
@ -85,6 +85,9 @@ enum PrimitiveSelected {
|
||||
ConicalFrustum,
|
||||
Torus,
|
||||
Tetrahedron,
|
||||
Arc,
|
||||
CircularSector,
|
||||
CircularSegment,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PrimitiveSelected {
|
||||
@ -99,7 +102,7 @@ impl std::fmt::Display for PrimitiveSelected {
|
||||
}
|
||||
|
||||
impl PrimitiveSelected {
|
||||
const ALL: [Self; 16] = [
|
||||
const ALL: [Self; 19] = [
|
||||
Self::RectangleAndCuboid,
|
||||
Self::CircleAndSphere,
|
||||
Self::Ellipse,
|
||||
@ -116,6 +119,9 @@ impl PrimitiveSelected {
|
||||
Self::ConicalFrustum,
|
||||
Self::Torus,
|
||||
Self::Tetrahedron,
|
||||
Self::Arc,
|
||||
Self::CircularSector,
|
||||
Self::CircularSegment,
|
||||
];
|
||||
|
||||
fn next(self) -> Self {
|
||||
@ -269,6 +275,25 @@ const TETRAHEDRON: Tetrahedron = Tetrahedron {
|
||||
],
|
||||
};
|
||||
|
||||
const ARC: Arc2d = Arc2d {
|
||||
radius: BIG_2D,
|
||||
half_angle: std::f32::consts::FRAC_PI_4,
|
||||
};
|
||||
|
||||
const CIRCULAR_SECTOR: CircularSector = CircularSector {
|
||||
arc: Arc2d {
|
||||
radius: BIG_2D,
|
||||
half_angle: std::f32::consts::FRAC_PI_4,
|
||||
},
|
||||
};
|
||||
|
||||
const CIRCULAR_SEGMENT: CircularSegment = CircularSegment {
|
||||
arc: Arc2d {
|
||||
radius: BIG_2D,
|
||||
half_angle: std::f32::consts::FRAC_PI_4,
|
||||
},
|
||||
};
|
||||
|
||||
fn setup_cameras(mut commands: Commands) {
|
||||
let start_in_2d = true;
|
||||
let make_camera = |is_active| Camera {
|
||||
@ -446,6 +471,13 @@ fn draw_gizmos_2d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time
|
||||
PrimitiveSelected::ConicalFrustum => {}
|
||||
PrimitiveSelected::Torus => gizmos.primitive_2d(&ANNULUS, POSITION, angle, color),
|
||||
PrimitiveSelected::Tetrahedron => {}
|
||||
PrimitiveSelected::Arc => gizmos.primitive_2d(&ARC, POSITION, angle, color),
|
||||
PrimitiveSelected::CircularSector => {
|
||||
gizmos.primitive_2d(&CIRCULAR_SECTOR, POSITION, angle, color);
|
||||
}
|
||||
PrimitiveSelected::CircularSegment => {
|
||||
gizmos.primitive_2d(&CIRCULAR_SEGMENT, POSITION, angle, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,5 +707,9 @@ fn draw_gizmos_3d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time
|
||||
PrimitiveSelected::Tetrahedron => {
|
||||
gizmos.primitive_3d(&TETRAHEDRON, POSITION, rotation, color);
|
||||
}
|
||||
|
||||
PrimitiveSelected::Arc => {}
|
||||
PrimitiveSelected::CircularSector => {}
|
||||
PrimitiveSelected::CircularSegment => {}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user