//! 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/// Samples of time points outside of the curve's domain will be filtered out and won't21/// contribute to the rendering. If you wish to render the curve outside of its domain you need22/// to create a new curve with an extended domain.23///24/// # Arguments25/// - `curve_2d` some type that implements the [`Curve`] trait and samples `Vec2`s26/// - `times` some iterable type yielding `f32` which will be used for sampling the curve27/// - `color` the color of the curve28///29/// # Example30/// ```31/// # use bevy_gizmos::prelude::*;32/// # use bevy_math::prelude::*;33/// # use bevy_color::palettes::basic::{RED};34/// fn system(mut gizmos: Gizmos) {35/// let domain = Interval::UNIT;36/// let curve = FunctionCurve::new(domain, |t| Vec2::from(t.sin_cos()));37/// gizmos.curve_2d(curve, (0..=100).map(|n| n as f32 / 100.0), RED);38/// }39/// # bevy_ecs::system::assert_is_system(system);40/// ```41pub fn curve_2d(42&mut self,43curve_2d: impl Curve<Vec2>,44times: impl IntoIterator<Item = f32>,45color: impl Into<Color>,46) {47self.linestrip_2d(curve_2d.sample_iter(times).flatten(), color);48}4950/// Draw a curve, at the given time points, sampling in 3D.51///52/// Samples of time points outside of the curve's domain will be filtered out and won't53/// contribute to the rendering. If you wish to render the curve outside of its domain you need54/// to create a new curve with an extended domain.55///56/// # Arguments57/// - `curve_3d` some type that implements the [`Curve`] trait and samples `Vec3`s58/// - `times` some iterable type yielding `f32` which will be used for sampling the curve59/// - `color` the color of the curve60///61/// # Example62/// ```63/// # use bevy_gizmos::prelude::*;64/// # use bevy_math::prelude::*;65/// # use bevy_color::palettes::basic::{RED};66/// fn system(mut gizmos: Gizmos) {67/// let domain = Interval::UNIT;68/// let curve = FunctionCurve::new(domain, |t| {69/// let (x,y) = t.sin_cos();70/// Vec3::new(x, y, t)71/// });72/// gizmos.curve_3d(curve, (0..=100).map(|n| n as f32 / 100.0), RED);73/// }74/// # bevy_ecs::system::assert_is_system(system);75/// ```76pub fn curve_3d(77&mut self,78curve_3d: impl Curve<Vec3>,79times: impl IntoIterator<Item = f32>,80color: impl Into<Color>,81) {82self.linestrip(curve_3d.sample_iter(times).flatten(), color);83}8485/// Draw a curve, at the given time points, sampling in 2D, with a color gradient.86///87/// Samples of time points outside of the curve's domain will be filtered out and won't88/// contribute to the rendering. If you wish to render the curve outside of its domain you need89/// to create a new curve with an extended domain.90///91/// # Arguments92/// - `curve_2d` some type that implements the [`Curve`] trait and samples `Vec2`s93/// - `times_with_colors` some iterable type yielding `f32` which will be used for sampling94/// the curve together with the color at this position95///96/// # Example97/// ```98/// # use bevy_gizmos::prelude::*;99/// # use bevy_math::prelude::*;100/// # use bevy_color::{Mix, palettes::basic::{GREEN, RED}};101/// fn system(mut gizmos: Gizmos) {102/// let domain = Interval::UNIT;103/// let curve = FunctionCurve::new(domain, |t| Vec2::from(t.sin_cos()));104/// gizmos.curve_gradient_2d(105/// curve,106/// (0..=100).map(|n| n as f32 / 100.0)107/// .map(|t| (t, GREEN.mix(&RED, t)))108/// );109/// }110/// # bevy_ecs::system::assert_is_system(system);111/// ```112pub fn curve_gradient_2d<C>(113&mut self,114curve_2d: impl Curve<Vec2>,115times_with_colors: impl IntoIterator<Item = (f32, C)>,116) where117C: Into<Color>,118{119self.linestrip_gradient_2d(120times_with_colors121.into_iter()122.filter_map(|(time, color)| curve_2d.sample(time).map(|sample| (sample, color))),123);124}125126/// Draw a curve, at the given time points, sampling in 3D, with a color gradient.127///128/// Samples of time points outside of the curve's domain will be filtered out and won't129/// contribute to the rendering. If you wish to render the curve outside of its domain you need130/// to create a new curve with an extended domain.131///132/// # Arguments133/// - `curve_3d` some type that implements the [`Curve`] trait and samples `Vec3`s134/// - `times_with_colors` some iterable type yielding `f32` which will be used for sampling135/// the curve together with the color at this position136///137/// # Example138/// ```139/// # use bevy_gizmos::prelude::*;140/// # use bevy_math::prelude::*;141/// # use bevy_color::{Mix, palettes::basic::{GREEN, RED}};142/// fn system(mut gizmos: Gizmos) {143/// let domain = Interval::UNIT;144/// let curve = FunctionCurve::new(domain, |t| {145/// let (x,y) = t.sin_cos();146/// Vec3::new(x, y, t)147/// });148/// gizmos.curve_gradient_3d(149/// curve,150/// (0..=100).map(|n| n as f32 / 100.0)151/// .map(|t| (t, GREEN.mix(&RED, t)))152/// );153/// }154/// # bevy_ecs::system::assert_is_system(system);155/// ```156pub fn curve_gradient_3d<C>(157&mut self,158curve_3d: impl Curve<Vec3>,159times_with_colors: impl IntoIterator<Item = (f32, C)>,160) where161C: Into<Color>,162{163self.linestrip_gradient(164times_with_colors165.into_iter()166.filter_map(|(time, color)| curve_3d.sample(time).map(|sample| (sample, color))),167);168}169}170171172