Add sample_clamped method to animation curves, returning Boxed values

This commit is contained in:
Manuel Brea 2024-11-15 12:12:45 +00:00
parent 5cbc2a9018
commit 85fc54f4f9

View file

@ -81,6 +81,7 @@ use core::{
fmt::{self, Debug, Formatter}, fmt::{self, Debug, Formatter},
marker::PhantomData, marker::PhantomData,
}; };
use std::any::Any;
use bevy_ecs::{component::Component, world::Mut}; use bevy_ecs::{component::Component, world::Mut};
use bevy_math::{ use bevy_math::{
@ -209,6 +210,21 @@ where
phantom: PhantomData<P>, phantom: PhantomData<P>,
} }
pub struct AnimatableCurveSample {
pub component_type: TypeId,
pub property_type: TypeId,
pub get_mut_boxed: fn(&mut dyn Any) -> Option<&mut dyn Reflect>,
pub value: Box<dyn Reflect>,
}
fn get_mut_boxed<P: AnimatableProperty>(component: &mut dyn Any) -> Option<&mut dyn Reflect> {
if let Some(component) = component.downcast_mut::<P::Component>() {
P::get_mut(component).map(|p| p.as_reflect_mut())
} else {
panic!("Type mismatch")
}
}
impl<P, C> AnimatableCurve<P, C> impl<P, C> AnimatableCurve<P, C>
where where
P: AnimatableProperty, P: AnimatableProperty,
@ -294,6 +310,17 @@ where
}); });
Ok(()) Ok(())
} }
fn sample_clamped(&self, t: f32) -> Box<dyn Any> {
let value = self.curve.sample_clamped(t);
Box::new(AnimatableCurveSample {
component_type: TypeId::of::<P::Component>(),
property_type: TypeId::of::<P::Property>(),
get_mut_boxed: get_mut_boxed::<P>,
value: Box::new(value),
})
}
} }
impl<P> AnimationCurveEvaluator for AnimatableCurveEvaluator<P> impl<P> AnimationCurveEvaluator for AnimatableCurveEvaluator<P>
@ -353,6 +380,14 @@ pub struct TranslationCurveEvaluator {
evaluator: BasicAnimationCurveEvaluator<Vec3>, evaluator: BasicAnimationCurveEvaluator<Vec3>,
} }
/// Type indicating that the sampled value from an animation curve is coming from a
/// [`TranslationCurve`].
///
/// You shouldn't need to interact with this type unless you're manually evaluating animation
/// curves.
#[derive(Reflect)]
pub struct TranslationCurveSample(Vec3);
impl<C> AnimationCurve for TranslationCurve<C> impl<C> AnimationCurve for TranslationCurve<C>
where where
C: AnimationCompatibleCurve<Vec3>, C: AnimationCompatibleCurve<Vec3>,
@ -396,6 +431,12 @@ where
}); });
Ok(()) Ok(())
} }
fn sample_clamped(&self, t: f32) -> Box<dyn Any> {
let value = self.0.sample_clamped(t);
Box::new(TranslationCurveSample(value))
}
} }
impl AnimationCurveEvaluator for TranslationCurveEvaluator { impl AnimationCurveEvaluator for TranslationCurveEvaluator {
@ -450,6 +491,14 @@ pub struct RotationCurveEvaluator {
evaluator: BasicAnimationCurveEvaluator<Quat>, evaluator: BasicAnimationCurveEvaluator<Quat>,
} }
/// Type indicating that the sampled value from an animation curve is coming from a
/// [`RotationCurve`].
///
/// You shouldn't need to interact with this type unless you're manually evaluating animation
/// curves.
#[derive(Reflect)]
pub struct RotationCurveSample(Quat);
impl<C> AnimationCurve for RotationCurve<C> impl<C> AnimationCurve for RotationCurve<C>
where where
C: AnimationCompatibleCurve<Quat>, C: AnimationCompatibleCurve<Quat>,
@ -493,6 +542,12 @@ where
}); });
Ok(()) Ok(())
} }
fn sample_clamped(&self, t: f32) -> Box<dyn Any> {
let value = self.0.sample_clamped(t);
Box::new(RotationCurveSample(value))
}
} }
impl AnimationCurveEvaluator for RotationCurveEvaluator { impl AnimationCurveEvaluator for RotationCurveEvaluator {
@ -547,6 +602,14 @@ pub struct ScaleCurveEvaluator {
evaluator: BasicAnimationCurveEvaluator<Vec3>, evaluator: BasicAnimationCurveEvaluator<Vec3>,
} }
/// Type indicating that the sampled value from an animation curve is coming from a
/// [`ScaleCurve`].
///
/// You shouldn't need to interact with this type unless you're manually evaluating animation
/// curves.
#[derive(Reflect)]
pub struct ScaleCurveSample(Vec3);
impl<C> AnimationCurve for ScaleCurve<C> impl<C> AnimationCurve for ScaleCurve<C>
where where
C: AnimationCompatibleCurve<Vec3>, C: AnimationCompatibleCurve<Vec3>,
@ -590,6 +653,12 @@ where
}); });
Ok(()) Ok(())
} }
fn sample_clamped(&self, t: f32) -> Box<dyn Any> {
let value = self.0.sample_clamped(t);
Box::new(ScaleCurveSample(value))
}
} }
impl AnimationCurveEvaluator for ScaleCurveEvaluator { impl AnimationCurveEvaluator for ScaleCurveEvaluator {
@ -671,6 +740,14 @@ struct WeightsCurveEvaluator {
morph_target_count: Option<u32>, morph_target_count: Option<u32>,
} }
/// Type indicating that the sampled value from an animation curve is coming from a
/// [`ScaleCurve`].
///
/// You shouldn't need to interact with this type unless you're manually evaluating animation
/// curves.
#[derive(Reflect)]
pub struct WeightsCurveSample(Vec<f32>);
impl<C> AnimationCurve for WeightsCurve<C> impl<C> AnimationCurve for WeightsCurve<C>
where where
C: IterableCurve<f32> + Debug + Clone + Reflectable, C: IterableCurve<f32> + Debug + Clone + Reflectable,
@ -722,6 +799,12 @@ where
.push((weight, graph_node)); .push((weight, graph_node));
Ok(()) Ok(())
} }
fn sample_clamped(&self, t: f32) -> Box<dyn Any> {
let value = self.0.sample_iter_clamped(t);
Box::new(WeightsCurveSample(value.collect()))
}
} }
impl WeightsCurveEvaluator { impl WeightsCurveEvaluator {
@ -1010,6 +1093,8 @@ pub trait AnimationCurve: Reflect + Debug + Send + Sync {
weight: f32, weight: f32,
graph_node: AnimationNodeIndex, graph_node: AnimationNodeIndex,
) -> Result<(), AnimationEvaluationError>; ) -> Result<(), AnimationEvaluationError>;
fn sample_clamped(&self, t: f32) -> Box<dyn Any>;
} }
/// A low-level trait for use in [`crate::VariableCurve`] that provides fine /// A low-level trait for use in [`crate::VariableCurve`] that provides fine