More gizmos builders (#13261)
# Objective - Add GizmoBuilders for some primitives as discussed in #13233 ## Solution - `gizmos.primitive_2d(CIRCLE)` and `gizmos.primitive_2d(ELLIPSE)` now return `Ellipse2dBuilder` aswell. - `gizmos.primitive_3d(SPHERE)` and `gizmos.sphere()` now return the same `SphereBuilder`. - the `.circle_segments` method on the `SphereBuilder` that used to be returned by `.sphere()` is now called `.segments` - the sphere primitive gizmo now matches the `gizmos.sphere` gizmo - `gizmos.primitive_2d(ANNULUS)` now returns a `Annulus2dBuilder` allowing the configuration of the `segments` - gizmos cylinders and capsules now have only 1 line per axis, similar to `gizmos.sphere` ## Migration Guide - Some `gizmos.primitive_nd` methods now return some or different builders. You may need to adjust types and match statements - Replace any calls to `circle_segments()` with `.segments()` --------- Co-authored-by: Raphael Büttgenbach <62256001+solis-lumine-vorago@users.noreply.github.com>
This commit is contained in:
parent
cca4fc76de
commit
e6a0f75a63
@ -178,6 +178,45 @@ where
|
||||
resolution: DEFAULT_CIRCLE_RESOLUTION,
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a wireframe sphere in 3D made out of 3 circles around the axes.
|
||||
///
|
||||
/// This should be called for each frame the sphere needs to be rendered.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use bevy_gizmos::prelude::*;
|
||||
/// # use bevy_render::prelude::*;
|
||||
/// # use bevy_math::prelude::*;
|
||||
/// # use bevy_color::Color;
|
||||
/// fn system(mut gizmos: Gizmos) {
|
||||
/// gizmos.sphere(Vec3::ZERO, Quat::IDENTITY, 1., Color::BLACK);
|
||||
///
|
||||
/// // Each circle has 32 line-segments by default.
|
||||
/// // You may want to increase this for larger spheres.
|
||||
/// gizmos
|
||||
/// .sphere(Vec3::ZERO, Quat::IDENTITY, 5., Color::BLACK)
|
||||
/// .resolution(64);
|
||||
/// }
|
||||
/// # bevy_ecs::system::assert_is_system(system);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn sphere(
|
||||
&mut self,
|
||||
position: Vec3,
|
||||
rotation: Quat,
|
||||
radius: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> SphereBuilder<'_, 'w, 's, Config, Clear> {
|
||||
SphereBuilder {
|
||||
gizmos: self,
|
||||
radius,
|
||||
position,
|
||||
rotation,
|
||||
color: color.into(),
|
||||
resolution: DEFAULT_CIRCLE_RESOLUTION,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder returned by [`Gizmos::ellipse`].
|
||||
@ -266,3 +305,66 @@ where
|
||||
self.gizmos.linestrip_2d(positions, self.color);
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder for configuring the drawing options of [`Sphere`].
|
||||
pub struct SphereBuilder<'a, 'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
|
||||
// Radius of the sphere
|
||||
radius: f32,
|
||||
|
||||
// Rotation of the sphere around the origin in 3D space
|
||||
rotation: Quat,
|
||||
// Center position of the sphere in 3D space
|
||||
position: Vec3,
|
||||
// Color of the sphere
|
||||
color: Color,
|
||||
|
||||
// Number of line-segments used to approximate the sphere geometry
|
||||
resolution: usize,
|
||||
}
|
||||
|
||||
impl<Config, Clear> SphereBuilder<'_, '_, '_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Set the number of line-segments used to approximate the sphere geometry.
|
||||
pub fn resolution(mut self, resolution: usize) -> Self {
|
||||
self.resolution = resolution;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for SphereBuilder<'_, '_, '_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
if !self.gizmos.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
let SphereBuilder {
|
||||
radius,
|
||||
position: center,
|
||||
rotation,
|
||||
color,
|
||||
resolution,
|
||||
..
|
||||
} = self;
|
||||
|
||||
// draws one great circle around each of the local axes
|
||||
Vec3::AXES.into_iter().for_each(|axis| {
|
||||
let normal = *rotation * axis;
|
||||
self.gizmos
|
||||
.circle(*center, Dir3::new_unchecked(normal), *radius, *color)
|
||||
.resolution(*resolution);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,14 +2,13 @@
|
||||
|
||||
use std::{iter, marker::PhantomData, mem};
|
||||
|
||||
use crate::circles::DEFAULT_CIRCLE_RESOLUTION;
|
||||
use bevy_color::{Color, LinearRgba};
|
||||
use bevy_ecs::{
|
||||
component::Tick,
|
||||
system::{Deferred, ReadOnlySystemParam, Res, Resource, SystemBuffer, SystemMeta, SystemParam},
|
||||
world::{unsafe_world_cell::UnsafeWorldCell, World},
|
||||
};
|
||||
use bevy_math::{Dir3, Quat, Rotation2d, Vec2, Vec3};
|
||||
use bevy_math::{Quat, Rotation2d, Vec2, Vec3};
|
||||
use bevy_transform::TransformPoint;
|
||||
use bevy_utils::default;
|
||||
|
||||
@ -459,45 +458,6 @@ where
|
||||
strip_colors.push(LinearRgba::NAN);
|
||||
}
|
||||
|
||||
/// Draw a wireframe sphere in 3D made out of 3 circles around the axes.
|
||||
///
|
||||
/// This should be called for each frame the sphere needs to be rendered.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
/// # use bevy_gizmos::prelude::*;
|
||||
/// # use bevy_render::prelude::*;
|
||||
/// # use bevy_math::prelude::*;
|
||||
/// # use bevy_color::Color;
|
||||
/// fn system(mut gizmos: Gizmos) {
|
||||
/// gizmos.sphere(Vec3::ZERO, Quat::IDENTITY, 1., Color::BLACK);
|
||||
///
|
||||
/// // Each circle has 32 line-segments by default.
|
||||
/// // You may want to increase this for larger spheres.
|
||||
/// gizmos
|
||||
/// .sphere(Vec3::ZERO, Quat::IDENTITY, 5., Color::BLACK)
|
||||
/// .resolution(64);
|
||||
/// }
|
||||
/// # bevy_ecs::system::assert_is_system(system);
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn sphere(
|
||||
&mut self,
|
||||
position: Vec3,
|
||||
rotation: Quat,
|
||||
radius: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> SphereBuilder<'_, 'w, 's, Config, Clear> {
|
||||
SphereBuilder {
|
||||
gizmos: self,
|
||||
position,
|
||||
rotation: rotation.normalize(),
|
||||
radius,
|
||||
color: color.into(),
|
||||
resolution: DEFAULT_CIRCLE_RESOLUTION,
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a wireframe rectangle in 3D.
|
||||
///
|
||||
/// This should be called for each frame the rectangle needs to be rendered.
|
||||
@ -790,49 +750,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder returned by [`Gizmos::sphere`].
|
||||
pub struct SphereBuilder<'a, 'w, 's, Config, Clear = ()>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
position: Vec3,
|
||||
rotation: Quat,
|
||||
radius: f32,
|
||||
color: Color,
|
||||
resolution: usize,
|
||||
}
|
||||
|
||||
impl<Config, Clear> SphereBuilder<'_, '_, '_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Set the number of line-segments per circle for this sphere.
|
||||
pub fn resolution(mut self, resolution: usize) -> Self {
|
||||
self.resolution = resolution;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for SphereBuilder<'_, '_, '_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
if !self.gizmos.enabled {
|
||||
return;
|
||||
}
|
||||
for axis in Dir3::AXES {
|
||||
self.gizmos
|
||||
.circle(self.position, self.rotation * axis, self.radius, self.color)
|
||||
.resolution(self.resolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn rect_inner(size: Vec2) -> [Vec2; 4] {
|
||||
let half_size = size / 2.;
|
||||
let tl = Vec2::new(-half_size.x, half_size.y);
|
||||
|
||||
@ -102,7 +102,7 @@ where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a> = () where Self: 'a;
|
||||
type Output<'a> = crate::circles::Ellipse2dBuilder<'a, 'w, 's, Config, Clear> where Self: 'a;
|
||||
|
||||
fn primitive_2d(
|
||||
&mut self,
|
||||
@ -111,11 +111,7 @@ where
|
||||
_angle: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> Self::Output<'_> {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
self.circle_2d(position, primitive.radius, color);
|
||||
self.circle_2d(position, primitive.radius, color)
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,46 +201,114 @@ where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a> = () where Self: 'a;
|
||||
type Output<'a> = crate::circles::Ellipse2dBuilder<'a, 'w, 's, Config, Clear> where Self: 'a;
|
||||
|
||||
fn primitive_2d(
|
||||
fn primitive_2d<'a>(
|
||||
&mut self,
|
||||
primitive: &Ellipse,
|
||||
position: Vec2,
|
||||
angle: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> Self::Output<'_> {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
self.ellipse_2d(position, angle, primitive.half_size, color);
|
||||
self.ellipse_2d(position, angle, primitive.half_size, color)
|
||||
}
|
||||
}
|
||||
|
||||
// annulus 2d
|
||||
|
||||
/// Builder for configuring the drawing options of [`Annulus`].
|
||||
pub struct Annulus2dBuilder<'a, 'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
position: Vec2,
|
||||
inner_radius: f32,
|
||||
outer_radius: f32,
|
||||
color: Color,
|
||||
inner_resolution: usize,
|
||||
outer_resolution: usize,
|
||||
}
|
||||
|
||||
impl<Config, Clear> Annulus2dBuilder<'_, '_, '_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Set the number of line-segments for each circle of the annulus.
|
||||
pub fn resolution(mut self, resolution: usize) -> Self {
|
||||
self.outer_resolution = resolution;
|
||||
self.inner_resolution = resolution;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the number of line-segments for the outer circle of the annulus.
|
||||
pub fn outer_resolution(mut self, resolution: usize) -> Self {
|
||||
self.outer_resolution = resolution;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the number of line-segments for the inner circle of the annulus.
|
||||
pub fn inner_resolution(mut self, resolution: usize) -> Self {
|
||||
self.inner_resolution = resolution;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive2d<Annulus> for Gizmos<'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
type Output<'a> = () where Self: 'a;
|
||||
type Output<'a> = Annulus2dBuilder<'a, 'w, 's, Config, Clear> where Self: 'a;
|
||||
|
||||
fn primitive_2d(
|
||||
&mut self,
|
||||
primitive: &Annulus,
|
||||
position: Vec2,
|
||||
angle: f32,
|
||||
_angle: f32,
|
||||
color: impl Into<Color>,
|
||||
) -> Self::Output<'_> {
|
||||
if !self.enabled {
|
||||
Annulus2dBuilder {
|
||||
gizmos: self,
|
||||
position,
|
||||
inner_radius: primitive.inner_circle.radius,
|
||||
outer_radius: primitive.outer_circle.radius,
|
||||
color: color.into(),
|
||||
inner_resolution: crate::circles::DEFAULT_CIRCLE_RESOLUTION,
|
||||
outer_resolution: crate::circles::DEFAULT_CIRCLE_RESOLUTION,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for Annulus2dBuilder<'_, '_, '_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
if !self.gizmos.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
let color = color.into();
|
||||
self.primitive_2d(&primitive.inner_circle, position, angle, color);
|
||||
self.primitive_2d(&primitive.outer_circle, position, angle, color);
|
||||
let Annulus2dBuilder {
|
||||
gizmos,
|
||||
position,
|
||||
inner_radius,
|
||||
outer_radius,
|
||||
inner_resolution,
|
||||
outer_resolution,
|
||||
color,
|
||||
..
|
||||
} = self;
|
||||
|
||||
gizmos
|
||||
.circle_2d(*position, *outer_radius, *color)
|
||||
.resolution(*outer_resolution);
|
||||
gizmos
|
||||
.circle_2d(*position, *inner_radius, *color)
|
||||
.resolution(*inner_resolution);
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,8 +330,7 @@ where
|
||||
) -> Self::Output<'_> {
|
||||
if !self.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
let [a, b, c, d] =
|
||||
[(1.0, 0.0), (0.0, 1.0), (-1.0, 0.0), (0.0, -1.0)].map(|(sign_x, sign_y)| {
|
||||
Vec2::new(
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
//! A module for rendering each of the 3D [`bevy_math::primitives`] with [`Gizmos`].
|
||||
|
||||
use super::helpers::*;
|
||||
use std::f32::consts::TAU;
|
||||
use std::f32::consts::{FRAC_PI_2, PI, TAU};
|
||||
|
||||
use bevy_color::Color;
|
||||
use bevy_math::primitives::{
|
||||
@ -10,6 +10,7 @@ use bevy_math::primitives::{
|
||||
};
|
||||
use bevy_math::{Dir3, Quat, Vec3};
|
||||
|
||||
use crate::circles::SphereBuilder;
|
||||
use crate::prelude::{GizmoConfigGroup, Gizmos};
|
||||
|
||||
const DEFAULT_RESOLUTION: usize = 5;
|
||||
@ -55,41 +56,6 @@ where
|
||||
|
||||
// sphere
|
||||
|
||||
/// Builder for configuring the drawing options of [`Sphere`].
|
||||
pub struct SphereBuilder<'a, 'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
gizmos: &'a mut Gizmos<'w, 's, Config, Clear>,
|
||||
|
||||
// Radius of the sphere
|
||||
radius: f32,
|
||||
|
||||
// Rotation of the sphere around the origin in 3D space
|
||||
rotation: Quat,
|
||||
// Center position of the sphere in 3D space
|
||||
position: Vec3,
|
||||
// Color of the sphere
|
||||
color: Color,
|
||||
|
||||
// Resolution of the gizmos used to approximate the sphere geometry
|
||||
// The number of vertices used to approximate the sphere geometry.
|
||||
resolution: usize,
|
||||
}
|
||||
|
||||
impl<Config, Clear> SphereBuilder<'_, '_, '_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
/// Set the number of lines used to approximate the sphere geometry.
|
||||
pub fn resolution(mut self, resolution: usize) -> Self {
|
||||
self.resolution = resolution;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'w, 's, Config, Clear> GizmoPrimitive3d<Sphere> for Gizmos<'w, 's, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
@ -104,59 +70,7 @@ where
|
||||
rotation: Quat,
|
||||
color: impl Into<Color>,
|
||||
) -> Self::Output<'_> {
|
||||
SphereBuilder {
|
||||
gizmos: self,
|
||||
radius: primitive.radius,
|
||||
position,
|
||||
rotation,
|
||||
color: color.into(),
|
||||
resolution: DEFAULT_RESOLUTION,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Config, Clear> Drop for SphereBuilder<'_, '_, '_, Config, Clear>
|
||||
where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
fn drop(&mut self) {
|
||||
if !self.gizmos.enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
let SphereBuilder {
|
||||
radius,
|
||||
position: center,
|
||||
rotation,
|
||||
color,
|
||||
resolution,
|
||||
..
|
||||
} = self;
|
||||
|
||||
// draws the upper and lower semi spheres
|
||||
[-1.0, 1.0].into_iter().for_each(|sign| {
|
||||
let top = *center + (*rotation * Vec3::Y) * sign * *radius;
|
||||
draw_semi_sphere(
|
||||
self.gizmos,
|
||||
*radius,
|
||||
*resolution,
|
||||
*rotation,
|
||||
*center,
|
||||
top,
|
||||
*color,
|
||||
);
|
||||
});
|
||||
|
||||
// draws one great circle of the sphere
|
||||
draw_circle_3d(
|
||||
self.gizmos,
|
||||
*radius,
|
||||
*resolution,
|
||||
*rotation,
|
||||
*center,
|
||||
*color,
|
||||
);
|
||||
self.sphere(position, rotation, primitive.radius, color)
|
||||
}
|
||||
}
|
||||
|
||||
@ -578,30 +492,27 @@ where
|
||||
resolution,
|
||||
} = self;
|
||||
|
||||
let normal = *rotation * Vec3::Y;
|
||||
let normal = Dir3::new_unchecked(*rotation * Vec3::Y);
|
||||
let up = normal.as_vec3() * *half_height;
|
||||
|
||||
// draw upper and lower circle of the cylinder
|
||||
[-1.0, 1.0].into_iter().for_each(|sign| {
|
||||
draw_circle_3d(
|
||||
gizmos,
|
||||
*radius,
|
||||
*resolution,
|
||||
*rotation,
|
||||
*position + sign * *half_height * normal,
|
||||
*color,
|
||||
);
|
||||
gizmos
|
||||
.circle(*position + sign * up, normal, *radius, *color)
|
||||
.resolution(*resolution);
|
||||
});
|
||||
|
||||
// draw lines connecting the two cylinder circles
|
||||
draw_cylinder_vertical_lines(
|
||||
gizmos,
|
||||
*radius,
|
||||
*resolution,
|
||||
*half_height,
|
||||
*rotation,
|
||||
*position,
|
||||
*color,
|
||||
);
|
||||
[Vec3::NEG_X, Vec3::NEG_Z, Vec3::X, Vec3::Z]
|
||||
.into_iter()
|
||||
.for_each(|axis| {
|
||||
let axis = *rotation * axis;
|
||||
gizmos.line(
|
||||
*position + up + axis * *radius,
|
||||
*position - up + axis * *radius,
|
||||
*color,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -691,26 +602,57 @@ where
|
||||
resolution,
|
||||
} = self;
|
||||
|
||||
let normal = *rotation * Vec3::Y;
|
||||
// Draw the circles at the top and bottom of the cylinder
|
||||
let y_offset = *rotation * Vec3::Y;
|
||||
gizmos
|
||||
.circle(
|
||||
*position + y_offset * *half_length,
|
||||
Dir3::new_unchecked(y_offset),
|
||||
*radius,
|
||||
*color,
|
||||
)
|
||||
.resolution(*resolution);
|
||||
gizmos
|
||||
.circle(
|
||||
*position - y_offset * *half_length,
|
||||
Dir3::new_unchecked(y_offset),
|
||||
*radius,
|
||||
*color,
|
||||
)
|
||||
.resolution(*resolution);
|
||||
let y_offset = y_offset * *half_length;
|
||||
|
||||
// draw two semi spheres for the capsule
|
||||
[1.0, -1.0].into_iter().for_each(|sign| {
|
||||
let center = *position + sign * *half_length * normal;
|
||||
let top = center + sign * *radius * normal;
|
||||
draw_semi_sphere(gizmos, *radius, *resolution, *rotation, center, top, *color);
|
||||
draw_circle_3d(gizmos, *radius, *resolution, *rotation, center, *color);
|
||||
// Draw the vertical lines and the cap semicircles
|
||||
[Vec3::X, Vec3::Z].into_iter().for_each(|axis| {
|
||||
let normal = *rotation * axis;
|
||||
|
||||
gizmos.line(
|
||||
*position + normal * *radius + y_offset,
|
||||
*position + normal * *radius - y_offset,
|
||||
*color,
|
||||
);
|
||||
gizmos.line(
|
||||
*position - normal * *radius + y_offset,
|
||||
*position - normal * *radius - y_offset,
|
||||
*color,
|
||||
);
|
||||
|
||||
let rotation = *rotation
|
||||
* Quat::from_euler(bevy_math::EulerRot::ZYX, 0., axis.z * FRAC_PI_2, FRAC_PI_2);
|
||||
|
||||
gizmos
|
||||
.arc_3d(PI, *radius, *position + y_offset, rotation, *color)
|
||||
.resolution(*resolution / 2);
|
||||
gizmos
|
||||
.arc_3d(
|
||||
PI,
|
||||
*radius,
|
||||
*position - y_offset,
|
||||
rotation * Quat::from_rotation_y(PI),
|
||||
*color,
|
||||
)
|
||||
.resolution(*resolution / 2);
|
||||
});
|
||||
|
||||
// connect the two semi spheres with lines
|
||||
draw_cylinder_vertical_lines(
|
||||
gizmos,
|
||||
*radius,
|
||||
*resolution,
|
||||
*half_length,
|
||||
*rotation,
|
||||
*position,
|
||||
*color,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -46,33 +46,6 @@ pub(crate) fn circle_coordinates(radius: f32, resolution: usize) -> impl Iterato
|
||||
.take(resolution)
|
||||
}
|
||||
|
||||
/// Draws a semi-sphere.
|
||||
///
|
||||
/// This function draws a semi-sphere at the specified `center` point with the given `rotation`,
|
||||
/// `radius`, and `color`. The `resolution` parameter determines the level of detail, and the `top`
|
||||
/// argument specifies the shape of the semi-sphere's tip.
|
||||
pub(crate) fn draw_semi_sphere<Config, Clear>(
|
||||
gizmos: &mut Gizmos<'_, '_, Config, Clear>,
|
||||
radius: f32,
|
||||
resolution: usize,
|
||||
rotation: Quat,
|
||||
center: Vec3,
|
||||
top: Vec3,
|
||||
color: Color,
|
||||
) where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
circle_coordinates(radius, resolution)
|
||||
.map(|p| Vec3::new(p.x, 0.0, p.y))
|
||||
.map(rotate_then_translate_3d(rotation, center))
|
||||
.for_each(|from| {
|
||||
gizmos
|
||||
.short_arc_3d_between(center, from, top, color)
|
||||
.resolution(resolution / 2);
|
||||
});
|
||||
}
|
||||
|
||||
/// Draws a circle in 3D space.
|
||||
///
|
||||
/// # Note
|
||||
@ -97,28 +70,3 @@ pub(crate) fn draw_circle_3d<Config, Clear>(
|
||||
.map(rotate_then_translate_3d(rotation, translation));
|
||||
gizmos.linestrip(positions, color);
|
||||
}
|
||||
|
||||
/// Draws the connecting lines of a cylinder between the top circle and the bottom circle.
|
||||
pub(crate) fn draw_cylinder_vertical_lines<Config, Clear>(
|
||||
gizmos: &mut Gizmos<'_, '_, Config, Clear>,
|
||||
radius: f32,
|
||||
resolution: usize,
|
||||
half_height: f32,
|
||||
rotation: Quat,
|
||||
center: Vec3,
|
||||
color: Color,
|
||||
) where
|
||||
Config: GizmoConfigGroup,
|
||||
Clear: 'static + Send + Sync,
|
||||
{
|
||||
circle_coordinates(radius, resolution)
|
||||
.map(move |point_2d| {
|
||||
[1.0, -1.0]
|
||||
.map(|sign| sign * half_height)
|
||||
.map(|height| Vec3::new(point_2d.x, height, point_2d.y))
|
||||
})
|
||||
.map(|ps| ps.map(rotate_then_translate_3d(rotation, center)))
|
||||
.for_each(|[start, end]| {
|
||||
gizmos.line(start, end, color);
|
||||
});
|
||||
}
|
||||
|
||||
@ -452,8 +452,10 @@ fn draw_gizmos_2d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time
|
||||
PrimitiveSelected::RectangleAndCuboid => {
|
||||
gizmos.primitive_2d(&RECTANGLE, POSITION, angle, color);
|
||||
}
|
||||
PrimitiveSelected::CircleAndSphere => gizmos.primitive_2d(&CIRCLE, POSITION, angle, color),
|
||||
PrimitiveSelected::Ellipse => gizmos.primitive_2d(&ELLIPSE, POSITION, angle, color),
|
||||
PrimitiveSelected::CircleAndSphere => {
|
||||
gizmos.primitive_2d(&CIRCLE, POSITION, angle, color);
|
||||
}
|
||||
PrimitiveSelected::Ellipse => drop(gizmos.primitive_2d(&ELLIPSE, POSITION, angle, color)),
|
||||
PrimitiveSelected::Triangle => gizmos.primitive_2d(&TRIANGLE_2D, POSITION, angle, color),
|
||||
PrimitiveSelected::Plane => gizmos.primitive_2d(&PLANE_2D, POSITION, angle, color),
|
||||
PrimitiveSelected::Line => drop(gizmos.primitive_2d(&LINE2D, POSITION, angle, color)),
|
||||
@ -469,7 +471,7 @@ fn draw_gizmos_2d(mut gizmos: Gizmos, state: Res<State<PrimitiveSelected>>, time
|
||||
PrimitiveSelected::Cylinder => {}
|
||||
PrimitiveSelected::Cone => {}
|
||||
PrimitiveSelected::ConicalFrustum => {}
|
||||
PrimitiveSelected::Torus => gizmos.primitive_2d(&ANNULUS, POSITION, angle, color),
|
||||
PrimitiveSelected::Torus => drop(gizmos.primitive_2d(&ANNULUS, POSITION, angle, color)),
|
||||
PrimitiveSelected::Tetrahedron => {}
|
||||
PrimitiveSelected::Arc => gizmos.primitive_2d(&ARC, POSITION, angle, color),
|
||||
PrimitiveSelected::CircularSector => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user