1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use std::ptr;
use crate::error::Result;
use crate::ffi;
use crate::handle::ObjectHandle;
use crate::types::Matrix4x4ArrayInfo;
use crate::util::{parse_json, required_handle};
#[derive(Debug, Clone)]
/// Wraps the corresponding Model I/O matrix4x4array counterpart.
pub struct Matrix4x4Array {
handle: ObjectHandle,
}
impl Matrix4x4Array {
/// Builds this wrapper from the retained handle of the wrapped Model I/O matrix4x4array counterpart.
pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
Self { handle }
}
#[allow(dead_code)]
/// Returns the opaque pointer used to call the wrapped Model I/O matrix4x4array counterpart.
pub(crate) fn as_ptr(&self) -> *mut core::ffi::c_void {
self.handle.as_ptr()
}
/// Wraps the corresponding Model I/O initializer for the wrapped Model I/O matrix4x4array counterpart.
pub fn new(element_count: usize) -> Result<Self> {
let mut out_array = ptr::null_mut();
let mut out_error = ptr::null_mut();
// SAFETY: The unsafe operation is valid in this context.
let status = unsafe {
ffi::mdl_matrix4x4_array_new(element_count as u64, &mut out_array, &mut out_error)
};
crate::util::status_result(status, out_error)?;
Ok(Self::from_handle(required_handle(
out_array,
"MDLMatrix4x4Array",
)?))
}
/// Calls the corresponding Model I/O method on the wrapped Model I/O matrix4x4array counterpart.
pub fn info(&self) -> Result<Matrix4x4ArrayInfo> {
parse_json(
// SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
unsafe { ffi::mdl_matrix4x4_array_info_json(self.handle.as_ptr()) },
"MDLMatrix4x4Array",
)
}
/// Calls the corresponding Model I/O method on the wrapped Model I/O matrix4x4array counterpart.
pub fn clear(&self) {
// SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
unsafe { ffi::mdl_matrix4x4_array_clear(self.handle.as_ptr()) };
}
/// Calls the corresponding Model I/O method on the wrapped Model I/O matrix4x4array counterpart.
pub fn set_float_matrices(&self, values: &[[f32; 16]]) {
let flattened = values
.iter()
.flat_map(|value| value.iter().copied())
.collect::<Vec<_>>();
// SAFETY: The unsafe operation is valid in this context.
unsafe {
ffi::mdl_matrix4x4_array_set_float_matrices(
self.handle.as_ptr(),
flattened.as_ptr(),
values.len() as u64,
);
};
}
/// Calls the corresponding Model I/O method on the wrapped Model I/O matrix4x4array counterpart.
pub fn float_matrices(&self) -> Result<Vec<[f32; 16]>> {
let count = self.info()?.element_count;
if count == 0 {
return Ok(Vec::new());
}
let mut flattened = vec![0.0_f32; count * 16];
// SAFETY: The unsafe operation is valid in this context.
let written = unsafe {
ffi::mdl_matrix4x4_array_copy_float_matrices(
self.handle.as_ptr(),
flattened.as_mut_ptr(),
count as u64,
)
} as usize;
flattened.truncate(written * 16);
Ok(flattened
.chunks_exact(16)
.map(|chunk| {
let mut matrix = [0.0_f32; 16];
matrix.copy_from_slice(chunk);
matrix
})
.collect())
}
}