diff --git a/Cargo.toml b/Cargo.toml index dc5e25e..120a37b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ maintenance = { status = "actively-developed" } [dependencies] float-cmp = "0.9" thiserror = "1.0" +bitflags = "2.4.0" [build-dependencies] cc = { version = "1.0" } diff --git a/examples/demo.rs b/examples/demo.rs index 7ee705b..3ff7706 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -655,6 +655,7 @@ fn simplify(mesh: &Mesh) { &vertex_adapter, ::std::cmp::min(src.len(), target_index_count), target_error, + meshopt::SimplifyOptions::None, ); } lods.push(lod); diff --git a/gen/bindings.rs b/gen/bindings.rs index f87f48b..1d355d3 100644 --- a/gen/bindings.rs +++ b/gen/bindings.rs @@ -1,7 +1,7 @@ /* automatically generated by rust-bindgen 0.59.2 */ -#[doc = " Vertex attribute stream, similar to glVertexPointer"] -#[doc = " Each element takes size bytes, with stride controlling the spacing between successive elements."] +#[doc = " Vertex attribute stream"] +#[doc = " Each element takes size bytes, beginning at data, with stride controlling the spacing between successive elements (stride >= size)."] #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct meshopt_Stream { @@ -111,7 +111,7 @@ extern "C" { #[doc = " This can be used to implement algorithms like silhouette detection/expansion and other forms of GS-driven rendering."] #[doc = ""] #[doc = " destination must contain enough space for the resulting index buffer (index_count*2 elements)"] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] pub fn meshopt_generateAdjacencyIndexBuffer( destination: *mut ::std::os::raw::c_uint, indices: *const ::std::os::raw::c_uint, @@ -133,7 +133,7 @@ extern "C" { #[doc = " See \"Tessellation on Any Budget\" (John McDonald, GDC 2011) for implementation details."] #[doc = ""] #[doc = " destination must contain enough space for the resulting index buffer (index_count*4 elements)"] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] pub fn meshopt_generateTessellationIndexBuffer( destination: *mut ::std::os::raw::c_uint, indices: *const ::std::os::raw::c_uint, @@ -192,7 +192,7 @@ extern "C" { #[doc = ""] #[doc = " destination must contain enough space for the resulting index buffer (index_count elements)"] #[doc = " indices must contain index data that is the result of meshopt_optimizeVertexCache (*not* the original mesh indices!)"] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] #[doc = " threshold indicates how much the overdraw optimizer can degrade vertex cache efficiency (1.05 = up to 5%) to reduce overdraw more efficiently"] pub fn meshopt_optimizeOverdraw( destination: *mut ::std::os::raw::c_uint, @@ -419,7 +419,7 @@ extern "C" { ); } extern "C" { - #[doc = " Experimental: Mesh simplifier"] + #[doc = " Mesh simplifier"] #[doc = " Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible"] #[doc = " The algorithm tries to preserve mesh topology and can stop short of the target goal based on topology constraints or target error."] #[doc = " If not all attributes from the input mesh are required, it's recommended to reindex the mesh using meshopt_generateShadowIndexBuffer prior to simplification."] @@ -428,8 +428,9 @@ extern "C" { #[doc = " If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended."] #[doc = ""] #[doc = " destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)!"] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] #[doc = " target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation"] + #[doc = " options must be a bitmask composed of meshopt_SimplifyX options; 0 is a safe default"] #[doc = " result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification"] pub fn meshopt_simplify( destination: *mut ::std::os::raw::c_uint, @@ -440,6 +441,7 @@ extern "C" { vertex_positions_stride: usize, target_index_count: usize, target_error: f32, + options: ::std::os::raw::c_uint, result_error: *mut f32, ) -> usize; } @@ -452,7 +454,7 @@ extern "C" { #[doc = " If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended."] #[doc = ""] #[doc = " destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)!"] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] #[doc = " target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation"] #[doc = " result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification"] pub fn meshopt_simplifySloppy( @@ -475,7 +477,7 @@ extern "C" { #[doc = " If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended."] #[doc = ""] #[doc = " destination must contain enough space for the target index buffer (target_vertex_count elements)"] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] pub fn meshopt_simplifyPoints( destination: *mut ::std::os::raw::c_uint, vertex_positions: *const f32, @@ -485,7 +487,7 @@ extern "C" { ) -> usize; } extern "C" { - #[doc = " Experimental: Returns the error scaling factor used by the simplifier to convert between absolute and relative extents"] + #[doc = " Returns the error scaling factor used by the simplifier to convert between absolute and relative extents"] #[doc = ""] #[doc = " Absolute error must be *divided* by the scaling factor before passing it to meshopt_simplify as target_error"] #[doc = " Relative error returned by meshopt_simplify via result_error must be *multiplied* by the scaling factor to get absolute error."] @@ -564,7 +566,7 @@ extern "C" { #[doc = " Returns overdraw statistics using a software rasterizer"] #[doc = " Results may not match actual GPU performance"] #[doc = ""] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] pub fn meshopt_analyzeOverdraw( indices: *const ::std::os::raw::c_uint, index_count: usize, @@ -608,7 +610,7 @@ extern "C" { #[doc = " meshlets must contain enough space for all meshlets, worst case size can be computed with meshopt_buildMeshletsBound"] #[doc = " meshlet_vertices must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_vertices"] #[doc = " meshlet_triangles must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_triangles * 3"] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] #[doc = " max_vertices and max_triangles must not exceed implementation limits (max_vertices <= 255 - not 256!, max_triangles <= 512)"] #[doc = " cone_weight should be set to 0 when cone culling is not used, and a value between 0 and 1 otherwise to balance between cluster size and cone culling efficiency"] pub fn meshopt_buildMeshlets( @@ -673,7 +675,7 @@ extern "C" { #[doc = " The formula that uses the apex is slightly more accurate but needs the apex; if you are already using bounding sphere"] #[doc = " to do frustum/occlusion culling, the formula that doesn't use the apex may be preferable."] #[doc = ""] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] #[doc = " index_count/3 should be less than or equal to 512 (the function assumes clusters of limited size)"] pub fn meshopt_computeClusterBounds( indices: *const ::std::os::raw::c_uint, @@ -711,7 +713,7 @@ extern "C" { #[doc = " Reorders triangles for spatial locality, and generates a new index buffer. The resulting index buffer can be used with other functions like optimizeVertexCache."] #[doc = ""] #[doc = " destination must contain enough space for the resulting index buffer (index_count elements)"] - #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer"] + #[doc = " vertex_positions should have float3 position in the first 12 bytes of each vertex"] pub fn meshopt_spatialSortTriangles( destination: *mut ::std::os::raw::c_uint, indices: *const ::std::os::raw::c_uint, diff --git a/src/simplify.rs b/src/simplify.rs index ffe817c..72d7147 100644 --- a/src/simplify.rs +++ b/src/simplify.rs @@ -1,6 +1,15 @@ use crate::{ffi, DecodePosition, VertexDataAdapter}; +use bitflags::bitflags; use std::mem; +bitflags! { + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct SimplifyOptions : u32 { + const None = 0; + const LockBorder = 1; + } +} + /// Reduces the number of triangles in the mesh, attempting to preserve mesh /// appearance as much as possible. /// @@ -13,6 +22,7 @@ pub fn simplify( vertices: &VertexDataAdapter<'_>, target_count: usize, target_error: f32, + options: SimplifyOptions, ) -> Vec { let vertex_data = vertices.reader.get_ref(); let vertex_data = vertex_data.as_ptr().cast::(); @@ -28,6 +38,7 @@ pub fn simplify( vertices.vertex_stride, target_count, target_error, + options.bits(), std::ptr::null_mut(), ) }; @@ -47,6 +58,7 @@ pub fn simplify_decoder( vertices: &[T], target_count: usize, target_error: f32, + options: SimplifyOptions, ) -> Vec { let positions = vertices .iter() @@ -63,6 +75,7 @@ pub fn simplify_decoder( mem::size_of::() * 3, target_count, target_error, + options.bits(), std::ptr::null_mut(), ) };