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}