|
@@ -1,7 +1,7 @@
|
|
/**
|
|
/**
|
|
- * meshoptimizer - version 0.20
|
|
|
|
|
|
+ * meshoptimizer - version 0.22
|
|
*
|
|
*
|
|
- * Copyright (C) 2016-2023, by Arseny Kapoulkine ([email protected])
|
|
|
|
|
|
+ * Copyright (C) 2016-2024, by Arseny Kapoulkine ([email protected])
|
|
* Report bugs and download new versions at https://github.com/zeux/meshoptimizer
|
|
* Report bugs and download new versions at https://github.com/zeux/meshoptimizer
|
|
*
|
|
*
|
|
* This library is distributed under the MIT License. See notice at the end of this file.
|
|
* This library is distributed under the MIT License. See notice at the end of this file.
|
|
@@ -12,7 +12,7 @@
|
|
#include <stddef.h>
|
|
#include <stddef.h>
|
|
|
|
|
|
/* Version macro; major * 1000 + minor * 10 + patch */
|
|
/* Version macro; major * 1000 + minor * 10 + patch */
|
|
-#define MESHOPTIMIZER_VERSION 200 /* 0.20 */
|
|
|
|
|
|
+#define MESHOPTIMIZER_VERSION 220 /* 0.22 */
|
|
|
|
|
|
/* If no API is defined, assume default */
|
|
/* If no API is defined, assume default */
|
|
#ifndef MESHOPTIMIZER_API
|
|
#ifndef MESHOPTIMIZER_API
|
|
@@ -29,11 +29,14 @@
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* Experimental APIs have unstable interface and might have implementation that's not fully tested or optimized */
|
|
/* Experimental APIs have unstable interface and might have implementation that's not fully tested or optimized */
|
|
|
|
+#ifndef MESHOPTIMIZER_EXPERIMENTAL
|
|
#define MESHOPTIMIZER_EXPERIMENTAL MESHOPTIMIZER_API
|
|
#define MESHOPTIMIZER_EXPERIMENTAL MESHOPTIMIZER_API
|
|
|
|
+#endif
|
|
|
|
|
|
/* C interface */
|
|
/* C interface */
|
|
#ifdef __cplusplus
|
|
#ifdef __cplusplus
|
|
-extern "C" {
|
|
|
|
|
|
+extern "C"
|
|
|
|
+{
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -137,6 +140,19 @@ MESHOPTIMIZER_API void meshopt_generateAdjacencyIndexBuffer(unsigned int* destin
|
|
*/
|
|
*/
|
|
MESHOPTIMIZER_API void meshopt_generateTessellationIndexBuffer(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
|
MESHOPTIMIZER_API void meshopt_generateTessellationIndexBuffer(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Experimental: Generate index buffer that can be used for visibility buffer rendering and returns the size of the reorder table
|
|
|
|
+ * Each triangle's provoking vertex index is equal to primitive id; this allows passing it to the fragment shader using nointerpolate attribute.
|
|
|
|
+ * This is important for performance on hardware where primitive id can't be accessed efficiently in fragment shader.
|
|
|
|
+ * The reorder table stores the original vertex id for each vertex in the new index buffer, and should be used in the vertex shader to load vertex data.
|
|
|
|
+ * The provoking vertex is assumed to be the first vertex in the triangle; if this is not the case (OpenGL), rotate each triangle (abc -> bca) before rendering.
|
|
|
|
+ * For maximum efficiency the input index buffer should be optimized for vertex cache first.
|
|
|
|
+ *
|
|
|
|
+ * destination must contain enough space for the resulting index buffer (index_count elements)
|
|
|
|
+ * reorder must contain enough space for the worst case reorder table (vertex_count + index_count/3 elements)
|
|
|
|
+ */
|
|
|
|
+MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_generateProvokingIndexBuffer(unsigned int* destination, unsigned int* reorder, const unsigned int* indices, size_t index_count, size_t vertex_count);
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Vertex transform cache optimizer
|
|
* Vertex transform cache optimizer
|
|
* Reorders indices to reduce the number of GPU vertex shader invocations
|
|
* Reorders indices to reduce the number of GPU vertex shader invocations
|
|
@@ -254,6 +270,7 @@ MESHOPTIMIZER_API int meshopt_decodeIndexSequence(void* destination, size_t inde
|
|
* Returns encoded data size on success, 0 on error; the only error condition is if buffer doesn't have enough space
|
|
* Returns encoded data size on success, 0 on error; the only error condition is if buffer doesn't have enough space
|
|
* This function works for a single vertex stream; for multiple vertex streams, call meshopt_encodeVertexBuffer for each stream.
|
|
* This function works for a single vertex stream; for multiple vertex streams, call meshopt_encodeVertexBuffer for each stream.
|
|
* Note that all vertex_size bytes of each vertex are encoded verbatim, including padding which should be zero-initialized.
|
|
* Note that all vertex_size bytes of each vertex are encoded verbatim, including padding which should be zero-initialized.
|
|
|
|
+ * For maximum efficiency the vertex buffer being encoded has to be quantized and optimized for locality of reference (cache/fetch) first.
|
|
*
|
|
*
|
|
* buffer must contain enough space for the encoded vertex buffer (use meshopt_encodeVertexBufferBound to compute worst case size)
|
|
* buffer must contain enough space for the encoded vertex buffer (use meshopt_encodeVertexBufferBound to compute worst case size)
|
|
*/
|
|
*/
|
|
@@ -289,9 +306,9 @@ MESHOPTIMIZER_API int meshopt_decodeVertexBuffer(void* destination, size_t verte
|
|
* meshopt_decodeFilterExp decodes exponential encoding of floating-point data with 8-bit exponent and 24-bit integer mantissa as 2^E*M.
|
|
* meshopt_decodeFilterExp decodes exponential encoding of floating-point data with 8-bit exponent and 24-bit integer mantissa as 2^E*M.
|
|
* Each 32-bit component is decoded in isolation; stride must be divisible by 4.
|
|
* Each 32-bit component is decoded in isolation; stride must be divisible by 4.
|
|
*/
|
|
*/
|
|
-MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterOct(void* buffer, size_t count, size_t stride);
|
|
|
|
-MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterQuat(void* buffer, size_t count, size_t stride);
|
|
|
|
-MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t count, size_t stride);
|
|
|
|
|
|
+MESHOPTIMIZER_API void meshopt_decodeFilterOct(void* buffer, size_t count, size_t stride);
|
|
|
|
+MESHOPTIMIZER_API void meshopt_decodeFilterQuat(void* buffer, size_t count, size_t stride);
|
|
|
|
+MESHOPTIMIZER_API void meshopt_decodeFilterExp(void* buffer, size_t count, size_t stride);
|
|
|
|
|
|
/**
|
|
/**
|
|
* Vertex buffer filter encoders
|
|
* Vertex buffer filter encoders
|
|
@@ -311,32 +328,40 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t cou
|
|
*/
|
|
*/
|
|
enum meshopt_EncodeExpMode
|
|
enum meshopt_EncodeExpMode
|
|
{
|
|
{
|
|
- /* When encoding exponents, use separate values for each component (maximum quality) */
|
|
|
|
- meshopt_EncodeExpSeparate,
|
|
|
|
- /* When encoding exponents, use shared value for all components of each vector (better compression) */
|
|
|
|
- meshopt_EncodeExpSharedVector,
|
|
|
|
- /* When encoding exponents, use shared value for each component of all vectors (best compression) */
|
|
|
|
- meshopt_EncodeExpSharedComponent,
|
|
|
|
|
|
+ /* When encoding exponents, use separate values for each component (maximum quality) */
|
|
|
|
+ meshopt_EncodeExpSeparate,
|
|
|
|
+ /* When encoding exponents, use shared value for all components of each vector (better compression) */
|
|
|
|
+ meshopt_EncodeExpSharedVector,
|
|
|
|
+ /* When encoding exponents, use shared value for each component of all vectors (best compression) */
|
|
|
|
+ meshopt_EncodeExpSharedComponent,
|
|
|
|
+ /* Experimental: When encoding exponents, use separate values for each component, but clamp to 0 (good quality if very small values are not important) */
|
|
|
|
+ meshopt_EncodeExpClamped,
|
|
};
|
|
};
|
|
|
|
|
|
-MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterOct(void* destination, size_t count, size_t stride, int bits, const float* data);
|
|
|
|
-MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterQuat(void* destination, size_t count, size_t stride, int bits, const float* data);
|
|
|
|
-MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_t count, size_t stride, int bits, const float* data, enum meshopt_EncodeExpMode mode);
|
|
|
|
|
|
+MESHOPTIMIZER_API void meshopt_encodeFilterOct(void* destination, size_t count, size_t stride, int bits, const float* data);
|
|
|
|
+MESHOPTIMIZER_API void meshopt_encodeFilterQuat(void* destination, size_t count, size_t stride, int bits, const float* data);
|
|
|
|
+MESHOPTIMIZER_API void meshopt_encodeFilterExp(void* destination, size_t count, size_t stride, int bits, const float* data, enum meshopt_EncodeExpMode mode);
|
|
|
|
|
|
/**
|
|
/**
|
|
* Simplification options
|
|
* Simplification options
|
|
*/
|
|
*/
|
|
enum
|
|
enum
|
|
{
|
|
{
|
|
- /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */
|
|
|
|
- meshopt_SimplifyLockBorder = 1 << 0,
|
|
|
|
|
|
+ /* Do not move vertices that are located on the topological border (vertices on triangle edges that don't have a paired triangle). Useful for simplifying portions of the larger mesh. */
|
|
|
|
+ meshopt_SimplifyLockBorder = 1 << 0,
|
|
|
|
+ /* Improve simplification performance assuming input indices are a sparse subset of the mesh. Note that error becomes relative to subset extents. */
|
|
|
|
+ meshopt_SimplifySparse = 1 << 1,
|
|
|
|
+ /* Treat error limit and resulting error as absolute instead of relative to mesh extents. */
|
|
|
|
+ meshopt_SimplifyErrorAbsolute = 1 << 2,
|
|
|
|
+ /* Experimental: remove disconnected parts of the mesh during simplification incrementally, regardless of the topological restrictions inside components. */
|
|
|
|
+ meshopt_SimplifyPrune = 1 << 3,
|
|
};
|
|
};
|
|
|
|
|
|
/**
|
|
/**
|
|
* Mesh simplifier
|
|
* Mesh simplifier
|
|
* Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible
|
|
* Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible
|
|
* The algorithm tries to preserve mesh topology and can stop short of the target goal based on topology constraints or target error.
|
|
* The algorithm tries to preserve mesh topology and can stop short of the target goal based on topology constraints or target error.
|
|
- * If not all attributes from the input mesh are required, it's recommended to reindex the mesh using meshopt_generateShadowIndexBuffer prior to simplification.
|
|
|
|
|
|
+ * If not all attributes from the input mesh are required, it's recommended to reindex the mesh without them prior to simplification.
|
|
* Returns the number of indices after simplification, with destination containing new index data
|
|
* Returns the number of indices after simplification, with destination containing new index data
|
|
* The resulting index buffer references vertices from the original vertex buffer.
|
|
* The resulting index buffer references vertices from the original vertex buffer.
|
|
* If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended.
|
|
* If the original vertex data isn't required, creating a compact vertex buffer using meshopt_optimizeVertexFetch is recommended.
|
|
@@ -351,15 +376,15 @@ MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsig
|
|
|
|
|
|
/**
|
|
/**
|
|
* Experimental: Mesh simplifier with attribute metric
|
|
* Experimental: Mesh simplifier with attribute metric
|
|
- * The algorithm ehnahces meshopt_simplify by incorporating attribute values into the error metric used to prioritize simplification order; see meshopt_simplify documentation for details.
|
|
|
|
|
|
+ * The algorithm enhances meshopt_simplify by incorporating attribute values into the error metric used to prioritize simplification order; see meshopt_simplify documentation for details.
|
|
* Note that the number of attributes affects memory requirements and running time; this algorithm requires ~1.5x more memory and time compared to meshopt_simplify when using 4 scalar attributes.
|
|
* Note that the number of attributes affects memory requirements and running time; this algorithm requires ~1.5x more memory and time compared to meshopt_simplify when using 4 scalar attributes.
|
|
*
|
|
*
|
|
* vertex_attributes should have attribute_count floats for each vertex
|
|
* vertex_attributes should have attribute_count floats for each vertex
|
|
- * attribute_weights should have attribute_count floats in total; the weights determine relative priority of attributes between each other and wrt position. The recommended weight range is [1e-3..1e-1], assuming attribute data is in [0..1] range.
|
|
|
|
- * attribute_count must be <= 16
|
|
|
|
- * TODO target_error/result_error currently use combined distance+attribute error; this may change in the future
|
|
|
|
|
|
+ * attribute_weights should have attribute_count floats in total; the weights determine relative priority of attributes between each other and wrt position
|
|
|
|
+ * attribute_count must be <= 32
|
|
|
|
+ * vertex_lock can be NULL; when it's not NULL, it should have a value for each vertex; 1 denotes vertices that can't be moved
|
|
*/
|
|
*/
|
|
-MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* result_error);
|
|
|
|
|
|
+MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error);
|
|
|
|
|
|
/**
|
|
/**
|
|
* Experimental: Mesh simplifier (sloppy)
|
|
* Experimental: Mesh simplifier (sloppy)
|
|
@@ -386,6 +411,7 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destinati
|
|
* destination must contain enough space for the target index buffer (target_vertex_count elements)
|
|
* destination must contain enough space for the target index buffer (target_vertex_count elements)
|
|
* vertex_positions should have float3 position in the first 12 bytes of each vertex
|
|
* vertex_positions should have float3 position in the first 12 bytes of each vertex
|
|
* vertex_colors should can be NULL; when it's not NULL, it should have float3 color in the first 12 bytes of each vertex
|
|
* vertex_colors should can be NULL; when it's not NULL, it should have float3 color in the first 12 bytes of each vertex
|
|
|
|
+ * color_weight determines relative priority of color wrt position; 1.0 is a safe default
|
|
*/
|
|
*/
|
|
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_colors, size_t vertex_colors_stride, float color_weight, size_t target_vertex_count);
|
|
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_colors, size_t vertex_colors_stride, float color_weight, size_t target_vertex_count);
|
|
|
|
|
|
@@ -464,6 +490,13 @@ struct meshopt_VertexFetchStatistics
|
|
*/
|
|
*/
|
|
MESHOPTIMIZER_API struct meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const unsigned int* indices, size_t index_count, size_t vertex_count, size_t vertex_size);
|
|
MESHOPTIMIZER_API struct meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const unsigned int* indices, size_t index_count, size_t vertex_count, size_t vertex_size);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Meshlet is a small mesh cluster (subset) that consists of:
|
|
|
|
+ * - triangles, an 8-bit micro triangle (index) buffer, that for each triangle specifies three local vertices to use;
|
|
|
|
+ * - vertices, a 32-bit vertex indirection buffer, that for each local vertex specifies which mesh vertex to fetch vertex attributes from.
|
|
|
|
+ *
|
|
|
|
+ * For efficiency, meshlet triangles and vertices are packed into two large arrays; this structure contains offsets and counts to access the data.
|
|
|
|
+ */
|
|
struct meshopt_Meshlet
|
|
struct meshopt_Meshlet
|
|
{
|
|
{
|
|
/* offsets within meshlet_vertices and meshlet_triangles arrays with meshlet data */
|
|
/* offsets within meshlet_vertices and meshlet_triangles arrays with meshlet data */
|
|
@@ -479,6 +512,7 @@ struct meshopt_Meshlet
|
|
* Meshlet builder
|
|
* Meshlet builder
|
|
* Splits the mesh into a set of meshlets where each meshlet has a micro index buffer indexing into meshlet vertices that refer to the original vertex buffer
|
|
* Splits the mesh into a set of meshlets where each meshlet has a micro index buffer indexing into meshlet vertices that refer to the original vertex buffer
|
|
* The resulting data can be used to render meshes using NVidia programmable mesh shading pipeline, or in other cluster-based renderers.
|
|
* The resulting data can be used to render meshes using NVidia programmable mesh shading pipeline, or in other cluster-based renderers.
|
|
|
|
+ * When targeting mesh shading hardware, for maximum efficiency meshlets should be further optimized using meshopt_optimizeMeshlet.
|
|
* When using buildMeshlets, vertex positions need to be provided to minimize the size of the resulting clusters.
|
|
* When using buildMeshlets, vertex positions need to be provided to minimize the size of the resulting clusters.
|
|
* When using buildMeshletsScan, for maximum efficiency the index buffer being converted has to be optimized for vertex cache first.
|
|
* When using buildMeshletsScan, for maximum efficiency the index buffer being converted has to be optimized for vertex cache first.
|
|
*
|
|
*
|
|
@@ -486,13 +520,23 @@ struct meshopt_Meshlet
|
|
* meshlet_vertices must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_vertices
|
|
* meshlet_vertices must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_vertices
|
|
* meshlet_triangles must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_triangles * 3
|
|
* meshlet_triangles must contain enough space for all meshlets, worst case size is equal to max_meshlets * max_triangles * 3
|
|
* vertex_positions should have float3 position in the first 12 bytes of each vertex
|
|
* vertex_positions should have float3 position in the first 12 bytes of each vertex
|
|
- * max_vertices and max_triangles must not exceed implementation limits (max_vertices <= 255 - not 256!, max_triangles <= 512)
|
|
|
|
|
|
+ * max_vertices and max_triangles must not exceed implementation limits (max_vertices <= 255 - not 256!, max_triangles <= 512; max_triangles must be divisible by 4)
|
|
* 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
|
|
* 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
|
|
*/
|
|
*/
|
|
MESHOPTIMIZER_API size_t meshopt_buildMeshlets(struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t max_vertices, size_t max_triangles, float cone_weight);
|
|
MESHOPTIMIZER_API size_t meshopt_buildMeshlets(struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t max_vertices, size_t max_triangles, float cone_weight);
|
|
MESHOPTIMIZER_API size_t meshopt_buildMeshletsScan(struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, size_t vertex_count, size_t max_vertices, size_t max_triangles);
|
|
MESHOPTIMIZER_API size_t meshopt_buildMeshletsScan(struct meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const unsigned int* indices, size_t index_count, size_t vertex_count, size_t max_vertices, size_t max_triangles);
|
|
MESHOPTIMIZER_API size_t meshopt_buildMeshletsBound(size_t index_count, size_t max_vertices, size_t max_triangles);
|
|
MESHOPTIMIZER_API size_t meshopt_buildMeshletsBound(size_t index_count, size_t max_vertices, size_t max_triangles);
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Experimental: Meshlet optimizer
|
|
|
|
+ * Reorders meshlet vertices and triangles to maximize locality to improve rasterizer throughput
|
|
|
|
+ *
|
|
|
|
+ * meshlet_triangles and meshlet_vertices must refer to meshlet triangle and vertex index data; when buildMeshlets* is used, these
|
|
|
|
+ * need to be computed from meshlet's vertex_offset and triangle_offset
|
|
|
|
+ * triangle_count and vertex_count must not exceed implementation limits (vertex_count <= 255 - not 256!, triangle_count <= 512)
|
|
|
|
+ */
|
|
|
|
+MESHOPTIMIZER_EXPERIMENTAL void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, size_t triangle_count, size_t vertex_count);
|
|
|
|
+
|
|
struct meshopt_Bounds
|
|
struct meshopt_Bounds
|
|
{
|
|
{
|
|
/* bounding sphere, useful for frustum and occlusion culling */
|
|
/* bounding sphere, useful for frustum and occlusion culling */
|
|
@@ -529,7 +573,8 @@ struct meshopt_Bounds
|
|
* Real-Time Rendering 4th Edition, section 19.3).
|
|
* Real-Time Rendering 4th Edition, section 19.3).
|
|
*
|
|
*
|
|
* vertex_positions should have float3 position in the first 12 bytes of each vertex
|
|
* vertex_positions should have float3 position in the first 12 bytes of each vertex
|
|
- * index_count/3 should be less than or equal to 512 (the function assumes clusters of limited size)
|
|
|
|
|
|
+ * vertex_count should specify the number of vertices in the entire mesh, not cluster or meshlet
|
|
|
|
+ * index_count/3 and triangle_count must not exceed implementation limits (<= 512)
|
|
*/
|
|
*/
|
|
MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeClusterBounds(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
|
MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeClusterBounds(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
|
MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeMeshletBounds(const unsigned int* meshlet_vertices, const unsigned char* meshlet_triangles, size_t triangle_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
|
MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeMeshletBounds(const unsigned int* meshlet_vertices, const unsigned char* meshlet_triangles, size_t triangle_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
|
@@ -559,7 +604,7 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_spatialSortTriangles(unsigned int* desti
|
|
* Note that all algorithms only allocate memory for temporary use.
|
|
* Note that all algorithms only allocate memory for temporary use.
|
|
* allocate/deallocate are always called in a stack-like order - last pointer to be allocated is deallocated first.
|
|
* allocate/deallocate are always called in a stack-like order - last pointer to be allocated is deallocated first.
|
|
*/
|
|
*/
|
|
-MESHOPTIMIZER_API void meshopt_setAllocator(void* (MESHOPTIMIZER_ALLOC_CALLCONV *allocate)(size_t), void (MESHOPTIMIZER_ALLOC_CALLCONV *deallocate)(void*));
|
|
|
|
|
|
+MESHOPTIMIZER_API void meshopt_setAllocator(void* (MESHOPTIMIZER_ALLOC_CALLCONV* allocate)(size_t), void (MESHOPTIMIZER_ALLOC_CALLCONV* deallocate)(void*));
|
|
|
|
|
|
#ifdef __cplusplus
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
} /* extern "C" */
|
|
@@ -627,6 +672,8 @@ inline void meshopt_generateAdjacencyIndexBuffer(T* destination, const T* indice
|
|
template <typename T>
|
|
template <typename T>
|
|
inline void meshopt_generateTessellationIndexBuffer(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
|
inline void meshopt_generateTessellationIndexBuffer(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
|
template <typename T>
|
|
template <typename T>
|
|
|
|
+inline size_t meshopt_generateProvokingIndexBuffer(T* destination, unsigned int* reorder, const T* indices, size_t index_count, size_t vertex_count);
|
|
|
|
+template <typename T>
|
|
inline void meshopt_optimizeVertexCache(T* destination, const T* indices, size_t index_count, size_t vertex_count);
|
|
inline void meshopt_optimizeVertexCache(T* destination, const T* indices, size_t index_count, size_t vertex_count);
|
|
template <typename T>
|
|
template <typename T>
|
|
inline void meshopt_optimizeVertexCacheStrip(T* destination, const T* indices, size_t index_count, size_t vertex_count);
|
|
inline void meshopt_optimizeVertexCacheStrip(T* destination, const T* indices, size_t index_count, size_t vertex_count);
|
|
@@ -649,7 +696,7 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const
|
|
template <typename T>
|
|
template <typename T>
|
|
inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL);
|
|
inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL);
|
|
template <typename T>
|
|
template <typename T>
|
|
-inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL);
|
|
|
|
|
|
+inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options = 0, float* result_error = NULL);
|
|
template <typename T>
|
|
template <typename T>
|
|
inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = NULL);
|
|
inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float* result_error = NULL);
|
|
template <typename T>
|
|
template <typename T>
|
|
@@ -705,15 +752,15 @@ public:
|
|
template <typename T>
|
|
template <typename T>
|
|
struct StorageT
|
|
struct StorageT
|
|
{
|
|
{
|
|
- static void* (MESHOPTIMIZER_ALLOC_CALLCONV *allocate)(size_t);
|
|
|
|
- static void (MESHOPTIMIZER_ALLOC_CALLCONV *deallocate)(void*);
|
|
|
|
|
|
+ static void* (MESHOPTIMIZER_ALLOC_CALLCONV* allocate)(size_t);
|
|
|
|
+ static void (MESHOPTIMIZER_ALLOC_CALLCONV* deallocate)(void*);
|
|
};
|
|
};
|
|
|
|
|
|
typedef StorageT<void> Storage;
|
|
typedef StorageT<void> Storage;
|
|
|
|
|
|
meshopt_Allocator()
|
|
meshopt_Allocator()
|
|
- : blocks()
|
|
|
|
- , count(0)
|
|
|
|
|
|
+ : blocks()
|
|
|
|
+ , count(0)
|
|
{
|
|
{
|
|
}
|
|
}
|
|
|
|
|
|
@@ -723,7 +770,8 @@ public:
|
|
Storage::deallocate(blocks[i - 1]);
|
|
Storage::deallocate(blocks[i - 1]);
|
|
}
|
|
}
|
|
|
|
|
|
- template <typename T> T* allocate(size_t size)
|
|
|
|
|
|
+ template <typename T>
|
|
|
|
+ T* allocate(size_t size)
|
|
{
|
|
{
|
|
assert(count < sizeof(blocks) / sizeof(blocks[0]));
|
|
assert(count < sizeof(blocks) / sizeof(blocks[0]));
|
|
T* result = static_cast<T*>(Storage::allocate(size > size_t(-1) / sizeof(T) ? size_t(-1) : size * sizeof(T)));
|
|
T* result = static_cast<T*>(Storage::allocate(size > size_t(-1) / sizeof(T) ? size_t(-1) : size * sizeof(T)));
|
|
@@ -744,8 +792,10 @@ private:
|
|
};
|
|
};
|
|
|
|
|
|
// This makes sure that allocate/deallocate are lazily generated in translation units that need them and are deduplicated by the linker
|
|
// This makes sure that allocate/deallocate are lazily generated in translation units that need them and are deduplicated by the linker
|
|
-template <typename T> void* (MESHOPTIMIZER_ALLOC_CALLCONV *meshopt_Allocator::StorageT<T>::allocate)(size_t) = operator new;
|
|
|
|
-template <typename T> void (MESHOPTIMIZER_ALLOC_CALLCONV *meshopt_Allocator::StorageT<T>::deallocate)(void*) = operator delete;
|
|
|
|
|
|
+template <typename T>
|
|
|
|
+void* (MESHOPTIMIZER_ALLOC_CALLCONV* meshopt_Allocator::StorageT<T>::allocate)(size_t) = operator new;
|
|
|
|
+template <typename T>
|
|
|
|
+void (MESHOPTIMIZER_ALLOC_CALLCONV* meshopt_Allocator::StorageT<T>::deallocate)(void*) = operator delete;
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/* Inline implementation for C++ templated wrappers */
|
|
/* Inline implementation for C++ templated wrappers */
|
|
@@ -860,6 +910,19 @@ inline void meshopt_generateTessellationIndexBuffer(T* destination, const T* ind
|
|
meshopt_generateTessellationIndexBuffer(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
|
meshopt_generateTessellationIndexBuffer(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+template <typename T>
|
|
|
|
+inline size_t meshopt_generateProvokingIndexBuffer(T* destination, unsigned int* reorder, const T* indices, size_t index_count, size_t vertex_count)
|
|
|
|
+{
|
|
|
|
+ meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
|
|
|
+ meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
|
|
|
+
|
|
|
|
+ size_t bound = vertex_count + (index_count / 3);
|
|
|
|
+ assert(size_t(T(bound - 1)) == bound - 1); // bound - 1 must fit in T
|
|
|
|
+ (void)bound;
|
|
|
|
+
|
|
|
|
+ return meshopt_generateProvokingIndexBuffer(out.data, reorder, in.data, index_count, vertex_count);
|
|
|
|
+}
|
|
|
|
+
|
|
template <typename T>
|
|
template <typename T>
|
|
inline void meshopt_optimizeVertexCache(T* destination, const T* indices, size_t index_count, size_t vertex_count)
|
|
inline void meshopt_optimizeVertexCache(T* destination, const T* indices, size_t index_count, size_t vertex_count)
|
|
{
|
|
{
|
|
@@ -956,12 +1019,12 @@ inline size_t meshopt_simplify(T* destination, const T* indices, size_t index_co
|
|
}
|
|
}
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
-inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t target_index_count, float target_error, unsigned int options, float* result_error)
|
|
|
|
|
|
+inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, const unsigned char* vertex_lock, size_t target_index_count, float target_error, unsigned int options, float* result_error)
|
|
{
|
|
{
|
|
- meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
|
|
|
- meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
|
|
|
|
|
+ meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
|
|
|
+ meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
|
|
|
|
|
- return meshopt_simplifyWithAttributes(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, attribute_count, target_index_count, target_error, options, result_error);
|
|
|
|
|
|
+ return meshopt_simplifyWithAttributes(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, vertex_attributes, vertex_attributes_stride, attribute_weights, attribute_count, vertex_lock, target_index_count, target_error, options, result_error);
|
|
}
|
|
}
|
|
|
|
|
|
template <typename T>
|
|
template <typename T>
|
|
@@ -1050,7 +1113,7 @@ inline void meshopt_spatialSortTriangles(T* destination, const T* indices, size_
|
|
#endif
|
|
#endif
|
|
|
|
|
|
/**
|
|
/**
|
|
- * Copyright (c) 2016-2023 Arseny Kapoulkine
|
|
|
|
|
|
+ * Copyright (c) 2016-2024 Arseny Kapoulkine
|
|
*
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* obtaining a copy of this software and associated documentation
|