Skip to main content

modelio/
submesh.rs

1use crate::error::Result;
2use crate::ffi;
3use crate::handle::ObjectHandle;
4use crate::material::Material;
5use crate::mesh::MeshBuffer;
6use crate::types::{GeometryType, IndexBitDepth};
7use crate::util::{c_string, take_string};
8
9#[derive(Debug, Clone)]
10pub struct Submesh {
11    handle: ObjectHandle,
12}
13
14impl Submesh {
15    pub(crate) fn from_handle(handle: ObjectHandle) -> Self {
16        Self { handle }
17    }
18
19    #[must_use]
20    pub fn name(&self) -> Option<String> {
21        take_string(unsafe { ffi::mdl_submesh_name_string(self.handle.as_ptr()) })
22    }
23
24    pub fn set_name(&self, name: &str) -> Result<()> {
25        let name = c_string(name)?;
26        unsafe { ffi::mdl_submesh_set_name(self.handle.as_ptr(), name.as_ptr()) };
27        Ok(())
28    }
29
30    #[must_use]
31    pub fn index_count(&self) -> usize {
32        unsafe { ffi::mdl_submesh_index_count(self.handle.as_ptr()) as usize }
33    }
34
35    #[must_use]
36    pub fn index_type(&self) -> Option<IndexBitDepth> {
37        IndexBitDepth::from_raw(unsafe { ffi::mdl_submesh_index_type(self.handle.as_ptr()) })
38    }
39
40    #[must_use]
41    pub fn geometry_type(&self) -> Option<GeometryType> {
42        GeometryType::from_raw(unsafe { ffi::mdl_submesh_geometry_type(self.handle.as_ptr()) })
43    }
44
45    #[must_use]
46    pub fn index_buffer(&self) -> Option<MeshBuffer> {
47        let ptr = unsafe { ffi::mdl_submesh_index_buffer(self.handle.as_ptr()) };
48        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
49    }
50
51    #[must_use]
52    pub fn index_buffer_as_type(&self, index_type: IndexBitDepth) -> Option<MeshBuffer> {
53        let ptr = unsafe {
54            ffi::mdl_submesh_index_buffer_as_type(self.handle.as_ptr(), index_type.as_raw())
55        };
56        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(MeshBuffer::from_handle)
57    }
58
59    #[must_use]
60    pub fn material(&self) -> Option<Material> {
61        let ptr = unsafe { ffi::mdl_submesh_material(self.handle.as_ptr()) };
62        unsafe { ObjectHandle::from_retained_ptr(ptr) }.map(Material::from_handle)
63    }
64
65    pub fn set_material(&self, material: Option<&Material>) {
66        unsafe {
67            ffi::mdl_submesh_set_material(
68                self.handle.as_ptr(),
69                material.map_or(std::ptr::null_mut(), Material::as_ptr),
70            );
71        };
72    }
73}