Skip to main content

modelio/
vertex_attribute.rs

1use std::ptr;
2
3use crate::error::Result;
4use crate::ffi;
5use crate::handle::ObjectHandle;
6use crate::types::{VertexAttributeDescriptorInfo, VertexDescriptorInfo};
7use crate::util::{c_string, parse_json, required_handle};
8
9#[derive(Debug, Clone)]
10/// Wraps the corresponding Model I/O vertex attribute counterpart.
11pub struct VertexAttribute {
12    handle: ObjectHandle,
13}
14
15impl VertexAttribute {
16    /// Builds this wrapper from the retained handle of the wrapped Model I/O vertex attribute counterpart.
17    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
18        Self { handle }
19    }
20
21    /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O vertex attribute counterpart.
22    pub fn new(name: &str, format: u32, offset: usize, buffer_index: usize) -> Result<Self> {
23        let name = c_string(name)?;
24        let mut out_attribute = ptr::null_mut();
25        let mut out_error = ptr::null_mut();
26        // SAFETY: The unsafe operation is valid in this context.
27        let status = unsafe {
28            ffi::mdl_vertex_attribute_new(
29                name.as_ptr(),
30                format,
31                offset as u64,
32                buffer_index as u64,
33                &mut out_attribute,
34                &mut out_error,
35            )
36        };
37        crate::util::status_result(status, out_error)?;
38        Ok(Self::from_handle(required_handle(
39            out_attribute,
40            "MDLVertexAttribute",
41        )?))
42    }
43
44    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex attribute counterpart.
45    pub fn info(&self) -> Result<VertexAttributeDescriptorInfo> {
46        parse_json(
47            // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
48            unsafe { ffi::mdl_vertex_attribute_info_json(self.handle.as_ptr()) },
49            "MDLVertexAttribute",
50        )
51    }
52
53    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex attribute counterpart.
54    pub fn set_name(&self, name: &str) -> Result<()> {
55        let name = c_string(name)?;
56        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
57        unsafe { ffi::mdl_vertex_attribute_set_name(self.handle.as_ptr(), name.as_ptr()) };
58        Ok(())
59    }
60
61    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex attribute counterpart.
62    pub fn set_format(&self, format: u32) {
63        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
64        unsafe { ffi::mdl_vertex_attribute_set_format(self.handle.as_ptr(), format) };
65    }
66
67    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex attribute counterpart.
68    pub fn set_offset(&self, offset: usize) {
69        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
70        unsafe { ffi::mdl_vertex_attribute_set_offset(self.handle.as_ptr(), offset as u64) };
71    }
72
73    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex attribute counterpart.
74    pub fn set_buffer_index(&self, buffer_index: usize) {
75        // SAFETY: The unsafe operation is valid in this context.
76        unsafe {
77            ffi::mdl_vertex_attribute_set_buffer_index(self.handle.as_ptr(), buffer_index as u64);
78        };
79    }
80
81    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex attribute counterpart.
82    pub fn set_time(&self, time: f64) {
83        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
84        unsafe { ffi::mdl_vertex_attribute_set_time(self.handle.as_ptr(), time) };
85    }
86
87    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex attribute counterpart.
88    pub fn set_initialization_value(&self, value: [f32; 4]) {
89        // SAFETY: The unsafe operation is valid in this context.
90        unsafe {
91            ffi::mdl_vertex_attribute_set_initialization_value(
92                self.handle.as_ptr(),
93                value[0],
94                value[1],
95                value[2],
96                value[3],
97            );
98        };
99    }
100}
101
102#[derive(Debug, Clone)]
103/// Wraps the corresponding Model I/O vertex buffer layout counterpart.
104pub struct VertexBufferLayout {
105    handle: ObjectHandle,
106}
107
108impl VertexBufferLayout {
109    /// Builds this wrapper from the retained handle of the wrapped Model I/O vertex buffer layout counterpart.
110    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
111        Self { handle }
112    }
113
114    /// Wraps the corresponding Model I/O initializer for the wrapped Model I/O vertex buffer layout counterpart.
115    pub fn new(stride: usize) -> Result<Self> {
116        let mut out_layout = ptr::null_mut();
117        let mut out_error = ptr::null_mut();
118        // SAFETY: The unsafe operation is valid in this context.
119        let status = unsafe {
120            ffi::mdl_vertex_buffer_layout_new(stride as u64, &mut out_layout, &mut out_error)
121        };
122        crate::util::status_result(status, out_error)?;
123        Ok(Self::from_handle(required_handle(
124            out_layout,
125            "MDLVertexBufferLayout",
126        )?))
127    }
128
129    #[must_use]
130    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex buffer layout counterpart.
131    pub fn stride(&self) -> usize {
132        // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
133        unsafe { ffi::mdl_vertex_buffer_layout_stride(self.handle.as_ptr()) as usize }
134    }
135
136    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex buffer layout counterpart.
137    pub fn set_stride(&self, stride: usize) {
138        // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
139        unsafe { ffi::mdl_vertex_buffer_layout_set_stride(self.handle.as_ptr(), stride as u64) };
140    }
141}
142
143#[derive(Debug, Clone)]
144/// Wraps the corresponding Model I/O vertex descriptor counterpart.
145pub struct VertexDescriptor {
146    handle: ObjectHandle,
147}
148
149impl VertexDescriptor {
150    /// Builds this wrapper from the retained handle of the wrapped Model I/O vertex descriptor counterpart.
151    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
152        Self { handle }
153    }
154
155    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
156    pub fn copy(&self) -> Result<Self> {
157        let mut out_descriptor = ptr::null_mut();
158        let mut out_error = ptr::null_mut();
159        // SAFETY: The unsafe operation is valid in this context.
160        let status = unsafe {
161            ffi::mdl_vertex_descriptor_new_copy(
162                self.handle.as_ptr(),
163                &mut out_descriptor,
164                &mut out_error,
165            )
166        };
167        crate::util::status_result(status, out_error)?;
168        Ok(Self::from_handle(required_handle(
169            out_descriptor,
170            "MDLVertexDescriptor",
171        )?))
172    }
173
174    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
175    pub fn info(&self) -> Result<VertexDescriptorInfo> {
176        parse_json(
177            // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
178            unsafe { ffi::mdl_vertex_descriptor_info_json(self.handle.as_ptr()) },
179            "MDLVertexDescriptor",
180        )
181    }
182
183    #[must_use]
184    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
185    pub fn attribute_count(&self) -> usize {
186        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
187        unsafe { ffi::mdl_vertex_descriptor_attribute_count(self.handle.as_ptr()) as usize }
188    }
189
190    #[must_use]
191    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
192    pub fn attribute_at(&self, index: usize) -> Option<VertexAttribute> {
193        let ptr =
194            // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
195            unsafe { ffi::mdl_vertex_descriptor_attribute_at(self.handle.as_ptr(), index as u64) };
196        // SAFETY: The unsafe operation is valid in this context.
197        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(VertexAttribute::from_handle)
198    }
199
200    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
201    pub fn attribute_named(&self, name: &str) -> Result<Option<VertexAttribute>> {
202        let name = c_string(name)?;
203        // SAFETY: The unsafe operation is valid in this context.
204        let ptr = unsafe {
205            ffi::mdl_vertex_descriptor_attribute_named(self.handle.as_ptr(), name.as_ptr())
206        };
207        // SAFETY: The unsafe operation is valid in this context.
208        Ok(unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(VertexAttribute::from_handle))
209    }
210
211    #[must_use]
212    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
213    pub fn attributes(&self) -> Vec<VertexAttribute> {
214        (0..self.attribute_count())
215            .filter_map(|index| self.attribute_at(index))
216            .collect()
217    }
218
219    #[must_use]
220    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
221    pub fn layout_count(&self) -> usize {
222        // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
223        unsafe { ffi::mdl_vertex_descriptor_layout_count(self.handle.as_ptr()) as usize }
224    }
225
226    #[must_use]
227    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
228    pub fn layout_at(&self, index: usize) -> Option<VertexBufferLayout> {
229        let ptr =
230            // SAFETY: Output pointers are initialized and managed; FFI function is called safely.
231            unsafe { ffi::mdl_vertex_descriptor_layout_at(self.handle.as_ptr(), index as u64) };
232        // SAFETY: The unsafe operation is valid in this context.
233        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(VertexBufferLayout::from_handle)
234    }
235
236    #[must_use]
237    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
238    pub fn layouts(&self) -> Vec<VertexBufferLayout> {
239        (0..self.layout_count())
240            .filter_map(|index| self.layout_at(index))
241            .collect()
242    }
243
244    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
245    pub fn reset(&self) {
246        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
247        unsafe { ffi::mdl_vertex_descriptor_reset(self.handle.as_ptr()) };
248    }
249
250    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
251    pub fn set_packed_offsets(&self) {
252        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
253        unsafe { ffi::mdl_vertex_descriptor_set_packed_offsets(self.handle.as_ptr()) };
254    }
255
256    /// Calls the corresponding Model I/O method on the wrapped Model I/O vertex descriptor counterpart.
257    pub fn set_packed_strides(&self) {
258        // SAFETY: ObjectHandle wraps a valid opaque pointer from Swift; FFI function accepts it safely.
259        unsafe { ffi::mdl_vertex_descriptor_set_packed_strides(self.handle.as_ptr()) };
260    }
261}