embree4_rs/geometry/
tri_mesh.rs1use std::{mem::size_of, slice};
2
3use anyhow::{bail, Result};
4
5use crate::Device;
6
7use super::Geometry;
8
9pub struct TriangleMeshGeometry {
10 pub handle: embree4_sys::RTCGeometry,
11}
12
13impl TriangleMeshGeometry {
14 pub fn try_new(
35 device: &Device,
36 vertices: &[(f32, f32, f32)],
37 indices: &[(u32, u32, u32)],
38 ) -> Result<Self> {
39 let geometry = unsafe {
40 embree4_sys::rtcNewGeometry(device.handle, embree4_sys::RTCGeometryType::TRIANGLE)
41 };
42 if geometry.is_null() {
43 bail!("Failed to create geometry: {:?}", device.error());
44 }
45
46 let vertex_buf_ptr = unsafe {
47 embree4_sys::rtcSetNewGeometryBuffer(
48 geometry,
49 embree4_sys::RTCBufferType::VERTEX,
50 0,
51 embree4_sys::RTCFormat::FLOAT3,
52 3 * size_of::<f32>(),
53 vertices.len(),
54 )
55 };
56 if vertex_buf_ptr.is_null() {
57 bail!(
58 "Failed to create triangle mesh vertex buffer: {:?}",
59 device.error()
60 );
61 }
62 device.error_or((), "Failed not create triangle mesh vertex buffer")?;
63
64 let vertex_buf =
65 unsafe { slice::from_raw_parts_mut(vertex_buf_ptr as *mut f32, 3 * vertices.len()) };
66
67 for (i, v) in vertices.iter().enumerate() {
69 vertex_buf[3 * i] = v.0;
70 vertex_buf[3 * i + 1] = v.1;
71 vertex_buf[3 * i + 2] = v.2;
72 }
73
74 let index_buf_ptr = unsafe {
75 embree4_sys::rtcSetNewGeometryBuffer(
76 geometry,
77 embree4_sys::RTCBufferType::INDEX,
78 0,
79 embree4_sys::RTCFormat::UINT3,
80 3 * size_of::<u32>(),
81 indices.len(),
82 )
83 };
84 if index_buf_ptr.is_null() {
85 bail!(
86 "Failed to create triangle mesh index buffer: {:?}",
87 device.error()
88 );
89 }
90 device.error_or((), "Failed to create triangle mesh index buffer")?;
91
92 let index_buf =
93 unsafe { slice::from_raw_parts_mut(index_buf_ptr as *mut u32, 3 * indices.len()) };
94
95 for (i, idx) in indices.iter().enumerate() {
97 index_buf[3 * i] = idx.0;
98 index_buf[3 * i + 1] = idx.1;
99 index_buf[3 * i + 2] = idx.2;
100 }
101
102 unsafe {
103 embree4_sys::rtcCommitGeometry(geometry);
104 }
105 device.error_or((), "Failed to commit triangle mesh geometry")?;
106
107 Ok(Self { handle: geometry })
108 }
109}
110
111impl Drop for TriangleMeshGeometry {
112 fn drop(&mut self) {
113 unsafe {
114 embree4_sys::rtcReleaseGeometry(self.handle);
115 }
116 }
117}
118
119impl Geometry for TriangleMeshGeometry {
120 fn handle(&self) -> &embree4_sys::RTCGeometry {
121 &self.handle
122 }
123}