1use crate::{ffi, DecodePosition, VertexDataAdapter};
2use bitflags::bitflags;
3use std::mem;
4
5bitflags! {
6 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
7 pub struct SimplifyOptions : u32 {
8 const None = 0;
9 const LockBorder = 1;
14 const Sparse = 2;
17 const ErrorAbsolute = 4;
19 const Prune = 8;
22 const Regularize = 16;
25 const Permissive = 32;
27 }
28}
29
30pub fn simplify(
38 indices: &[u32],
39 vertices: &VertexDataAdapter<'_>,
40 target_count: usize,
41 target_error: f32,
42 options: SimplifyOptions,
43 result_error: Option<&mut f32>,
44) -> Vec<u32> {
45 let mut result: Vec<u32> = vec![0; indices.len()];
46 let index_count = unsafe {
47 ffi::meshopt_simplify(
48 result.as_mut_ptr().cast(),
49 indices.as_ptr().cast(),
50 indices.len(),
51 vertices.pos_ptr(),
52 vertices.vertex_count,
53 vertices.vertex_stride,
54 target_count,
55 target_error,
56 options.bits(),
57 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
58 )
59 };
60 result.resize(index_count, 0u32);
61 result
62}
63
64pub fn simplify_decoder<T: DecodePosition>(
72 indices: &[u32],
73 vertices: &[T],
74 target_count: usize,
75 target_error: f32,
76 options: SimplifyOptions,
77 result_error: Option<&mut f32>,
78) -> Vec<u32> {
79 let positions = vertices
80 .iter()
81 .map(|vertex| vertex.decode_position())
82 .collect::<Vec<[f32; 3]>>();
83 let mut result: Vec<u32> = vec![0; indices.len()];
84 let index_count = unsafe {
85 ffi::meshopt_simplify(
86 result.as_mut_ptr().cast(),
87 indices.as_ptr().cast(),
88 indices.len(),
89 positions.as_ptr().cast(),
90 positions.len(),
91 mem::size_of::<f32>() * 3,
92 target_count,
93 target_error,
94 options.bits(),
95 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
96 )
97 };
98 result.resize(index_count, 0u32);
99 result
100}
101
102pub fn simplify_with_locks(
110 indices: &[u32],
111 vertices: &VertexDataAdapter<'_>,
112 vertex_lock: &[bool],
113 target_count: usize,
114 target_error: f32,
115 options: SimplifyOptions,
116 result_error: Option<&mut f32>,
117) -> Vec<u32> {
118 let mut result: Vec<u32> = vec![0; indices.len()];
119 let index_count = unsafe {
120 ffi::meshopt_simplifyWithAttributes(
121 result.as_mut_ptr().cast(),
122 indices.as_ptr().cast(),
123 indices.len(),
124 vertices.pos_ptr(),
125 vertices.vertex_count,
126 vertices.vertex_stride,
127 std::ptr::null(),
128 0,
129 std::ptr::null(),
130 0,
131 vertex_lock.as_ptr().cast(),
132 target_count,
133 target_error,
134 options.bits(),
135 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
136 )
137 };
138 result.resize(index_count, 0u32);
139 result
140}
141
142pub fn simplify_with_locks_decoder<T: DecodePosition>(
150 indices: &[u32],
151 vertices: &[T],
152 vertex_lock: &[bool],
153 target_count: usize,
154 target_error: f32,
155 options: SimplifyOptions,
156 result_error: Option<&mut f32>,
157) -> Vec<u32> {
158 let positions = vertices
159 .iter()
160 .map(|vertex| vertex.decode_position())
161 .collect::<Vec<[f32; 3]>>();
162 let mut result: Vec<u32> = vec![0; indices.len()];
163 let index_count = unsafe {
164 ffi::meshopt_simplifyWithAttributes(
165 result.as_mut_ptr().cast(),
166 indices.as_ptr().cast(),
167 indices.len(),
168 positions.as_ptr().cast(),
169 positions.len(),
170 mem::size_of::<f32>() * 3,
171 std::ptr::null(),
172 0,
173 std::ptr::null(),
174 0,
175 vertex_lock.as_ptr().cast(),
176 target_count,
177 target_error,
178 options.bits(),
179 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
180 )
181 };
182 result.resize(index_count, 0u32);
183 result
184}
185
186#[allow(clippy::too_many_arguments)]
195pub fn simplify_with_attributes_and_locks(
196 indices: &[u32],
197 vertices: &VertexDataAdapter<'_>,
198 vertex_attributes: &[f32],
199 vertex_attribute_weights: &[f32],
200 vertex_attributes_stride: usize,
201 vertex_lock: &[bool],
202 target_count: usize,
203 target_error: f32,
204 options: SimplifyOptions,
205 result_error: Option<&mut f32>,
206) -> Vec<u32> {
207 let mut result: Vec<u32> = vec![0; indices.len()];
208 let index_count = unsafe {
209 ffi::meshopt_simplifyWithAttributes(
210 result.as_mut_ptr().cast(),
211 indices.as_ptr().cast(),
212 indices.len(),
213 vertices.pos_ptr(),
214 vertices.vertex_count,
215 vertices.vertex_stride,
216 vertex_attributes.as_ptr(),
217 vertex_attributes_stride,
218 vertex_attribute_weights.as_ptr(),
219 vertex_attribute_weights.len(),
220 vertex_lock.as_ptr().cast(),
221 target_count,
222 target_error,
223 options.bits(),
224 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
225 )
226 };
227 result.resize(index_count, 0u32);
228 result
229}
230
231#[allow(clippy::too_many_arguments)]
240pub fn simplify_with_attributes_and_locks_decoder<T: DecodePosition>(
241 indices: &[u32],
242 vertices: &[T],
243 vertex_attributes: &[f32],
244 vertex_attribute_weights: &[f32],
245 vertex_attributes_stride: usize,
246 vertex_lock: &[bool],
247 target_count: usize,
248 target_error: f32,
249 options: SimplifyOptions,
250 result_error: Option<&mut f32>,
251) -> Vec<u32> {
252 let positions = vertices
253 .iter()
254 .map(|vertex| vertex.decode_position())
255 .collect::<Vec<[f32; 3]>>();
256 let mut result: Vec<u32> = vec![0; indices.len()];
257 let index_count = unsafe {
258 ffi::meshopt_simplifyWithAttributes(
259 result.as_mut_ptr().cast(),
260 indices.as_ptr().cast(),
261 indices.len(),
262 positions.as_ptr().cast(),
263 positions.len(),
264 mem::size_of::<f32>() * 3,
265 vertex_attributes.as_ptr(),
266 vertex_attributes_stride,
267 vertex_attribute_weights.as_ptr(),
268 vertex_attribute_weights.len(),
269 vertex_lock.as_ptr().cast(),
270 target_count,
271 target_error,
272 options.bits(),
273 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
274 )
275 };
276 result.resize(index_count, 0u32);
277 result
278}
279
280pub fn simplify_sloppy(
289 indices: &[u32],
290 vertices: &VertexDataAdapter<'_>,
291 target_count: usize,
292 target_error: f32,
293 result_error: Option<&mut f32>,
294) -> Vec<u32> {
295 let mut result: Vec<u32> = vec![0; indices.len()];
296 let index_count = unsafe {
297 ffi::meshopt_simplifySloppy(
298 result.as_mut_ptr().cast(),
299 indices.as_ptr().cast(),
300 indices.len(),
301 vertices.pos_ptr(),
302 vertices.vertex_count,
303 vertices.vertex_stride,
304 std::ptr::null(),
305 target_count,
306 target_error,
307 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
308 )
309 };
310 result.resize(index_count, 0u32);
311 result
312}
313
314pub fn simplify_sloppy_decoder<T: DecodePosition>(
323 indices: &[u32],
324 vertices: &[T],
325 target_count: usize,
326 target_error: f32,
327 result_error: Option<&mut f32>,
328) -> Vec<u32> {
329 let positions = vertices
330 .iter()
331 .map(|vertex| vertex.decode_position())
332 .collect::<Vec<[f32; 3]>>();
333 let mut result: Vec<u32> = vec![0; indices.len()];
334 let index_count = unsafe {
335 ffi::meshopt_simplifySloppy(
336 result.as_mut_ptr().cast(),
337 indices.as_ptr().cast(),
338 indices.len(),
339 positions.as_ptr().cast(),
340 positions.len(),
341 mem::size_of::<f32>() * 3,
342 std::ptr::null(),
343 target_count,
344 target_error,
345 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
346 )
347 };
348 result.resize(index_count, 0u32);
349 result
350}
351
352pub fn simplify_sloppy_with_locks(
362 indices: &[u32],
363 vertices: &VertexDataAdapter<'_>,
364 vertex_lock: &[bool],
365 target_count: usize,
366 target_error: f32,
367 result_error: Option<&mut f32>,
368) -> Vec<u32> {
369 let positions = vertices.pos_ptr();
370 let mut result: Vec<u32> = vec![0; indices.len()];
371 let index_count = unsafe {
372 ffi::meshopt_simplifySloppy(
373 result.as_mut_ptr().cast(),
374 indices.as_ptr().cast(),
375 indices.len(),
376 positions.cast(),
377 vertices.vertex_count,
378 vertices.vertex_stride,
379 vertex_lock.as_ptr().cast(),
380 target_count,
381 target_error,
382 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
383 )
384 };
385 result.resize(index_count, 0u32);
386 result
387}
388
389pub fn simplify_sloppy_with_locks_decoder<T: DecodePosition>(
399 indices: &[u32],
400 vertices: &[T],
401 vertex_lock: &[bool],
402 target_count: usize,
403 target_error: f32,
404 result_error: Option<&mut f32>,
405) -> Vec<u32> {
406 let positions = vertices
407 .iter()
408 .map(|vertex| vertex.decode_position())
409 .collect::<Vec<[f32; 3]>>();
410 let mut result: Vec<u32> = vec![0; indices.len()];
411 let index_count = unsafe {
412 ffi::meshopt_simplifySloppy(
413 result.as_mut_ptr().cast(),
414 indices.as_ptr().cast(),
415 indices.len(),
416 positions.as_ptr().cast(),
417 positions.len(),
418 mem::size_of::<f32>() * 3,
419 vertex_lock.as_ptr().cast(),
420 target_count,
421 target_error,
422 result_error.map_or_else(std::ptr::null_mut, |v| v as *mut _),
423 )
424 };
425 result.resize(index_count, 0u32);
426 result
427}
428
429pub fn simplify_scale(vertices: &VertexDataAdapter<'_>) -> f32 {
434 unsafe {
435 ffi::meshopt_simplifyScale(
436 vertices.pos_ptr(),
437 vertices.vertex_count,
438 vertices.vertex_stride,
439 )
440 }
441}
442
443pub fn simplify_scale_decoder<T: DecodePosition>(vertices: &[T]) -> f32 {
448 let positions = vertices
449 .iter()
450 .map(|vertex| vertex.decode_position())
451 .collect::<Vec<[f32; 3]>>();
452
453 unsafe {
454 ffi::meshopt_simplifyScale(
455 positions.as_ptr().cast(),
456 positions.len(),
457 mem::size_of::<f32>() * 3,
458 )
459 }
460}
461
462#[cfg(test)]
463mod tests {
464 use super::*;
465 use crate::typed_to_bytes;
466
467 #[test]
468 fn test_simplify_sloppy_with_locks() {
469 let indices = &[
474 0, 2, 1, 1, 2, 3, 3, 2, 4, 2, 5, 4, ];
479
480 let vertices: &[f32] = &[
481 0.0, 4.0, 0.0, 0.0, 1.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 4.0, 0.0, 0.0, ];
488
489 let vertex_locks = &[true, false, true, false, false, true];
491
492 let vertices_adapter =
493 VertexDataAdapter::new(typed_to_bytes(vertices), 3 * mem::size_of::<f32>(), 0).unwrap();
494
495 let mut result_error = 0.0f32;
496 let result = simplify_sloppy_with_locks(
497 indices,
498 &vertices_adapter,
499 vertex_locks,
500 3, 1.0,
502 Some(&mut result_error),
503 );
504
505 assert_eq!(result.len(), 6);
507 assert_eq!(result_error, 0.0);
508
509 let expected = &[0, 2, 1, 1, 2, 5];
511 assert_eq!(result, expected);
512 }
513}