//! Additional [`GizmoBuffer`] Functions -- Curves1//!2//! Includes the implementation of [`GizmoBuffer::curve_2d`],3//! [`GizmoBuffer::curve_3d`] and assorted support items.45use bevy_color::Color;6use bevy_math::{7curve::{Curve, CurveExt},8Vec2, Vec3,9};1011use crate::{gizmos::GizmoBuffer, prelude::GizmoConfigGroup};1213impl<Config, Clear> GizmoBuffer<Config, Clear>14where15Config: GizmoConfigGroup,16Clear: 'static + Send + Sync,17{18/// Draw a curve, at the given time points, sampling in 2D.19///20/// This should be called for each frame the curve needs to be rendered.21///22/// Samples of time points outside of the curve's domain will be filtered out and won't23/// contribute to the rendering. If you wish to render the curve outside of its domain you need24/// to create a new curve with an extended domain.25///26/// # Arguments27/// - `curve_2d` some type that implements the [`Curve`] trait and samples `Vec2`s28/// - `times` some iterable type yielding `f32` which will be used for sampling the curve29/// - `color` the color of the curve30///31/// # Example32/// ```33/// # use bevy_gizmos::prelude::*;34/// # use bevy_math::prelude::*;35/// # use bevy_color::palettes::basic::{RED};36/// fn system(mut gizmos: Gizmos) {37/// let domain = Interval::UNIT;38/// let curve = FunctionCurve::new(domain, |t| Vec2::from(t.sin_cos()));39/// gizmos.curve_2d(curve, (0..=100).map(|n| n as f32 / 100.0), RED);40/// }41/// # bevy_ecs::system::assert_is_system(system);42/// ```43pub fn curve_2d(44&mut self,45curve_2d: impl Curve<Vec2>,46times: impl IntoIterator<Item = f32>,47color: impl Into<Color>,48) {49self.linestrip_2d(curve_2d.sample_iter(times).flatten(), color);50}5152/// Draw a curve, at the given time points, sampling in 3D.53///54/// This should be called for each frame the curve needs to be rendered.55///56/// Samples of time points outside of the curve's domain will be filtered out and won't57/// contribute to the rendering. If you wish to render the curve outside of its domain you need58/// to create a new curve with an extended domain.59///60/// # Arguments61/// - `curve_3d` some type that implements the [`Curve`] trait and samples `Vec3`s62/// - `times` some iterable type yielding `f32` which will be used for sampling the curve63/// - `color` the color of the curve64///65/// # Example66/// ```67/// # use bevy_gizmos::prelude::*;68/// # use bevy_math::prelude::*;69/// # use bevy_color::palettes::basic::{RED};70/// fn system(mut gizmos: Gizmos) {71/// let domain = Interval::UNIT;72/// let curve = FunctionCurve::new(domain, |t| {73/// let (x,y) = t.sin_cos();74/// Vec3::new(x, y, t)75/// });76/// gizmos.curve_3d(curve, (0..=100).map(|n| n as f32 / 100.0), RED);77/// }78/// # bevy_ecs::system::assert_is_system(system);79/// ```80pub fn curve_3d(81&mut self,82curve_3d: impl Curve<Vec3>,83times: impl IntoIterator<Item = f32>,84color: impl Into<Color>,85) {86self.linestrip(curve_3d.sample_iter(times).flatten(), color);87}8889/// Draw a curve, at the given time points, sampling in 2D, with a color gradient.90///91/// This should be called for each frame the curve needs to be rendered.92///93/// Samples of time points outside of the curve's domain will be filtered out and won't94/// contribute to the rendering. If you wish to render the curve outside of its domain you need95/// to create a new curve with an extended domain.96///97/// # Arguments98/// - `curve_2d` some type that implements the [`Curve`] trait and samples `Vec2`s99/// - `times_with_colors` some iterable type yielding `f32` which will be used for sampling100/// the curve together with the color at this position101///102/// # Example103/// ```104/// # use bevy_gizmos::prelude::*;105/// # use bevy_math::prelude::*;106/// # use bevy_color::{Mix, palettes::basic::{GREEN, RED}};107/// fn system(mut gizmos: Gizmos) {108/// let domain = Interval::UNIT;109/// let curve = FunctionCurve::new(domain, |t| Vec2::from(t.sin_cos()));110/// gizmos.curve_gradient_2d(111/// curve,112/// (0..=100).map(|n| n as f32 / 100.0)113/// .map(|t| (t, GREEN.mix(&RED, t)))114/// );115/// }116/// # bevy_ecs::system::assert_is_system(system);117/// ```118pub fn curve_gradient_2d<C>(119&mut self,120curve_2d: impl Curve<Vec2>,121times_with_colors: impl IntoIterator<Item = (f32, C)>,122) where123C: Into<Color>,124{125self.linestrip_gradient_2d(126times_with_colors127.into_iter()128.filter_map(|(time, color)| curve_2d.sample(time).map(|sample| (sample, color))),129);130}131132/// Draw a curve, at the given time points, sampling in 3D, with a color gradient.133///134/// This should be called for each frame the curve needs to be rendered.135///136/// Samples of time points outside of the curve's domain will be filtered out and won't137/// contribute to the rendering. If you wish to render the curve outside of its domain you need138/// to create a new curve with an extended domain.139///140/// # Arguments141/// - `curve_3d` some type that implements the [`Curve`] trait and samples `Vec3`s142/// - `times_with_colors` some iterable type yielding `f32` which will be used for sampling143/// the curve together with the color at this position144///145/// # Example146/// ```147/// # use bevy_gizmos::prelude::*;148/// # use bevy_math::prelude::*;149/// # use bevy_color::{Mix, palettes::basic::{GREEN, RED}};150/// fn system(mut gizmos: Gizmos) {151/// let domain = Interval::UNIT;152/// let curve = FunctionCurve::new(domain, |t| {153/// let (x,y) = t.sin_cos();154/// Vec3::new(x, y, t)155/// });156/// gizmos.curve_gradient_3d(157/// curve,158/// (0..=100).map(|n| n as f32 / 100.0)159/// .map(|t| (t, GREEN.mix(&RED, t)))160/// );161/// }162/// # bevy_ecs::system::assert_is_system(system);163/// ```164pub fn curve_gradient_3d<C>(165&mut self,166curve_3d: impl Curve<Vec3>,167times_with_colors: impl IntoIterator<Item = (f32, C)>,168) where169C: Into<Color>,170{171self.linestrip_gradient(172times_with_colors173.into_iter()174.filter_map(|(time, color)| curve_3d.sample(time).map(|sample| (sample, color))),175);176}177}178179180