use core::ffi::c_void;
pub struct MeshResource {
pub(crate) ptr: *mut c_void,
}
unsafe impl Send for MeshResource {}
unsafe impl Sync for MeshResource {}
impl Clone for MeshResource {
fn clone(&self) -> Self { unsafe { realitykit_sys::rk_retain(self.ptr) }; MeshResource { ptr: self.ptr } }
}
impl Drop for MeshResource {
fn drop(&mut self) { unsafe { realitykit_sys::rk_release(self.ptr) }; }
}
impl MeshResource {
pub fn box_(w: f32, h: f32, d: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_box(w, h, d) } }
}
pub fn box_chamfer(w: f32, h: f32, d: f32, corner_radius: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_box_chamfer(w, h, d, corner_radius) } }
}
pub fn cube(size: f32) -> Self { Self::box_(size, size, size) }
pub fn sphere(radius: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_sphere(radius) } }
}
pub fn plane(width: f32, depth: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_plane(width, depth) } }
}
pub fn plane_rounded(width: f32, depth: f32, corner_radius: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_plane_corner_radius(width, depth, corner_radius) } }
}
pub fn cone(height: f32, radius: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_cone(height, radius) } }
}
pub fn cylinder(height: f32, radius: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_cylinder(height, radius) } }
}
pub fn capsule(height: f32, radius: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_capsule(height, radius) } }
}
pub fn torus(mean_radius: f32, tube_radius: f32) -> Self {
MeshResource { ptr: unsafe { realitykit_sys::rk_mesh_torus(mean_radius, tube_radius) } }
}
pub fn text(string: &str, extrusion_depth: f32, font_size: f32) -> Self {
MeshResource {
ptr: unsafe { realitykit_sys::rk_mesh_text(string.as_ptr(), string.len(), extrusion_depth, font_size) }
}
}
pub fn from_buffers(
positions: &[f32],
normals: Option<&[f32]>,
uvs: Option<&[f32]>,
indices: Option<&[u32]>,
) -> Result<Self, String> {
assert_eq!(positions.len() % 3, 0, "positions must be f32 triples");
if let Some(n) = normals { assert_eq!(n.len() % 3, 0, "normals must be f32 triples"); }
if let Some(u) = uvs { assert_eq!(u.len() % 2, 0, "uvs must be f32 pairs"); }
if let Some(i) = indices { assert_eq!(i.len() % 3, 0, "indices must be u32 triples"); }
let (np, nc) = normals.map_or((core::ptr::null(), 0), |n| (n.as_ptr(), n.len() / 3));
let (up, uc) = uvs .map_or((core::ptr::null(), 0), |u| (u.as_ptr(), u.len() / 2));
let (ip, ic) = indices.map_or((core::ptr::null(), 0), |i| (i.as_ptr(), i.len()));
let mut err = [0u8; 2048];
let ptr = unsafe {
realitykit_sys::rk_mesh_from_buffers(
positions.as_ptr(), positions.len() / 3,
np, nc,
up, uc,
ip, ic,
err.as_mut_ptr(), err.len(),
)
};
if ptr.is_null() {
let n = err.iter().position(|&b| b == 0).unwrap_or(err.len());
Err(String::from_utf8_lossy(&err[..n]).into())
} else {
Ok(MeshResource { ptr })
}
}
}