forked from bevyengine/bevy
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Curve
gizmos integration (bevyengine#14971)
# Objective - Add gizmos integration for the new `Curve` things in the math lib ## Solution - Add the following methods - `curve_2d(curve, sample_times, color)` - `curve_3d(curve, sample_times, color)` - `curve_gradient_2d(curve, sample_times_with_colors)` - `curve_gradient_3d(curve, sample_times_with_colors)` ## Testing - I added examples of the 2D and 3D variants of the gradient curve gizmos to the gizmos examples. ## Showcase ### 2D  ```rust let domain = Interval::EVERYWHERE; let curve = function_curve(domain, |t| Vec2::new(t, (t / 25.0).sin() * 100.0)); let resolution = ((time.elapsed_seconds().sin() + 1.0) * 50.0) as usize; let times_and_colors = (0..=resolution) .map(|n| n as f32 / resolution as f32) .map(|t| (t - 0.5) * 600.0) .map(|t| (t, TEAL.mix(&HOT_PINK, (t + 300.0) / 600.0))); gizmos.curve_gradient_2d(curve, times_and_colors); ``` ### 3D  ```rust let domain = Interval::EVERYWHERE; let curve = function_curve(domain, |t| { (Vec2::from((t * 10.0).sin_cos())).extend(t - 6.0) }); let resolution = ((time.elapsed_seconds().sin() + 1.0) * 100.0) as usize; let times_and_colors = (0..=resolution) .map(|n| n as f32 / resolution as f32) .map(|t| t * 5.0) .map(|t| (t, TEAL.mix(&HOT_PINK, t / 5.0))); gizmos.curve_gradient_3d(curve, times_and_colors); ```
- Loading branch information
Showing
5 changed files
with
197 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
//! Additional [`Gizmos`] Functions -- Curves | ||
//! | ||
//! Includes the implementation of [`Gizmos::curve_2d`], | ||
//! [`Gizmos::curve_3d`] and assorted support items. | ||
use bevy_color::Color; | ||
use bevy_math::{curve::Curve, Vec2, Vec3}; | ||
|
||
use crate::prelude::{GizmoConfigGroup, Gizmos}; | ||
|
||
impl<'w, 's, Config, Clear> Gizmos<'w, 's, Config, Clear> | ||
where | ||
Config: GizmoConfigGroup, | ||
Clear: 'static + Send + Sync, | ||
{ | ||
/// Draw a curve, at the given time points, sampling in 2D. | ||
/// | ||
/// This should be called for each frame the curve needs to be rendered. | ||
/// | ||
/// Samples of time points outside of the curve's domain will be filtered out and won't | ||
/// contribute to the rendering. If you wish to render the curve outside of its domain you need | ||
/// to create a new curve with an extended domain. | ||
/// | ||
/// # Arguments | ||
/// - `curve_2d` some type that implements the [`Curve`] trait and samples `Vec2`s | ||
/// - `times` some iterable type yielding `f32` which will be used for sampling the curve | ||
/// - `color` the color of the curve | ||
/// | ||
/// # Example | ||
/// ``` | ||
/// # use bevy_gizmos::prelude::*; | ||
/// # use bevy_math::prelude::*; | ||
/// # use bevy_color::palettes::basic::{RED}; | ||
/// fn system(mut gizmos: Gizmos) { | ||
/// let domain = Interval::UNIT; | ||
/// let curve = function_curve(domain, |t| Vec2::from(t.sin_cos())); | ||
/// gizmos.curve_2d(curve, (0..=100).map(|n| n as f32 / 100.0), RED); | ||
/// } | ||
/// # bevy_ecs::system::assert_is_system(system); | ||
/// ``` | ||
pub fn curve_2d( | ||
&mut self, | ||
curve_2d: impl Curve<Vec2>, | ||
times: impl IntoIterator<Item = f32>, | ||
color: impl Into<Color>, | ||
) { | ||
self.linestrip_2d(curve_2d.sample_iter(times).flatten(), color); | ||
} | ||
|
||
/// Draw a curve, at the given time points, sampling in 3D. | ||
/// | ||
/// This should be called for each frame the curve needs to be rendered. | ||
/// | ||
/// Samples of time points outside of the curve's domain will be filtered out and won't | ||
/// contribute to the rendering. If you wish to render the curve outside of its domain you need | ||
/// to create a new curve with an extended domain. | ||
/// | ||
/// # Arguments | ||
/// - `curve_3d` some type that implements the [`Curve`] trait and samples `Vec3`s | ||
/// - `times` some iterable type yielding `f32` which will be used for sampling the curve | ||
/// - `color` the color of the curve | ||
/// | ||
/// # Example | ||
/// ``` | ||
/// # use bevy_gizmos::prelude::*; | ||
/// # use bevy_math::prelude::*; | ||
/// # use bevy_color::palettes::basic::{RED}; | ||
/// fn system(mut gizmos: Gizmos) { | ||
/// let domain = Interval::UNIT; | ||
/// let curve = function_curve(domain, |t| { | ||
/// let (x,y) = t.sin_cos(); | ||
/// Vec3::new(x, y, t) | ||
/// }); | ||
/// gizmos.curve_3d(curve, (0..=100).map(|n| n as f32 / 100.0), RED); | ||
/// } | ||
/// # bevy_ecs::system::assert_is_system(system); | ||
/// ``` | ||
pub fn curve_3d( | ||
&mut self, | ||
curve_3d: impl Curve<Vec3>, | ||
times: impl IntoIterator<Item = f32>, | ||
color: impl Into<Color>, | ||
) { | ||
self.linestrip(curve_3d.sample_iter(times).flatten(), color); | ||
} | ||
|
||
/// Draw a curve, at the given time points, sampling in 2D, with a color gradient. | ||
/// | ||
/// This should be called for each frame the curve needs to be rendered. | ||
/// | ||
/// Samples of time points outside of the curve's domain will be filtered out and won't | ||
/// contribute to the rendering. If you wish to render the curve outside of its domain you need | ||
/// to create a new curve with an extended domain. | ||
/// | ||
/// # Arguments | ||
/// - `curve_2d` some type that implements the [`Curve`] trait and samples `Vec2`s | ||
/// - `times_with_colors` some iterable type yielding `f32` which will be used for sampling | ||
/// the curve together with the color at this position | ||
/// | ||
/// # Example | ||
/// ``` | ||
/// # use bevy_gizmos::prelude::*; | ||
/// # use bevy_math::prelude::*; | ||
/// # use bevy_color::{Mix, palettes::basic::{GREEN, RED}}; | ||
/// fn system(mut gizmos: Gizmos) { | ||
/// let domain = Interval::UNIT; | ||
/// let curve = function_curve(domain, |t| Vec2::from(t.sin_cos())); | ||
/// gizmos.curve_gradient_2d( | ||
/// curve, | ||
/// (0..=100).map(|n| n as f32 / 100.0) | ||
/// .map(|t| (t, GREEN.mix(&RED, t))) | ||
/// ); | ||
/// } | ||
/// # bevy_ecs::system::assert_is_system(system); | ||
/// ``` | ||
pub fn curve_gradient_2d<C>( | ||
&mut self, | ||
curve_2d: impl Curve<Vec2>, | ||
times_with_colors: impl IntoIterator<Item = (f32, C)>, | ||
) where | ||
C: Into<Color>, | ||
{ | ||
self.linestrip_gradient_2d( | ||
times_with_colors | ||
.into_iter() | ||
.filter_map(|(time, color)| curve_2d.sample(time).map(|sample| (sample, color))), | ||
); | ||
} | ||
|
||
/// Draw a curve, at the given time points, sampling in 3D, with a color gradient. | ||
/// | ||
/// This should be called for each frame the curve needs to be rendered. | ||
/// | ||
/// Samples of time points outside of the curve's domain will be filtered out and won't | ||
/// contribute to the rendering. If you wish to render the curve outside of its domain you need | ||
/// to create a new curve with an extended domain. | ||
/// | ||
/// # Arguments | ||
/// - `curve_3d` some type that implements the [`Curve`] trait and samples `Vec3`s | ||
/// - `times_with_colors` some iterable type yielding `f32` which will be used for sampling | ||
/// the curve together with the color at this position | ||
/// | ||
/// # Example | ||
/// ``` | ||
/// # use bevy_gizmos::prelude::*; | ||
/// # use bevy_math::prelude::*; | ||
/// # use bevy_color::{Mix, palettes::basic::{GREEN, RED}}; | ||
/// fn system(mut gizmos: Gizmos) { | ||
/// let domain = Interval::UNIT; | ||
/// let curve = function_curve(domain, |t| { | ||
/// let (x,y) = t.sin_cos(); | ||
/// Vec3::new(x, y, t) | ||
/// }); | ||
/// gizmos.curve_gradient_3d( | ||
/// curve, | ||
/// (0..=100).map(|n| n as f32 / 100.0) | ||
/// .map(|t| (t, GREEN.mix(&RED, t))) | ||
/// ); | ||
/// } | ||
/// # bevy_ecs::system::assert_is_system(system); | ||
/// ``` | ||
pub fn curve_gradient_3d<C>( | ||
&mut self, | ||
curve_3d: impl Curve<Vec3>, | ||
times_with_colors: impl IntoIterator<Item = (f32, C)>, | ||
) where | ||
C: Into<Color>, | ||
{ | ||
self.linestrip_gradient( | ||
times_with_colors | ||
.into_iter() | ||
.filter_map(|(time, color)| curve_3d.sample(time).map(|sample| (sample, color))), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters