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