meshopt/
shadow.rs

1use crate::{ffi, DecodePosition, VertexDataAdapter, VertexStream};
2
3/// Generate index buffer that can be used for more efficient rendering when only a subset of the vertex
4/// attributes is necessary.
5///
6/// All vertices that are binary equivalent (wrt first `vertex_size` bytes) map to
7/// the first vertex in the original vertex buffer.
8///
9/// This makes it possible to use the index buffer for Z pre-pass or shadowmap rendering, while using
10/// the original index buffer for regular rendering.
11pub fn generate_shadow_indices(indices: &[u32], vertices: &VertexDataAdapter<'_>) -> Vec<u32> {
12    let vertex_data = vertices.reader.get_ref();
13    let vertex_data = vertex_data.as_ptr().cast::<u8>();
14    let positions = unsafe { vertex_data.add(vertices.position_offset) };
15    let mut shadow_indices: Vec<u32> = vec![0; indices.len()];
16    unsafe {
17        ffi::meshopt_generateShadowIndexBuffer(
18            shadow_indices.as_mut_ptr(),
19            indices.as_ptr(),
20            indices.len(),
21            positions.cast(),
22            vertices.vertex_count,
23            std::mem::size_of::<f32>() * 3,
24            vertices.vertex_stride,
25        );
26    }
27    shadow_indices
28}
29
30/// Generate index buffer that can be used for more efficient rendering when only a subset of the vertex
31/// attributes is necessary.
32///
33/// All vertices that are binary equivalent (wrt first `vertex_size` bytes) map to
34/// the first vertex in the original vertex buffer.
35///
36/// This makes it possible to use the index buffer for Z pre-pass or shadowmap rendering, while using
37/// the original index buffer for regular rendering.
38pub fn generate_shadow_indices_decoder<T: DecodePosition>(
39    indices: &[u32],
40    vertices: &[T],
41) -> Vec<u32> {
42    let vertices = vertices
43        .iter()
44        .map(|vertex| vertex.decode_position())
45        .collect::<Vec<[f32; 3]>>();
46    let positions = vertices.as_ptr().cast();
47    let mut shadow_indices: Vec<u32> = vec![0; indices.len()];
48    unsafe {
49        ffi::meshopt_generateShadowIndexBuffer(
50            shadow_indices.as_mut_ptr(),
51            indices.as_ptr(),
52            indices.len(),
53            positions,
54            vertices.len() * 3,
55            std::mem::size_of::<f32>() * 3,
56            std::mem::size_of::<f32>() * 3,
57        );
58    }
59    shadow_indices
60}
61
62/// Generate index buffer that can be used for more efficient rendering when only a subset of the vertex
63/// attributes is necessary.
64///
65/// All vertices that are binary equivalent (wrt specified streams) map to the
66/// first vertex in the original vertex buffer.
67///
68/// This makes it possible to use the index buffer for Z pre-pass or shadowmap rendering, while using
69/// the original index buffer for regular rendering.
70pub fn generate_shadow_indices_multi(
71    indices: &[u32],
72    vertex_count: usize,
73    streams: &[VertexStream<'_>],
74) -> Vec<u32> {
75    let streams: Vec<ffi::meshopt_Stream> = streams
76        .iter()
77        .map(|stream| ffi::meshopt_Stream {
78            data: stream.data.cast(),
79            size: stream.size,
80            stride: stream.stride,
81        })
82        .collect();
83    let mut shadow_indices: Vec<u32> = vec![0; indices.len()];
84    unsafe {
85        ffi::meshopt_generateShadowIndexBufferMulti(
86            shadow_indices.as_mut_ptr(),
87            indices.as_ptr(),
88            indices.len(),
89            vertex_count,
90            streams.as_ptr(),
91            streams.len(),
92        );
93    }
94    shadow_indices
95}