modelio/
vertex_attribute.rs1use 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}