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)]
10pub struct VertexAttribute {
11    handle: ObjectHandle,
12}
13
14impl VertexAttribute {
15    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
16        Self { handle }
17    }
18
19    pub fn new(name: &str, format: u32, offset: usize, buffer_index: usize) -> Result<Self> {
20        let name = c_string(name)?;
21        let mut out_attribute = ptr::null_mut();
22        let mut out_error = ptr::null_mut();
23        let status = unsafe {
24            ffi::mdl_vertex_attribute_new(
25                name.as_ptr(),
26                format,
27                offset as u64,
28                buffer_index as u64,
29                &mut out_attribute,
30                &mut out_error,
31            )
32        };
33        crate::util::status_result(status, out_error)?;
34        Ok(Self::from_handle(required_handle(
35            out_attribute,
36            "MDLVertexAttribute",
37        )?))
38    }
39
40    pub fn info(&self) -> Result<VertexAttributeDescriptorInfo> {
41        parse_json(
42            unsafe { ffi::mdl_vertex_attribute_info_json(self.handle.as_ptr()) },
43            "MDLVertexAttribute",
44        )
45    }
46
47    pub fn set_name(&self, name: &str) -> Result<()> {
48        let name = c_string(name)?;
49        unsafe { ffi::mdl_vertex_attribute_set_name(self.handle.as_ptr(), name.as_ptr()) };
50        Ok(())
51    }
52
53    pub fn set_format(&self, format: u32) {
54        unsafe { ffi::mdl_vertex_attribute_set_format(self.handle.as_ptr(), format) };
55    }
56
57    pub fn set_offset(&self, offset: usize) {
58        unsafe { ffi::mdl_vertex_attribute_set_offset(self.handle.as_ptr(), offset as u64) };
59    }
60
61    pub fn set_buffer_index(&self, buffer_index: usize) {
62        unsafe {
63            ffi::mdl_vertex_attribute_set_buffer_index(self.handle.as_ptr(), buffer_index as u64);
64        };
65    }
66
67    pub fn set_time(&self, time: f64) {
68        unsafe { ffi::mdl_vertex_attribute_set_time(self.handle.as_ptr(), time) };
69    }
70
71    pub fn set_initialization_value(&self, value: [f32; 4]) {
72        unsafe {
73            ffi::mdl_vertex_attribute_set_initialization_value(
74                self.handle.as_ptr(),
75                value[0],
76                value[1],
77                value[2],
78                value[3],
79            );
80        };
81    }
82}
83
84#[derive(Debug, Clone)]
85pub struct VertexDescriptor {
86    handle: ObjectHandle,
87}
88
89impl VertexDescriptor {
90    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
91        Self { handle }
92    }
93
94    pub fn copy(&self) -> Result<Self> {
95        let mut out_descriptor = ptr::null_mut();
96        let mut out_error = ptr::null_mut();
97        let status = unsafe {
98            ffi::mdl_vertex_descriptor_new_copy(
99                self.handle.as_ptr(),
100                &mut out_descriptor,
101                &mut out_error,
102            )
103        };
104        crate::util::status_result(status, out_error)?;
105        Ok(Self::from_handle(required_handle(
106            out_descriptor,
107            "MDLVertexDescriptor",
108        )?))
109    }
110
111    pub fn info(&self) -> Result<VertexDescriptorInfo> {
112        parse_json(
113            unsafe { ffi::mdl_vertex_descriptor_info_json(self.handle.as_ptr()) },
114            "MDLVertexDescriptor",
115        )
116    }
117
118    #[must_use]
119    pub fn attribute_count(&self) -> usize {
120        unsafe { ffi::mdl_vertex_descriptor_attribute_count(self.handle.as_ptr()) as usize }
121    }
122
123    #[must_use]
124    pub fn attribute_at(&self, index: usize) -> Option<VertexAttribute> {
125        let ptr =
126            unsafe { ffi::mdl_vertex_descriptor_attribute_at(self.handle.as_ptr(), index as u64) };
127        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(VertexAttribute::from_handle)
128    }
129
130    pub fn attribute_named(&self, name: &str) -> Result<Option<VertexAttribute>> {
131        let name = c_string(name)?;
132        let ptr = unsafe {
133            ffi::mdl_vertex_descriptor_attribute_named(self.handle.as_ptr(), name.as_ptr())
134        };
135        Ok(unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(VertexAttribute::from_handle))
136    }
137
138    #[must_use]
139    pub fn attributes(&self) -> Vec<VertexAttribute> {
140        (0..self.attribute_count())
141            .filter_map(|index| self.attribute_at(index))
142            .collect()
143    }
144
145    pub fn reset(&self) {
146        unsafe { ffi::mdl_vertex_descriptor_reset(self.handle.as_ptr()) };
147    }
148
149    pub fn set_packed_offsets(&self) {
150        unsafe { ffi::mdl_vertex_descriptor_set_packed_offsets(self.handle.as_ptr()) };
151    }
152
153    pub fn set_packed_strides(&self) {
154        unsafe { ffi::mdl_vertex_descriptor_set_packed_strides(self.handle.as_ptr()) };
155    }
156}