1use crate::core::{
25 algebra::{Unit, UnitQuaternion, Vector2, Vector3, Vector4},
26 log::Log,
27 math::lerpf,
28 num_traits::AsPrimitive,
29 reflect::prelude::*,
30 visitor::prelude::*,
31 ImmutableString,
32};
33use std::any::TypeId;
34use std::{
35 any,
36 any::Any,
37 fmt::{Debug, Display, Formatter},
38};
39
40#[derive(Visit, Reflect, Clone, Copy, Debug, PartialEq, Eq, Hash)]
42pub enum ValueType {
43 Bool,
45 F32,
47 F64,
49 U64,
51 I64,
53 U32,
55 I32,
57 U16,
59 I16,
61 U8,
63 I8,
65
66 Vector2Bool,
68 Vector2F32,
70 Vector2F64,
72 Vector2U64,
74 Vector2I64,
76 Vector2U32,
78 Vector2I32,
80 Vector2U16,
82 Vector2I16,
84 Vector2U8,
86 Vector2I8,
88
89 Vector3Bool,
91 Vector3F32,
93 Vector3F64,
95 Vector3U64,
97 Vector3I64,
99 Vector3U32,
101 Vector3I32,
103 Vector3U16,
105 Vector3I16,
107 Vector3U8,
109 Vector3I8,
111
112 Vector4Bool,
114 Vector4F32,
116 Vector4F64,
118 Vector4U64,
120 Vector4I64,
122 Vector4U32,
124 Vector4I32,
126 Vector4U16,
128 Vector4I16,
130 Vector4U8,
132 Vector4I8,
134
135 UnitQuaternionF32,
137 UnitQuaternionF64,
139}
140
141impl ValueType {
142 pub fn into_type_id(self) -> TypeId {
144 match self {
145 ValueType::Bool => TypeId::of::<bool>(),
146 ValueType::F32 => TypeId::of::<f32>(),
147 ValueType::F64 => TypeId::of::<f64>(),
148 ValueType::U64 => TypeId::of::<u64>(),
149 ValueType::I64 => TypeId::of::<i64>(),
150 ValueType::U32 => TypeId::of::<u32>(),
151 ValueType::I32 => TypeId::of::<i32>(),
152 ValueType::U16 => TypeId::of::<u16>(),
153 ValueType::I16 => TypeId::of::<i16>(),
154 ValueType::U8 => TypeId::of::<u8>(),
155 ValueType::I8 => TypeId::of::<i8>(),
156 ValueType::Vector2Bool => TypeId::of::<Vector2<bool>>(),
157 ValueType::Vector2F32 => TypeId::of::<Vector2<f32>>(),
158 ValueType::Vector2F64 => TypeId::of::<Vector2<f64>>(),
159 ValueType::Vector2U64 => TypeId::of::<Vector2<u64>>(),
160 ValueType::Vector2I64 => TypeId::of::<Vector2<i64>>(),
161 ValueType::Vector2U32 => TypeId::of::<Vector2<u32>>(),
162 ValueType::Vector2I32 => TypeId::of::<Vector2<i32>>(),
163 ValueType::Vector2U16 => TypeId::of::<Vector2<u16>>(),
164 ValueType::Vector2I16 => TypeId::of::<Vector2<i16>>(),
165 ValueType::Vector2U8 => TypeId::of::<Vector2<u8>>(),
166 ValueType::Vector2I8 => TypeId::of::<Vector2<i8>>(),
167 ValueType::Vector3Bool => TypeId::of::<Vector3<bool>>(),
168 ValueType::Vector3F32 => TypeId::of::<Vector3<f32>>(),
169 ValueType::Vector3F64 => TypeId::of::<Vector3<f64>>(),
170 ValueType::Vector3U64 => TypeId::of::<Vector3<u64>>(),
171 ValueType::Vector3I64 => TypeId::of::<Vector3<i64>>(),
172 ValueType::Vector3U32 => TypeId::of::<Vector3<u32>>(),
173 ValueType::Vector3I32 => TypeId::of::<Vector3<i32>>(),
174 ValueType::Vector3U16 => TypeId::of::<Vector3<u16>>(),
175 ValueType::Vector3I16 => TypeId::of::<Vector3<i16>>(),
176 ValueType::Vector3U8 => TypeId::of::<Vector3<u8>>(),
177 ValueType::Vector3I8 => TypeId::of::<Vector3<i8>>(),
178 ValueType::Vector4Bool => TypeId::of::<Vector4<bool>>(),
179 ValueType::Vector4F32 => TypeId::of::<Vector4<f32>>(),
180 ValueType::Vector4F64 => TypeId::of::<Vector4<f64>>(),
181 ValueType::Vector4U64 => TypeId::of::<Vector4<u64>>(),
182 ValueType::Vector4I64 => TypeId::of::<Vector4<i64>>(),
183 ValueType::Vector4U32 => TypeId::of::<Vector4<u32>>(),
184 ValueType::Vector4I32 => TypeId::of::<Vector4<i32>>(),
185 ValueType::Vector4U16 => TypeId::of::<Vector4<u16>>(),
186 ValueType::Vector4I16 => TypeId::of::<Vector4<i16>>(),
187 ValueType::Vector4U8 => TypeId::of::<Vector4<u8>>(),
188 ValueType::Vector4I8 => TypeId::of::<Vector4<i8>>(),
189 ValueType::UnitQuaternionF32 => TypeId::of::<UnitQuaternion<f32>>(),
190 ValueType::UnitQuaternionF64 => TypeId::of::<UnitQuaternion<f64>>(),
191 }
192 }
193}
194
195impl Default for ValueType {
196 fn default() -> Self {
197 Self::F32
198 }
199}
200
201#[derive(Clone, Debug, PartialEq)]
205pub enum TrackValue {
206 Real(f32),
208
209 Vector2(Vector2<f32>),
211
212 Vector3(Vector3<f32>),
214
215 Vector4(Vector4<f32>),
217
218 UnitQuaternion(UnitQuaternion<f32>),
220}
221
222impl TrackValue {
223 pub fn blend_with(&mut self, other: &Self, weight: f32) {
226 match (self, other) {
227 (Self::Real(a), Self::Real(b)) => *a = lerpf(*a, *b, weight),
228 (Self::Vector2(a), Self::Vector2(b)) => *a = a.lerp(b, weight),
229 (Self::Vector3(a), Self::Vector3(b)) => *a = a.lerp(b, weight),
230 (Self::Vector4(a), Self::Vector4(b)) => *a = a.lerp(b, weight),
231 (Self::UnitQuaternion(a), Self::UnitQuaternion(b)) => *a = nlerp(*a, b, weight),
232 _ => (),
233 }
234 }
235
236 pub fn apply_to_any(&self, any: &mut dyn Any, value_type: ValueType) -> bool {
239 fn convert_vec2<T>(vec2: &Vector2<f32>) -> Vector2<T>
240 where
241 f32: AsPrimitive<T>,
242 T: Copy + 'static,
243 {
244 Vector2::new(vec2.x.as_(), vec2.y.as_())
245 }
246
247 fn convert_vec3<T>(vec3: &Vector3<f32>) -> Vector3<T>
248 where
249 f32: AsPrimitive<T>,
250 T: Copy + 'static,
251 {
252 Vector3::new(vec3.x.as_(), vec3.y.as_(), vec3.z.as_())
253 }
254
255 fn convert_vec4<T>(vec4: &Vector4<f32>) -> Vector4<T>
256 where
257 f32: AsPrimitive<T>,
258 T: Copy + 'static,
259 {
260 Vector4::new(vec4.x.as_(), vec4.y.as_(), vec4.z.as_(), vec4.w.as_())
261 }
262
263 fn set<T>(any: &mut dyn Any, value: T) -> bool
264 where
265 T: Any + Copy,
266 {
267 if let Some(any_val) = any.downcast_mut::<T>() {
268 *any_val = value;
269 true
270 } else {
271 Log::err(format!(
272 "Animation: unable to set value of type {}! Types mismatch!",
273 any::type_name::<T>()
274 ));
275 false
276 }
277 }
278
279 match self {
280 TrackValue::Real(real) => match value_type {
281 ValueType::Bool => set(any, real.ne(&0.0)),
282 ValueType::F32 => set(any, *real),
283 ValueType::F64 => set(any, *real as f64),
284 ValueType::U64 => set(any, *real as u64),
285 ValueType::I64 => set(any, *real as i64),
286 ValueType::U32 => set(any, *real as u32),
287 ValueType::I32 => set(any, *real as i32),
288 ValueType::U16 => set(any, *real as u16),
289 ValueType::I16 => set(any, *real as i16),
290 ValueType::U8 => set(any, *real as u8),
291 ValueType::I8 => set(any, *real as i8),
292 _ => false,
293 },
294 TrackValue::Vector2(vec2) => match value_type {
295 ValueType::Vector2Bool => set(any, Vector2::new(vec2.x.ne(&0.0), vec2.y.ne(&0.0))),
296 ValueType::Vector2F32 => set(any, *vec2),
297 ValueType::Vector2F64 => set(any, convert_vec2::<f64>(vec2)),
298 ValueType::Vector2U64 => set(any, convert_vec2::<u64>(vec2)),
299 ValueType::Vector2I64 => set(any, convert_vec2::<i64>(vec2)),
300 ValueType::Vector2U32 => set(any, convert_vec2::<u32>(vec2)),
301 ValueType::Vector2I32 => set(any, convert_vec2::<i32>(vec2)),
302 ValueType::Vector2U16 => set(any, convert_vec2::<u16>(vec2)),
303 ValueType::Vector2I16 => set(any, convert_vec2::<i16>(vec2)),
304 ValueType::Vector2U8 => set(any, convert_vec2::<u8>(vec2)),
305 ValueType::Vector2I8 => set(any, convert_vec2::<i8>(vec2)),
306 _ => false,
307 },
308 TrackValue::Vector3(vec3) => match value_type {
309 ValueType::Vector3Bool => set(
310 any,
311 Vector3::new(vec3.x.ne(&0.0), vec3.y.ne(&0.0), vec3.z.ne(&0.0)),
312 ),
313 ValueType::Vector3F32 => set(any, *vec3),
314 ValueType::Vector3F64 => set(any, convert_vec3::<f64>(vec3)),
315 ValueType::Vector3U64 => set(any, convert_vec3::<u64>(vec3)),
316 ValueType::Vector3I64 => set(any, convert_vec3::<i64>(vec3)),
317 ValueType::Vector3U32 => set(any, convert_vec3::<u32>(vec3)),
318 ValueType::Vector3I32 => set(any, convert_vec3::<i32>(vec3)),
319 ValueType::Vector3U16 => set(any, convert_vec3::<u16>(vec3)),
320 ValueType::Vector3I16 => set(any, convert_vec3::<i16>(vec3)),
321 ValueType::Vector3U8 => set(any, convert_vec3::<u8>(vec3)),
322 ValueType::Vector3I8 => set(any, convert_vec3::<i8>(vec3)),
323 _ => false,
324 },
325 TrackValue::Vector4(vec4) => match value_type {
326 ValueType::Vector4Bool => set(
327 any,
328 Vector4::new(
329 vec4.x.ne(&0.0),
330 vec4.y.ne(&0.0),
331 vec4.z.ne(&0.0),
332 vec4.w.ne(&0.0),
333 ),
334 ),
335 ValueType::Vector4F32 => set(any, *vec4),
336 ValueType::Vector4F64 => set(any, convert_vec4::<f64>(vec4)),
337 ValueType::Vector4U64 => set(any, convert_vec4::<u64>(vec4)),
338 ValueType::Vector4I64 => set(any, convert_vec4::<i64>(vec4)),
339 ValueType::Vector4U32 => set(any, convert_vec4::<u32>(vec4)),
340 ValueType::Vector4I32 => set(any, convert_vec4::<i32>(vec4)),
341 ValueType::Vector4U16 => set(any, convert_vec4::<u16>(vec4)),
342 ValueType::Vector4I16 => set(any, convert_vec4::<i16>(vec4)),
343 ValueType::Vector4U8 => set(any, convert_vec4::<u8>(vec4)),
344 ValueType::Vector4I8 => set(any, convert_vec4::<i8>(vec4)),
345 _ => false,
346 },
347 TrackValue::UnitQuaternion(quat) => match value_type {
348 ValueType::UnitQuaternionF32 => set(any, *quat),
349 ValueType::UnitQuaternionF64 => set(any, quat.cast::<f64>()),
350 _ => false,
351 },
352 }
353 }
354}
355
356#[derive(Default, Clone, Visit, Reflect, Debug, PartialEq, Eq)]
361pub enum ValueBinding {
362 #[default]
364 Position,
365 Scale,
367 Rotation,
369 Property {
371 name: ImmutableString,
373 value_type: ValueType,
375 },
376}
377
378impl Display for ValueBinding {
379 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
380 match self {
381 ValueBinding::Position => write!(f, "Position"),
382 ValueBinding::Scale => write!(f, "Scale"),
383 ValueBinding::Rotation => write!(f, "Rotation"),
384 ValueBinding::Property { name, .. } => write!(f, "{name}"),
385 }
386 }
387}
388
389#[derive(Clone, Debug, PartialEq)]
391pub struct BoundValue {
392 pub binding: ValueBinding,
394 pub value: TrackValue,
396}
397
398impl BoundValue {
399 pub fn blend_with(&mut self, other: &Self, weight: f32) {
402 assert_eq!(self.binding, other.binding);
403 self.value.blend_with(&other.value, weight);
404 }
405
406 pub fn apply_to_object(
408 &self,
409 object: &mut dyn Reflect,
410 property_path: &str,
411 value_type: ValueType,
412 ) {
413 object.as_reflect_mut(&mut |object_ref| {
414 object_ref.resolve_path_mut(property_path, &mut |result| match result {
415 Ok(property) => {
416 let mut applied = false;
417 property.as_any_mut(&mut |any| {
418 applied = self.value.apply_to_any(any, value_type);
419 });
420 if applied {
421 property.as_inheritable_variable_mut(&mut |var| {
422 if let Some(var) = var {
423 var.mark_modified();
424 }
425 });
426 }
427 }
428 Err(err) => {
429 Log::err(format!(
430 "Failed to set property {property_path}! Reason: {err:?}"
431 ));
432 }
433 });
434 })
435 }
436}
437
438#[derive(Clone, Debug, Default, PartialEq)]
440pub struct BoundValueCollection {
441 pub values: Vec<BoundValue>,
443}
444
445impl BoundValueCollection {
446 pub fn blend_with(&mut self, other: &Self, weight: f32) {
449 for value in self.values.iter_mut() {
450 if let Some(other_value) = other.values.iter().find(|v| v.binding == value.binding) {
451 value.blend_with(other_value, weight);
452 }
453 }
454 }
455}
456
457pub fn nlerp(mut a: UnitQuaternion<f32>, b: &UnitQuaternion<f32>, w: f32) -> UnitQuaternion<f32> {
460 if a.dot(b) < 0.0 {
461 a = negate_unit_quaternion(&a)
462 }
463 a.nlerp(b, w)
464}
465
466pub fn negate_unit_quaternion(a: &UnitQuaternion<f32>) -> UnitQuaternion<f32> {
468 Unit::new_unchecked(-a.as_ref())
469}
470
471#[cfg(test)]
472mod test {
473 use crate::value::{BoundValue, TrackValue, ValueBinding, ValueType};
474 use fyrox_core::{reflect::prelude::*, variable::InheritableVariable};
475
476 #[derive(Reflect, Debug, PartialEq)]
477 struct OtherStruct {
478 field: u32,
479 inheritable_variable: InheritableVariable<u32>,
480 }
481
482 impl Default for OtherStruct {
483 fn default() -> Self {
484 Self {
485 field: 0,
486 inheritable_variable: InheritableVariable::new_non_modified(0),
487 }
488 }
489 }
490
491 #[derive(Default, Reflect, Debug, PartialEq)]
492 struct MyStruct {
493 some_bool: bool,
494 some_property: f32,
495 other_struct: OtherStruct,
496 }
497
498 #[test]
499 fn test_apply_value() {
500 let some_bool_value = BoundValue {
501 binding: ValueBinding::Property {
502 name: "some_bool".into(),
503 value_type: ValueType::Bool,
504 },
505 value: TrackValue::Real(1.0),
506 };
507
508 let some_property_value = BoundValue {
509 binding: ValueBinding::Property {
510 name: "some_property".into(),
511 value_type: ValueType::F32,
512 },
513 value: TrackValue::Real(123.0),
514 };
515
516 let field_value = BoundValue {
517 binding: ValueBinding::Property {
518 name: "field".into(),
519 value_type: ValueType::U32,
520 },
521 value: TrackValue::Real(123.0),
522 };
523
524 let inheritable_variable_value = BoundValue {
525 binding: ValueBinding::Property {
526 name: "inheritable_variable".into(),
527 value_type: ValueType::U32,
528 },
529 value: TrackValue::Real(123.0),
530 };
531
532 let mut object = MyStruct::default();
533
534 some_bool_value.apply_to_object(&mut object, "some_bool", ValueType::Bool);
535 assert!(object.some_bool);
536
537 some_property_value.apply_to_object(&mut object, "some_property", ValueType::F32);
538 assert_eq!(object.some_property, 123.0);
539
540 field_value.apply_to_object(&mut object, "other_struct.field", ValueType::U32);
541 assert_eq!(object.other_struct.field, 123);
542
543 assert!(!object.other_struct.inheritable_variable.is_modified());
544 inheritable_variable_value.apply_to_object(
545 &mut object,
546 "other_struct.inheritable_variable",
547 ValueType::U32,
548 );
549 assert_eq!(object.other_struct.field, 123);
550 assert!(object.other_struct.inheritable_variable.is_modified());
551 }
552}