Skip to main content

modelio/
animated_value_types.rs

1use std::ptr;
2
3use crate::error::Result;
4use crate::ffi;
5use crate::handle::ObjectHandle;
6use crate::types::{AnimatedValueInfo, AnimatedValueInterpolation};
7use crate::util::{parse_json, required_handle};
8
9fn animated_info(handle: &ObjectHandle, context: &'static str) -> Result<AnimatedValueInfo> {
10    parse_json(
11        unsafe { ffi::mdl_animated_value_info_json(handle.as_ptr()) },
12        context,
13    )
14}
15
16fn animated_clear(handle: &ObjectHandle) {
17    unsafe { ffi::mdl_animated_value_clear(handle.as_ptr()) };
18}
19
20fn animated_set_interpolation(handle: &ObjectHandle, interpolation: AnimatedValueInterpolation) {
21    unsafe { ffi::mdl_animated_value_set_interpolation(handle.as_ptr(), interpolation.as_raw()) };
22}
23
24fn convert_vectors<const N: usize>(raw: &[f32]) -> Vec<[f32; N]> {
25    raw.chunks_exact(N)
26        .map(|chunk| {
27            let mut value = [0.0_f32; N];
28            value.copy_from_slice(chunk);
29            value
30        })
31        .collect()
32}
33
34#[derive(Debug, Clone)]
35pub struct AnimatedScalar {
36    handle: ObjectHandle,
37}
38
39impl AnimatedScalar {
40    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
41        Self { handle }
42    }
43
44    pub fn new() -> Result<Self> {
45        let mut out_value = ptr::null_mut();
46        let mut out_error = ptr::null_mut();
47        let status = unsafe { ffi::mdl_animated_scalar_new(&mut out_value, &mut out_error) };
48        crate::util::status_result(status, out_error)?;
49        Ok(Self::from_handle(required_handle(
50            out_value,
51            "MDLAnimatedScalar",
52        )?))
53    }
54
55    pub fn info(&self) -> Result<AnimatedValueInfo> {
56        animated_info(&self.handle, "MDLAnimatedScalar")
57    }
58
59    pub fn clear(&self) {
60        animated_clear(&self.handle);
61    }
62
63    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
64        animated_set_interpolation(&self.handle, interpolation);
65    }
66
67    pub fn set_float(&self, value: f32, time: f64) {
68        unsafe { ffi::mdl_animated_scalar_set_float(self.handle.as_ptr(), value, time) };
69    }
70
71    #[must_use]
72    pub fn float_value(&self, time: f64) -> f32 {
73        unsafe { ffi::mdl_animated_scalar_float_value(self.handle.as_ptr(), time) }
74    }
75}
76
77#[derive(Debug, Clone)]
78pub struct AnimatedVector2 {
79    handle: ObjectHandle,
80}
81
82impl AnimatedVector2 {
83    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
84        Self { handle }
85    }
86
87    pub fn new() -> Result<Self> {
88        let mut out_value = ptr::null_mut();
89        let mut out_error = ptr::null_mut();
90        let status = unsafe { ffi::mdl_animated_vector2_new(&mut out_value, &mut out_error) };
91        crate::util::status_result(status, out_error)?;
92        Ok(Self::from_handle(required_handle(
93            out_value,
94            "MDLAnimatedVector2",
95        )?))
96    }
97
98    pub fn info(&self) -> Result<AnimatedValueInfo> {
99        animated_info(&self.handle, "MDLAnimatedVector2")
100    }
101
102    pub fn clear(&self) {
103        animated_clear(&self.handle);
104    }
105
106    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
107        animated_set_interpolation(&self.handle, interpolation);
108    }
109
110    pub fn set_float2(&self, value: [f32; 2], time: f64) {
111        unsafe {
112            ffi::mdl_animated_vector2_set_float2(self.handle.as_ptr(), value[0], value[1], time);
113        };
114    }
115
116    #[must_use]
117    pub fn float2_value(&self, time: f64) -> [f32; 2] {
118        let mut value = [0.0_f32; 2];
119        unsafe {
120            ffi::mdl_animated_vector2_copy_float2_value(
121                self.handle.as_ptr(),
122                time,
123                &mut value[0],
124                &mut value[1],
125            );
126        };
127        value
128    }
129}
130
131#[derive(Debug, Clone)]
132pub struct AnimatedVector3 {
133    handle: ObjectHandle,
134}
135
136impl AnimatedVector3 {
137    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
138        Self { handle }
139    }
140
141    pub fn new() -> Result<Self> {
142        let mut out_value = ptr::null_mut();
143        let mut out_error = ptr::null_mut();
144        let status = unsafe { ffi::mdl_animated_vector3_new(&mut out_value, &mut out_error) };
145        crate::util::status_result(status, out_error)?;
146        Ok(Self::from_handle(required_handle(
147            out_value,
148            "MDLAnimatedVector3",
149        )?))
150    }
151
152    pub fn info(&self) -> Result<AnimatedValueInfo> {
153        animated_info(&self.handle, "MDLAnimatedVector3")
154    }
155
156    pub fn clear(&self) {
157        animated_clear(&self.handle);
158    }
159
160    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
161        animated_set_interpolation(&self.handle, interpolation);
162    }
163
164    pub fn set_float3(&self, value: [f32; 3], time: f64) {
165        unsafe {
166            ffi::mdl_animated_vector3_set_float3(
167                self.handle.as_ptr(),
168                value[0],
169                value[1],
170                value[2],
171                time,
172            );
173        };
174    }
175
176    #[must_use]
177    pub fn float3_value(&self, time: f64) -> [f32; 3] {
178        let mut value = [0.0_f32; 3];
179        unsafe {
180            ffi::mdl_animated_vector3_copy_float3_value(
181                self.handle.as_ptr(),
182                time,
183                &mut value[0],
184                &mut value[1],
185                &mut value[2],
186            );
187        };
188        value
189    }
190}
191
192#[derive(Debug, Clone)]
193pub struct AnimatedVector4 {
194    handle: ObjectHandle,
195}
196
197impl AnimatedVector4 {
198    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
199        Self { handle }
200    }
201
202    pub fn new() -> Result<Self> {
203        let mut out_value = ptr::null_mut();
204        let mut out_error = ptr::null_mut();
205        let status = unsafe { ffi::mdl_animated_vector4_new(&mut out_value, &mut out_error) };
206        crate::util::status_result(status, out_error)?;
207        Ok(Self::from_handle(required_handle(
208            out_value,
209            "MDLAnimatedVector4",
210        )?))
211    }
212
213    pub fn info(&self) -> Result<AnimatedValueInfo> {
214        animated_info(&self.handle, "MDLAnimatedVector4")
215    }
216
217    pub fn clear(&self) {
218        animated_clear(&self.handle);
219    }
220
221    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
222        animated_set_interpolation(&self.handle, interpolation);
223    }
224
225    pub fn set_float4(&self, value: [f32; 4], time: f64) {
226        unsafe {
227            ffi::mdl_animated_vector4_set_float4(
228                self.handle.as_ptr(),
229                value[0],
230                value[1],
231                value[2],
232                value[3],
233                time,
234            );
235        };
236    }
237
238    #[must_use]
239    pub fn float4_value(&self, time: f64) -> [f32; 4] {
240        let mut value = [0.0_f32; 4];
241        unsafe {
242            ffi::mdl_animated_vector4_copy_float4_value(
243                self.handle.as_ptr(),
244                time,
245                &mut value[0],
246                &mut value[1],
247                &mut value[2],
248                &mut value[3],
249            );
250        };
251        value
252    }
253}
254
255#[derive(Debug, Clone)]
256pub struct AnimatedQuaternion {
257    handle: ObjectHandle,
258}
259
260impl AnimatedQuaternion {
261    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
262        Self { handle }
263    }
264
265    pub fn new() -> Result<Self> {
266        let mut out_value = ptr::null_mut();
267        let mut out_error = ptr::null_mut();
268        let status = unsafe { ffi::mdl_animated_quaternion_new(&mut out_value, &mut out_error) };
269        crate::util::status_result(status, out_error)?;
270        Ok(Self::from_handle(required_handle(
271            out_value,
272            "MDLAnimatedQuaternion",
273        )?))
274    }
275
276    pub fn info(&self) -> Result<AnimatedValueInfo> {
277        animated_info(&self.handle, "MDLAnimatedQuaternion")
278    }
279
280    pub fn clear(&self) {
281        animated_clear(&self.handle);
282    }
283
284    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
285        animated_set_interpolation(&self.handle, interpolation);
286    }
287
288    pub fn set_float_quaternion(&self, value: [f32; 4], time: f64) {
289        unsafe {
290            ffi::mdl_animated_quaternion_set_float(
291                self.handle.as_ptr(),
292                value[0],
293                value[1],
294                value[2],
295                value[3],
296                time,
297            );
298        };
299    }
300
301    #[must_use]
302    pub fn float_quaternion_value(&self, time: f64) -> [f32; 4] {
303        let mut raw = [0.0_f32; 4];
304        unsafe {
305            ffi::mdl_animated_quaternion_copy_float_value(
306                self.handle.as_ptr(),
307                time,
308                raw.as_mut_ptr(),
309            );
310        };
311        raw
312    }
313}
314
315#[derive(Debug, Clone)]
316pub struct AnimatedMatrix4x4 {
317    handle: ObjectHandle,
318}
319
320impl AnimatedMatrix4x4 {
321    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
322        Self { handle }
323    }
324
325    pub fn new() -> Result<Self> {
326        let mut out_value = ptr::null_mut();
327        let mut out_error = ptr::null_mut();
328        let status = unsafe { ffi::mdl_animated_matrix4x4_new(&mut out_value, &mut out_error) };
329        crate::util::status_result(status, out_error)?;
330        Ok(Self::from_handle(required_handle(
331            out_value,
332            "MDLAnimatedMatrix4x4",
333        )?))
334    }
335
336    pub fn info(&self) -> Result<AnimatedValueInfo> {
337        animated_info(&self.handle, "MDLAnimatedMatrix4x4")
338    }
339
340    pub fn clear(&self) {
341        animated_clear(&self.handle);
342    }
343
344    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
345        animated_set_interpolation(&self.handle, interpolation);
346    }
347
348    pub fn set_float4x4(&self, value: [f32; 16], time: f64) {
349        unsafe {
350            ffi::mdl_animated_matrix4x4_set_float(self.handle.as_ptr(), value.as_ptr(), time);
351        };
352    }
353
354    #[must_use]
355    pub fn float4x4_value(&self, time: f64) -> [f32; 16] {
356        let mut raw = [0.0_f32; 16];
357        unsafe {
358            ffi::mdl_animated_matrix4x4_copy_float_value(
359                self.handle.as_ptr(),
360                time,
361                raw.as_mut_ptr(),
362            );
363        };
364        raw
365    }
366}
367
368#[derive(Debug, Clone)]
369pub struct AnimatedScalarArray {
370    handle: ObjectHandle,
371}
372
373impl AnimatedScalarArray {
374    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
375        Self { handle }
376    }
377
378    pub fn new(element_count: usize) -> Result<Self> {
379        let mut out_value = ptr::null_mut();
380        let mut out_error = ptr::null_mut();
381        let status = unsafe {
382            ffi::mdl_animated_scalar_array_new(element_count as u64, &mut out_value, &mut out_error)
383        };
384        crate::util::status_result(status, out_error)?;
385        Ok(Self::from_handle(required_handle(
386            out_value,
387            "MDLAnimatedScalarArray",
388        )?))
389    }
390
391    pub fn info(&self) -> Result<AnimatedValueInfo> {
392        animated_info(&self.handle, "MDLAnimatedScalarArray")
393    }
394
395    pub fn clear(&self) {
396        animated_clear(&self.handle);
397    }
398
399    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
400        animated_set_interpolation(&self.handle, interpolation);
401    }
402
403    pub fn set_float_array(&self, values: &[f32], time: f64) {
404        unsafe {
405            ffi::mdl_animated_scalar_array_set_float(
406                self.handle.as_ptr(),
407                values.as_ptr(),
408                values.len() as u64,
409                time,
410            );
411        };
412    }
413
414    pub fn float_array_at_time(&self, time: f64) -> Result<Vec<f32>> {
415        let element_count = self.info()?.element_count.unwrap_or(0);
416        if element_count == 0 {
417            return Ok(Vec::new());
418        }
419        let mut values = vec![0.0_f32; element_count];
420        let written = unsafe {
421            ffi::mdl_animated_scalar_array_copy_float_at_time(
422                self.handle.as_ptr(),
423                time,
424                values.as_mut_ptr(),
425                element_count as u64,
426            )
427        } as usize;
428        values.truncate(written);
429        Ok(values)
430    }
431}
432
433#[derive(Debug, Clone)]
434pub struct AnimatedVector3Array {
435    handle: ObjectHandle,
436}
437
438impl AnimatedVector3Array {
439    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
440        Self { handle }
441    }
442
443    pub fn new(element_count: usize) -> Result<Self> {
444        let mut out_value = ptr::null_mut();
445        let mut out_error = ptr::null_mut();
446        let status = unsafe {
447            ffi::mdl_animated_vector3_array_new(
448                element_count as u64,
449                &mut out_value,
450                &mut out_error,
451            )
452        };
453        crate::util::status_result(status, out_error)?;
454        Ok(Self::from_handle(required_handle(
455            out_value,
456            "MDLAnimatedVector3Array",
457        )?))
458    }
459
460    pub fn info(&self) -> Result<AnimatedValueInfo> {
461        animated_info(&self.handle, "MDLAnimatedVector3Array")
462    }
463
464    pub fn clear(&self) {
465        animated_clear(&self.handle);
466    }
467
468    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
469        animated_set_interpolation(&self.handle, interpolation);
470    }
471
472    pub fn set_float3_array(&self, values: &[[f32; 3]], time: f64) {
473        let flattened = values
474            .iter()
475            .flat_map(|value| value.iter().copied())
476            .collect::<Vec<_>>();
477        unsafe {
478            ffi::mdl_animated_vector3_array_set_float(
479                self.handle.as_ptr(),
480                flattened.as_ptr(),
481                values.len() as u64,
482                time,
483            );
484        };
485    }
486
487    pub fn float3_array_at_time(&self, time: f64) -> Result<Vec<[f32; 3]>> {
488        let element_count = self.info()?.element_count.unwrap_or(0);
489        if element_count == 0 {
490            return Ok(Vec::new());
491        }
492        let mut values = vec![0.0_f32; element_count * 3];
493        let written = unsafe {
494            ffi::mdl_animated_vector3_array_copy_float_at_time(
495                self.handle.as_ptr(),
496                time,
497                values.as_mut_ptr(),
498                element_count as u64,
499            )
500        } as usize;
501        values.truncate(written * 3);
502        Ok(convert_vectors::<3>(&values))
503    }
504}
505
506#[derive(Debug, Clone)]
507pub struct AnimatedQuaternionArray {
508    handle: ObjectHandle,
509}
510
511impl AnimatedQuaternionArray {
512    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
513        Self { handle }
514    }
515
516    pub fn new(element_count: usize) -> Result<Self> {
517        let mut out_value = ptr::null_mut();
518        let mut out_error = ptr::null_mut();
519        let status = unsafe {
520            ffi::mdl_animated_quaternion_array_new(
521                element_count as u64,
522                &mut out_value,
523                &mut out_error,
524            )
525        };
526        crate::util::status_result(status, out_error)?;
527        Ok(Self::from_handle(required_handle(
528            out_value,
529            "MDLAnimatedQuaternionArray",
530        )?))
531    }
532
533    pub fn info(&self) -> Result<AnimatedValueInfo> {
534        animated_info(&self.handle, "MDLAnimatedQuaternionArray")
535    }
536
537    pub fn clear(&self) {
538        animated_clear(&self.handle);
539    }
540
541    pub fn set_interpolation(&self, interpolation: AnimatedValueInterpolation) {
542        animated_set_interpolation(&self.handle, interpolation);
543    }
544
545    pub fn set_float_quaternion_array(&self, values: &[[f32; 4]], time: f64) {
546        let flattened = values
547            .iter()
548            .flat_map(|value| value.iter().copied())
549            .collect::<Vec<_>>();
550        unsafe {
551            ffi::mdl_animated_quaternion_array_set_float(
552                self.handle.as_ptr(),
553                flattened.as_ptr(),
554                values.len() as u64,
555                time,
556            );
557        };
558    }
559
560    pub fn float_quaternion_array_at_time(&self, time: f64) -> Result<Vec<[f32; 4]>> {
561        let element_count = self.info()?.element_count.unwrap_or(0);
562        if element_count == 0 {
563            return Ok(Vec::new());
564        }
565        let mut values = vec![0.0_f32; element_count * 4];
566        let written = unsafe {
567            ffi::mdl_animated_quaternion_array_copy_float_at_time(
568                self.handle.as_ptr(),
569                time,
570                values.as_mut_ptr(),
571                element_count as u64,
572            )
573        } as usize;
574        values.truncate(written * 4);
575        Ok(convert_vectors::<4>(&values))
576    }
577}