Updated meshoptimizer.
This commit is contained in:
parent
fe578a3323
commit
0d6d961680
2
3rdparty/meshoptimizer/src/indexcodec.cpp
vendored
2
3rdparty/meshoptimizer/src/indexcodec.cpp
vendored
@ -13,7 +13,7 @@ namespace meshopt
|
|||||||
const unsigned char kIndexHeader = 0xe0;
|
const unsigned char kIndexHeader = 0xe0;
|
||||||
const unsigned char kSequenceHeader = 0xd0;
|
const unsigned char kSequenceHeader = 0xd0;
|
||||||
|
|
||||||
static int gEncodeIndexVersion = 0;
|
static int gEncodeIndexVersion = 1;
|
||||||
|
|
||||||
typedef unsigned int VertexFifo[16];
|
typedef unsigned int VertexFifo[16];
|
||||||
typedef unsigned int EdgeFifo[16][2];
|
typedef unsigned int EdgeFifo[16][2];
|
||||||
|
@ -157,7 +157,7 @@ static T* hashLookup(T* table, size_t buckets, const Hash& hash, const T& key, c
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(false && "Hash table is full"); // unreachable
|
assert(false && "Hash table is full"); // unreachable
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void buildPositionRemap(unsigned int* remap, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, meshopt_Allocator& allocator)
|
static void buildPositionRemap(unsigned int* remap, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, meshopt_Allocator& allocator)
|
||||||
|
109
3rdparty/meshoptimizer/src/meshoptimizer.h
vendored
109
3rdparty/meshoptimizer/src/meshoptimizer.h
vendored
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* meshoptimizer - version 0.19
|
* meshoptimizer - version 0.20
|
||||||
*
|
*
|
||||||
* Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
* Copyright (C) 2016-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||||
* Report bugs and download new versions at https://github.com/zeux/meshoptimizer
|
* Report bugs and download new versions at https://github.com/zeux/meshoptimizer
|
||||||
@ -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 190 /* 0.19 */
|
#define MESHOPTIMIZER_VERSION 200 /* 0.20 */
|
||||||
|
|
||||||
/* If no API is defined, assume default */
|
/* If no API is defined, assume default */
|
||||||
#ifndef MESHOPTIMIZER_API
|
#ifndef MESHOPTIMIZER_API
|
||||||
@ -67,6 +67,7 @@ MESHOPTIMIZER_API size_t meshopt_generateVertexRemap(unsigned int* destination,
|
|||||||
*
|
*
|
||||||
* destination must contain enough space for the resulting remap table (vertex_count elements)
|
* destination must contain enough space for the resulting remap table (vertex_count elements)
|
||||||
* indices can be NULL if the input is unindexed
|
* indices can be NULL if the input is unindexed
|
||||||
|
* stream_count must be <= 16
|
||||||
*/
|
*/
|
||||||
MESHOPTIMIZER_API size_t meshopt_generateVertexRemapMulti(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, const struct meshopt_Stream* streams, size_t stream_count);
|
MESHOPTIMIZER_API size_t meshopt_generateVertexRemapMulti(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, const struct meshopt_Stream* streams, size_t stream_count);
|
||||||
|
|
||||||
@ -103,6 +104,7 @@ MESHOPTIMIZER_API void meshopt_generateShadowIndexBuffer(unsigned int* destinati
|
|||||||
* Note that binary equivalence considers all size bytes in each stream, including padding which should be zero-initialized.
|
* Note that binary equivalence considers all size bytes in each stream, including padding which should be zero-initialized.
|
||||||
*
|
*
|
||||||
* destination must contain enough space for the resulting index buffer (index_count elements)
|
* destination must contain enough space for the resulting index buffer (index_count elements)
|
||||||
|
* stream_count must be <= 16
|
||||||
*/
|
*/
|
||||||
MESHOPTIMIZER_API void meshopt_generateShadowIndexBufferMulti(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, const struct meshopt_Stream* streams, size_t stream_count);
|
MESHOPTIMIZER_API void meshopt_generateShadowIndexBufferMulti(unsigned int* destination, const unsigned int* indices, size_t index_count, size_t vertex_count, const struct meshopt_Stream* streams, size_t stream_count);
|
||||||
|
|
||||||
@ -354,6 +356,7 @@ MESHOPTIMIZER_API size_t meshopt_simplify(unsigned int* destination, const unsig
|
|||||||
*
|
*
|
||||||
* 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_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
|
* TODO target_error/result_error currently use combined distance+attribute error; this may change in the future
|
||||||
*/
|
*/
|
||||||
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, size_t target_index_count, float target_error, unsigned int options, float* result_error);
|
||||||
@ -382,8 +385,9 @@ 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
|
||||||
*/
|
*/
|
||||||
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, 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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the error scaling factor used by the simplifier to convert between absolute and relative extents
|
* Returns the error scaling factor used by the simplifier to convert between absolute and relative extents
|
||||||
@ -531,13 +535,14 @@ MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeClusterBounds(const unsig
|
|||||||
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Experimental: Spatial sorter
|
* Spatial sorter
|
||||||
* Generates a remap table that can be used to reorder points for spatial locality.
|
* Generates a remap table that can be used to reorder points for spatial locality.
|
||||||
* Resulting remap table maps old vertices to new vertices and can be used in meshopt_remapVertexBuffer.
|
* Resulting remap table maps old vertices to new vertices and can be used in meshopt_remapVertexBuffer.
|
||||||
*
|
*
|
||||||
* destination must contain enough space for the resulting remap table (vertex_count elements)
|
* destination must contain enough space for the resulting remap table (vertex_count elements)
|
||||||
|
* vertex_positions should have float3 position in the first 12 bytes of each vertex
|
||||||
*/
|
*/
|
||||||
MESHOPTIMIZER_EXPERIMENTAL void meshopt_spatialSortRemap(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
MESHOPTIMIZER_API void meshopt_spatialSortRemap(unsigned int* destination, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Experimental: Spatial sorter
|
* Experimental: Spatial sorter
|
||||||
@ -642,11 +647,11 @@ inline size_t meshopt_encodeIndexSequence(unsigned char* buffer, size_t buffer_s
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const unsigned char* buffer, size_t buffer_size);
|
inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const unsigned char* buffer, size_t buffer_size);
|
||||||
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 = 0);
|
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 = 0);
|
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);
|
||||||
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 = 0);
|
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>
|
||||||
inline size_t meshopt_stripify(T* destination, const T* indices, size_t index_count, size_t vertex_count, T restart_index);
|
inline size_t meshopt_stripify(T* destination, const T* indices, size_t index_count, size_t vertex_count, T restart_index);
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -757,7 +762,7 @@ struct meshopt_IndexAdapter<T, false>
|
|||||||
|
|
||||||
meshopt_IndexAdapter(T* result_, const T* input, size_t count_)
|
meshopt_IndexAdapter(T* result_, const T* input, size_t count_)
|
||||||
: result(result_)
|
: result(result_)
|
||||||
, data(0)
|
, data(NULL)
|
||||||
, count(count_)
|
, count(count_)
|
||||||
{
|
{
|
||||||
size_t size = count > size_t(-1) / sizeof(unsigned int) ? size_t(-1) : count * sizeof(unsigned int);
|
size_t size = count > size_t(-1) / sizeof(unsigned int) ? size_t(-1) : count * sizeof(unsigned int);
|
||||||
@ -797,33 +802,33 @@ struct meshopt_IndexAdapter<T, true>
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_generateVertexRemap(unsigned int* destination, const T* indices, size_t index_count, const void* vertices, size_t vertex_count, size_t vertex_size)
|
inline size_t meshopt_generateVertexRemap(unsigned int* destination, const T* indices, size_t index_count, const void* vertices, size_t vertex_count, size_t vertex_size)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, indices ? index_count : 0);
|
meshopt_IndexAdapter<T> in(NULL, indices, indices ? index_count : 0);
|
||||||
|
|
||||||
return meshopt_generateVertexRemap(destination, indices ? in.data : 0, index_count, vertices, vertex_count, vertex_size);
|
return meshopt_generateVertexRemap(destination, indices ? in.data : NULL, index_count, vertices, vertex_count, vertex_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_generateVertexRemapMulti(unsigned int* destination, const T* indices, size_t index_count, size_t vertex_count, const meshopt_Stream* streams, size_t stream_count)
|
inline size_t meshopt_generateVertexRemapMulti(unsigned int* destination, const T* indices, size_t index_count, size_t vertex_count, const meshopt_Stream* streams, size_t stream_count)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, indices ? index_count : 0);
|
meshopt_IndexAdapter<T> in(NULL, indices, indices ? index_count : 0);
|
||||||
|
|
||||||
return meshopt_generateVertexRemapMulti(destination, indices ? in.data : 0, index_count, vertex_count, streams, stream_count);
|
return meshopt_generateVertexRemapMulti(destination, indices ? in.data : NULL, index_count, vertex_count, streams, stream_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void meshopt_remapIndexBuffer(T* destination, const T* indices, size_t index_count, const unsigned int* remap)
|
inline void meshopt_remapIndexBuffer(T* destination, const T* indices, size_t index_count, const unsigned int* remap)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, indices ? index_count : 0);
|
meshopt_IndexAdapter<T> in(NULL, indices, indices ? index_count : 0);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
||||||
|
|
||||||
meshopt_remapIndexBuffer(out.data, indices ? in.data : 0, index_count, remap);
|
meshopt_remapIndexBuffer(out.data, indices ? in.data : NULL, index_count, remap);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void meshopt_generateShadowIndexBuffer(T* destination, const T* indices, size_t index_count, const void* vertices, size_t vertex_count, size_t vertex_size, size_t vertex_stride)
|
inline void meshopt_generateShadowIndexBuffer(T* destination, const T* indices, size_t index_count, const void* vertices, size_t vertex_count, size_t vertex_size, size_t vertex_stride)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
meshopt_generateShadowIndexBuffer(out.data, in.data, index_count, vertices, vertex_count, vertex_size, vertex_stride);
|
meshopt_generateShadowIndexBuffer(out.data, in.data, index_count, vertices, vertex_count, vertex_size, vertex_stride);
|
||||||
}
|
}
|
||||||
@ -831,8 +836,8 @@ inline void meshopt_generateShadowIndexBuffer(T* destination, const T* indices,
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline void meshopt_generateShadowIndexBufferMulti(T* destination, const T* indices, size_t index_count, size_t vertex_count, const meshopt_Stream* streams, size_t stream_count)
|
inline void meshopt_generateShadowIndexBufferMulti(T* destination, const T* indices, size_t index_count, size_t vertex_count, const meshopt_Stream* streams, size_t stream_count)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
meshopt_generateShadowIndexBufferMulti(out.data, in.data, index_count, vertex_count, streams, stream_count);
|
meshopt_generateShadowIndexBufferMulti(out.data, in.data, index_count, vertex_count, streams, stream_count);
|
||||||
}
|
}
|
||||||
@ -840,8 +845,8 @@ inline void meshopt_generateShadowIndexBufferMulti(T* destination, const T* indi
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline void meshopt_generateAdjacencyIndexBuffer(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_generateAdjacencyIndexBuffer(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count * 2);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count * 2);
|
||||||
|
|
||||||
meshopt_generateAdjacencyIndexBuffer(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
meshopt_generateAdjacencyIndexBuffer(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
||||||
}
|
}
|
||||||
@ -849,8 +854,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)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count * 4);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count * 4);
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
@ -858,8 +863,8 @@ inline void meshopt_generateTessellationIndexBuffer(T* destination, const T* ind
|
|||||||
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)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
meshopt_optimizeVertexCache(out.data, in.data, index_count, vertex_count);
|
meshopt_optimizeVertexCache(out.data, in.data, index_count, vertex_count);
|
||||||
}
|
}
|
||||||
@ -867,8 +872,8 @@ inline void meshopt_optimizeVertexCache(T* destination, const T* indices, size_t
|
|||||||
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)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
meshopt_optimizeVertexCacheStrip(out.data, in.data, index_count, vertex_count);
|
meshopt_optimizeVertexCacheStrip(out.data, in.data, index_count, vertex_count);
|
||||||
}
|
}
|
||||||
@ -876,8 +881,8 @@ inline void meshopt_optimizeVertexCacheStrip(T* destination, const T* indices, s
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline void meshopt_optimizeVertexCacheFifo(T* destination, const T* indices, size_t index_count, size_t vertex_count, unsigned int cache_size)
|
inline void meshopt_optimizeVertexCacheFifo(T* destination, const T* indices, size_t index_count, size_t vertex_count, unsigned int cache_size)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
meshopt_optimizeVertexCacheFifo(out.data, in.data, index_count, vertex_count, cache_size);
|
meshopt_optimizeVertexCacheFifo(out.data, in.data, index_count, vertex_count, cache_size);
|
||||||
}
|
}
|
||||||
@ -885,8 +890,8 @@ inline void meshopt_optimizeVertexCacheFifo(T* destination, const T* indices, si
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline void meshopt_optimizeOverdraw(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, float threshold)
|
inline void meshopt_optimizeOverdraw(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride, float threshold)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
meshopt_optimizeOverdraw(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, threshold);
|
meshopt_optimizeOverdraw(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, threshold);
|
||||||
}
|
}
|
||||||
@ -894,7 +899,7 @@ inline void meshopt_optimizeOverdraw(T* destination, const T* indices, size_t in
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_optimizeVertexFetchRemap(unsigned int* destination, const T* indices, size_t index_count, size_t vertex_count)
|
inline size_t meshopt_optimizeVertexFetchRemap(unsigned int* destination, const T* indices, size_t index_count, size_t vertex_count)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_optimizeVertexFetchRemap(destination, in.data, index_count, vertex_count);
|
return meshopt_optimizeVertexFetchRemap(destination, in.data, index_count, vertex_count);
|
||||||
}
|
}
|
||||||
@ -910,7 +915,7 @@ inline size_t meshopt_optimizeVertexFetch(void* destination, T* indices, size_t
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, const T* indices, size_t index_count)
|
inline size_t meshopt_encodeIndexBuffer(unsigned char* buffer, size_t buffer_size, const T* indices, size_t index_count)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_encodeIndexBuffer(buffer, buffer_size, in.data, index_count);
|
return meshopt_encodeIndexBuffer(buffer, buffer_size, in.data, index_count);
|
||||||
}
|
}
|
||||||
@ -927,7 +932,7 @@ inline int meshopt_decodeIndexBuffer(T* destination, size_t index_count, const u
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_encodeIndexSequence(unsigned char* buffer, size_t buffer_size, const T* indices, size_t index_count)
|
inline size_t meshopt_encodeIndexSequence(unsigned char* buffer, size_t buffer_size, const T* indices, size_t index_count)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_encodeIndexSequence(buffer, buffer_size, in.data, index_count);
|
return meshopt_encodeIndexSequence(buffer, buffer_size, in.data, index_count);
|
||||||
}
|
}
|
||||||
@ -944,8 +949,8 @@ 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, float* result_error)
|
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, float* result_error)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, options, result_error);
|
return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, options, result_error);
|
||||||
}
|
}
|
||||||
@ -953,8 +958,8 @@ 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, size_t target_index_count, float target_error, unsigned int options, float* result_error)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, 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, target_index_count, target_error, options, result_error);
|
||||||
}
|
}
|
||||||
@ -962,8 +967,8 @@ inline size_t meshopt_simplifyWithAttributes(T* destination, const T* indices, s
|
|||||||
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)
|
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)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
return meshopt_simplifySloppy(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, result_error);
|
return meshopt_simplifySloppy(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, result_error);
|
||||||
}
|
}
|
||||||
@ -971,8 +976,8 @@ inline size_t meshopt_simplifySloppy(T* destination, const T* indices, size_t in
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_stripify(T* destination, const T* indices, size_t index_count, size_t vertex_count, T restart_index)
|
inline size_t meshopt_stripify(T* destination, const T* indices, size_t index_count, size_t vertex_count, T restart_index)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, (index_count / 3) * 5);
|
meshopt_IndexAdapter<T> out(destination, NULL, (index_count / 3) * 5);
|
||||||
|
|
||||||
return meshopt_stripify(out.data, in.data, index_count, vertex_count, unsigned(restart_index));
|
return meshopt_stripify(out.data, in.data, index_count, vertex_count, unsigned(restart_index));
|
||||||
}
|
}
|
||||||
@ -980,8 +985,8 @@ inline size_t meshopt_stripify(T* destination, const T* indices, size_t index_co
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_unstripify(T* destination, const T* indices, size_t index_count, T restart_index)
|
inline size_t meshopt_unstripify(T* destination, const T* indices, size_t index_count, T restart_index)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, (index_count - 2) * 3);
|
meshopt_IndexAdapter<T> out(destination, NULL, (index_count - 2) * 3);
|
||||||
|
|
||||||
return meshopt_unstripify(out.data, in.data, index_count, unsigned(restart_index));
|
return meshopt_unstripify(out.data, in.data, index_count, unsigned(restart_index));
|
||||||
}
|
}
|
||||||
@ -989,7 +994,7 @@ inline size_t meshopt_unstripify(T* destination, const T* indices, size_t index_
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline meshopt_VertexCacheStatistics meshopt_analyzeVertexCache(const T* indices, size_t index_count, size_t vertex_count, unsigned int cache_size, unsigned int warp_size, unsigned int buffer_size)
|
inline meshopt_VertexCacheStatistics meshopt_analyzeVertexCache(const T* indices, size_t index_count, size_t vertex_count, unsigned int cache_size, unsigned int warp_size, unsigned int buffer_size)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_analyzeVertexCache(in.data, index_count, vertex_count, cache_size, warp_size, buffer_size);
|
return meshopt_analyzeVertexCache(in.data, index_count, vertex_count, cache_size, warp_size, buffer_size);
|
||||||
}
|
}
|
||||||
@ -997,7 +1002,7 @@ inline meshopt_VertexCacheStatistics meshopt_analyzeVertexCache(const T* indices
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
|
inline meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_analyzeOverdraw(in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
return meshopt_analyzeOverdraw(in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
||||||
}
|
}
|
||||||
@ -1005,7 +1010,7 @@ inline meshopt_OverdrawStatistics meshopt_analyzeOverdraw(const T* indices, size
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const T* indices, size_t index_count, size_t vertex_count, size_t vertex_size)
|
inline meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const T* indices, size_t index_count, size_t vertex_count, size_t vertex_size)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_analyzeVertexFetch(in.data, index_count, vertex_count, vertex_size);
|
return meshopt_analyzeVertexFetch(in.data, index_count, vertex_count, vertex_size);
|
||||||
}
|
}
|
||||||
@ -1013,7 +1018,7 @@ inline meshopt_VertexFetchStatistics meshopt_analyzeVertexFetch(const T* indices
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const T* 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)
|
inline size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const T* 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)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_buildMeshlets(meshlets, meshlet_vertices, meshlet_triangles, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, max_vertices, max_triangles, cone_weight);
|
return meshopt_buildMeshlets(meshlets, meshlet_vertices, meshlet_triangles, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, max_vertices, max_triangles, cone_weight);
|
||||||
}
|
}
|
||||||
@ -1021,7 +1026,7 @@ inline size_t meshopt_buildMeshlets(meshopt_Meshlet* meshlets, unsigned int* mes
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline size_t meshopt_buildMeshletsScan(meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const T* indices, size_t index_count, size_t vertex_count, size_t max_vertices, size_t max_triangles)
|
inline size_t meshopt_buildMeshletsScan(meshopt_Meshlet* meshlets, unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, const T* indices, size_t index_count, size_t vertex_count, size_t max_vertices, size_t max_triangles)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_buildMeshletsScan(meshlets, meshlet_vertices, meshlet_triangles, in.data, index_count, vertex_count, max_vertices, max_triangles);
|
return meshopt_buildMeshletsScan(meshlets, meshlet_vertices, meshlet_triangles, in.data, index_count, vertex_count, max_vertices, max_triangles);
|
||||||
}
|
}
|
||||||
@ -1029,7 +1034,7 @@ inline size_t meshopt_buildMeshletsScan(meshopt_Meshlet* meshlets, unsigned int*
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline meshopt_Bounds meshopt_computeClusterBounds(const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
|
inline meshopt_Bounds meshopt_computeClusterBounds(const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
|
|
||||||
return meshopt_computeClusterBounds(in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
return meshopt_computeClusterBounds(in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
||||||
}
|
}
|
||||||
@ -1037,8 +1042,8 @@ inline meshopt_Bounds meshopt_computeClusterBounds(const T* indices, size_t inde
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
inline void meshopt_spatialSortTriangles(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_spatialSortTriangles(T* destination, const T* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride)
|
||||||
{
|
{
|
||||||
meshopt_IndexAdapter<T> in(0, indices, index_count);
|
meshopt_IndexAdapter<T> in(NULL, indices, index_count);
|
||||||
meshopt_IndexAdapter<T> out(destination, 0, index_count);
|
meshopt_IndexAdapter<T> out(destination, NULL, index_count);
|
||||||
|
|
||||||
meshopt_spatialSortTriangles(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
meshopt_spatialSortTriangles(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride);
|
||||||
}
|
}
|
||||||
|
118
3rdparty/meshoptimizer/src/simplifier.cpp
vendored
118
3rdparty/meshoptimizer/src/simplifier.cpp
vendored
@ -164,7 +164,7 @@ static T* hashLookup2(T* table, size_t buckets, const Hash& hash, const T& key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(false && "Hash table is full"); // unreachable
|
assert(false && "Hash table is full"); // unreachable
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, meshopt_Allocator& allocator)
|
static void buildPositionRemap(unsigned int* remap, unsigned int* wedge, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, meshopt_Allocator& allocator)
|
||||||
@ -445,6 +445,7 @@ static const size_t kMaxAttributes = 16;
|
|||||||
|
|
||||||
struct Quadric
|
struct Quadric
|
||||||
{
|
{
|
||||||
|
// a00*x^2 + a11*y^2 + a22*z^2 + 2*(a10*xy + a20*xz + a21*yz) + b0*x + b1*y + b2*z + c
|
||||||
float a00, a11, a22;
|
float a00, a11, a22;
|
||||||
float a10, a20, a21;
|
float a10, a20, a21;
|
||||||
float b0, b1, b2, c;
|
float b0, b1, b2, c;
|
||||||
@ -453,9 +454,17 @@ struct Quadric
|
|||||||
|
|
||||||
struct QuadricGrad
|
struct QuadricGrad
|
||||||
{
|
{
|
||||||
|
// gx*x + gy*y + gz*z + gw
|
||||||
float gx, gy, gz, gw;
|
float gx, gy, gz, gw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Reservoir
|
||||||
|
{
|
||||||
|
float x, y, z;
|
||||||
|
float r, g, b;
|
||||||
|
float w;
|
||||||
|
};
|
||||||
|
|
||||||
struct Collapse
|
struct Collapse
|
||||||
{
|
{
|
||||||
unsigned int v0;
|
unsigned int v0;
|
||||||
@ -596,22 +605,6 @@ static void quadricFromPlane(Quadric& Q, float a, float b, float c, float d, flo
|
|||||||
Q.w = w;
|
Q.w = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void quadricFromPoint(Quadric& Q, float x, float y, float z, float w)
|
|
||||||
{
|
|
||||||
// we need to encode (x - X) ^ 2 + (y - Y)^2 + (z - Z)^2 into the quadric
|
|
||||||
Q.a00 = w;
|
|
||||||
Q.a11 = w;
|
|
||||||
Q.a22 = w;
|
|
||||||
Q.a10 = 0.f;
|
|
||||||
Q.a20 = 0.f;
|
|
||||||
Q.a21 = 0.f;
|
|
||||||
Q.b0 = -2.f * x * w;
|
|
||||||
Q.b1 = -2.f * y * w;
|
|
||||||
Q.b2 = -2.f * z * w;
|
|
||||||
Q.c = (x * x + y * y + z * z) * w;
|
|
||||||
Q.w = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void quadricFromTriangle(Quadric& Q, const Vector3& p0, const Vector3& p1, const Vector3& p2, float weight)
|
static void quadricFromTriangle(Quadric& Q, const Vector3& p0, const Vector3& p1, const Vector3& p2, float weight)
|
||||||
{
|
{
|
||||||
Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z};
|
Vector3 p10 = {p1.x - p0.x, p1.y - p0.y, p1.z - p0.z};
|
||||||
@ -1330,17 +1323,41 @@ static void fillCellQuadrics(Quadric* cell_quadrics, const unsigned int* indices
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillCellQuadrics(Quadric* cell_quadrics, const Vector3* vertex_positions, size_t vertex_count, const unsigned int* vertex_cells)
|
static void fillCellReservoirs(Reservoir* cell_reservoirs, size_t cell_count, const Vector3* vertex_positions, const float* vertex_colors, size_t vertex_colors_stride, size_t vertex_count, const unsigned int* vertex_cells)
|
||||||
{
|
{
|
||||||
|
static const float dummy_color[] = { 0.f, 0.f, 0.f };
|
||||||
|
|
||||||
|
size_t vertex_colors_stride_float = vertex_colors_stride / sizeof(float);
|
||||||
|
|
||||||
for (size_t i = 0; i < vertex_count; ++i)
|
for (size_t i = 0; i < vertex_count; ++i)
|
||||||
{
|
{
|
||||||
unsigned int c = vertex_cells[i];
|
unsigned int cell = vertex_cells[i];
|
||||||
const Vector3& v = vertex_positions[i];
|
const Vector3& v = vertex_positions[i];
|
||||||
|
Reservoir& r = cell_reservoirs[cell];
|
||||||
|
|
||||||
Quadric Q;
|
const float* color = vertex_colors ? &vertex_colors[i * vertex_colors_stride_float] : dummy_color;
|
||||||
quadricFromPoint(Q, v.x, v.y, v.z, 1.f);
|
|
||||||
|
|
||||||
quadricAdd(cell_quadrics[c], Q);
|
r.x += v.x;
|
||||||
|
r.y += v.y;
|
||||||
|
r.z += v.z;
|
||||||
|
r.r += color[0];
|
||||||
|
r.g += color[1];
|
||||||
|
r.b += color[2];
|
||||||
|
r.w += 1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cell_count; ++i)
|
||||||
|
{
|
||||||
|
Reservoir& r = cell_reservoirs[i];
|
||||||
|
|
||||||
|
float iw = r.w == 0.f ? 0.f : 1.f / r.w;
|
||||||
|
|
||||||
|
r.x *= iw;
|
||||||
|
r.y *= iw;
|
||||||
|
r.z *= iw;
|
||||||
|
r.r *= iw;
|
||||||
|
r.g *= iw;
|
||||||
|
r.b *= iw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1361,6 +1378,34 @@ static void fillCellRemap(unsigned int* cell_remap, float* cell_errors, size_t c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fillCellRemap(unsigned int* cell_remap, float* cell_errors, size_t cell_count, const unsigned int* vertex_cells, const Reservoir* cell_reservoirs, const Vector3* vertex_positions, const float* vertex_colors, size_t vertex_colors_stride, float color_weight, size_t vertex_count)
|
||||||
|
{
|
||||||
|
static const float dummy_color[] = { 0.f, 0.f, 0.f };
|
||||||
|
|
||||||
|
size_t vertex_colors_stride_float = vertex_colors_stride / sizeof(float);
|
||||||
|
|
||||||
|
memset(cell_remap, -1, cell_count * sizeof(unsigned int));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < vertex_count; ++i)
|
||||||
|
{
|
||||||
|
unsigned int cell = vertex_cells[i];
|
||||||
|
const Vector3& v = vertex_positions[i];
|
||||||
|
const Reservoir& r = cell_reservoirs[cell];
|
||||||
|
|
||||||
|
const float* color = vertex_colors ? &vertex_colors[i * vertex_colors_stride_float] : dummy_color;
|
||||||
|
|
||||||
|
float pos_error = (v.x - r.x) * (v.x - r.x) + (v.y - r.y) * (v.y - r.y) + (v.z - r.z) * (v.z - r.z);
|
||||||
|
float col_error = (color[0] - r.r) * (color[0] - r.r) + (color[1] - r.g) * (color[1] - r.g) + (color[2] - r.b) * (color[2] - r.b);
|
||||||
|
float error = pos_error + color_weight * col_error;
|
||||||
|
|
||||||
|
if (cell_remap[cell] == ~0u || cell_errors[cell] > error)
|
||||||
|
{
|
||||||
|
cell_remap[cell] = unsigned(i);
|
||||||
|
cell_errors[cell] = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static size_t filterTriangles(unsigned int* destination, unsigned int* tritable, size_t tritable_size, const unsigned int* indices, size_t index_count, const unsigned int* vertex_cells, const unsigned int* cell_remap)
|
static size_t filterTriangles(unsigned int* destination, unsigned int* tritable, size_t tritable_size, const unsigned int* indices, size_t index_count, const unsigned int* vertex_cells, const unsigned int* cell_remap)
|
||||||
{
|
{
|
||||||
TriangleHasher hasher = {destination};
|
TriangleHasher hasher = {destination};
|
||||||
@ -1418,9 +1463,9 @@ static float interpolate(float y, float x0, float y0, float x1, float y1, float
|
|||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// Note: this is only exposed for debug visualization purposes; do *not* use these in debug builds
|
// Note: this is only exposed for debug visualization purposes; do *not* use these in debug builds
|
||||||
MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind = 0;
|
MESHOPTIMIZER_API unsigned char* meshopt_simplifyDebugKind = NULL;
|
||||||
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = 0;
|
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = NULL;
|
||||||
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0;
|
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, 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* out_result_error)
|
size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indices, size_t index_count, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, const float* vertex_attributes_data, 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* out_result_error)
|
||||||
@ -1729,12 +1774,15 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind
|
|||||||
return write;
|
return write;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions_data, size_t vertex_count, size_t vertex_positions_stride, size_t target_vertex_count)
|
size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_positions_data, 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)
|
||||||
{
|
{
|
||||||
using namespace meshopt;
|
using namespace meshopt;
|
||||||
|
|
||||||
assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
|
assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
|
||||||
assert(vertex_positions_stride % sizeof(float) == 0);
|
assert(vertex_positions_stride % sizeof(float) == 0);
|
||||||
|
assert(vertex_colors_stride == 0 || (vertex_colors_stride >= 12 && vertex_colors_stride <= 256));
|
||||||
|
assert(vertex_colors_stride % sizeof(float) == 0);
|
||||||
|
assert(vertex_colors == NULL || vertex_colors_stride != 0);
|
||||||
assert(target_vertex_count <= vertex_count);
|
assert(target_vertex_count <= vertex_count);
|
||||||
|
|
||||||
size_t target_cell_count = target_vertex_count;
|
size_t target_cell_count = target_vertex_count;
|
||||||
@ -1818,24 +1866,30 @@ size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_pos
|
|||||||
computeVertexIds(vertex_ids, vertex_positions, vertex_count, min_grid);
|
computeVertexIds(vertex_ids, vertex_positions, vertex_count, min_grid);
|
||||||
size_t cell_count = fillVertexCells(table, table_size, vertex_cells, vertex_ids, vertex_count);
|
size_t cell_count = fillVertexCells(table, table_size, vertex_cells, vertex_ids, vertex_count);
|
||||||
|
|
||||||
// build a quadric for each target cell
|
// accumulate points into a reservoir for each target cell
|
||||||
Quadric* cell_quadrics = allocator.allocate<Quadric>(cell_count);
|
Reservoir* cell_reservoirs = allocator.allocate<Reservoir>(cell_count);
|
||||||
memset(cell_quadrics, 0, cell_count * sizeof(Quadric));
|
memset(cell_reservoirs, 0, cell_count * sizeof(Reservoir));
|
||||||
|
|
||||||
fillCellQuadrics(cell_quadrics, vertex_positions, vertex_count, vertex_cells);
|
fillCellReservoirs(cell_reservoirs, cell_count, vertex_positions, vertex_colors, vertex_colors_stride, vertex_count, vertex_cells);
|
||||||
|
|
||||||
// for each target cell, find the vertex with the minimal error
|
// for each target cell, find the vertex with the minimal error
|
||||||
unsigned int* cell_remap = allocator.allocate<unsigned int>(cell_count);
|
unsigned int* cell_remap = allocator.allocate<unsigned int>(cell_count);
|
||||||
float* cell_errors = allocator.allocate<float>(cell_count);
|
float* cell_errors = allocator.allocate<float>(cell_count);
|
||||||
|
|
||||||
fillCellRemap(cell_remap, cell_errors, cell_count, vertex_cells, cell_quadrics, vertex_positions, vertex_count);
|
fillCellRemap(cell_remap, cell_errors, cell_count, vertex_cells, cell_reservoirs, vertex_positions, vertex_colors, vertex_colors_stride, color_weight * color_weight, vertex_count);
|
||||||
|
|
||||||
// copy results to the output
|
// copy results to the output
|
||||||
assert(cell_count <= target_vertex_count);
|
assert(cell_count <= target_vertex_count);
|
||||||
memcpy(destination, cell_remap, sizeof(unsigned int) * cell_count);
|
memcpy(destination, cell_remap, sizeof(unsigned int) * cell_count);
|
||||||
|
|
||||||
#if TRACE
|
#if TRACE
|
||||||
printf("result: %d cells\n", int(cell_count));
|
// compute error
|
||||||
|
float result_error = 0.f;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < cell_count; ++i)
|
||||||
|
result_error = result_error < cell_errors[i] ? cell_errors[i] : result_error;
|
||||||
|
|
||||||
|
printf("result: %d cells, %e error\n", int(cell_count), sqrtf(result_error));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return cell_count;
|
return cell_count;
|
||||||
|
20
3rdparty/meshoptimizer/src/vertexcodec.cpp
vendored
20
3rdparty/meshoptimizer/src/vertexcodec.cpp
vendored
@ -220,7 +220,7 @@ static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end,
|
|||||||
size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
|
size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
|
||||||
|
|
||||||
if (size_t(data_end - data) < header_size)
|
if (size_t(data_end - data) < header_size)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
data += header_size;
|
data += header_size;
|
||||||
|
|
||||||
@ -229,7 +229,7 @@ static unsigned char* encodeBytes(unsigned char* data, unsigned char* data_end,
|
|||||||
for (size_t i = 0; i < buffer_size; i += kByteGroupSize)
|
for (size_t i = 0; i < buffer_size; i += kByteGroupSize)
|
||||||
{
|
{
|
||||||
if (size_t(data_end - data) < kByteGroupDecodeLimit)
|
if (size_t(data_end - data) < kByteGroupDecodeLimit)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
int best_bits = 8;
|
int best_bits = 8;
|
||||||
size_t best_size = encodeBytesGroupMeasure(buffer + i, 8);
|
size_t best_size = encodeBytesGroupMeasure(buffer + i, 8);
|
||||||
@ -288,7 +288,7 @@ static unsigned char* encodeVertexBlock(unsigned char* data, unsigned char* data
|
|||||||
|
|
||||||
data = encodeBytes(data, data_end, buffer, (vertex_count + kByteGroupSize - 1) & ~(kByteGroupSize - 1));
|
data = encodeBytes(data, data_end, buffer, (vertex_count + kByteGroupSize - 1) & ~(kByteGroupSize - 1));
|
||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(last_vertex, &vertex_data[vertex_size * (vertex_count - 1)], vertex_size);
|
memcpy(last_vertex, &vertex_data[vertex_size * (vertex_count - 1)], vertex_size);
|
||||||
@ -356,14 +356,14 @@ static const unsigned char* decodeBytes(const unsigned char* data, const unsigne
|
|||||||
size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
|
size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
|
||||||
|
|
||||||
if (size_t(data_end - data) < header_size)
|
if (size_t(data_end - data) < header_size)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
data += header_size;
|
data += header_size;
|
||||||
|
|
||||||
for (size_t i = 0; i < buffer_size; i += kByteGroupSize)
|
for (size_t i = 0; i < buffer_size; i += kByteGroupSize)
|
||||||
{
|
{
|
||||||
if (size_t(data_end - data) < kByteGroupDecodeLimit)
|
if (size_t(data_end - data) < kByteGroupDecodeLimit)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
size_t header_offset = i / kByteGroupSize;
|
size_t header_offset = i / kByteGroupSize;
|
||||||
|
|
||||||
@ -388,7 +388,7 @@ static const unsigned char* decodeVertexBlock(const unsigned char* data, const u
|
|||||||
{
|
{
|
||||||
data = decodeBytes(data, data_end, buffer, vertex_count_aligned);
|
data = decodeBytes(data, data_end, buffer, vertex_count_aligned);
|
||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
size_t vertex_offset = k;
|
size_t vertex_offset = k;
|
||||||
|
|
||||||
@ -938,7 +938,7 @@ static const unsigned char* decodeBytesSimd(const unsigned char* data, const uns
|
|||||||
size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
|
size_t header_size = (buffer_size / kByteGroupSize + 3) / 4;
|
||||||
|
|
||||||
if (size_t(data_end - data) < header_size)
|
if (size_t(data_end - data) < header_size)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
data += header_size;
|
data += header_size;
|
||||||
|
|
||||||
@ -960,7 +960,7 @@ static const unsigned char* decodeBytesSimd(const unsigned char* data, const uns
|
|||||||
for (; i < buffer_size; i += kByteGroupSize)
|
for (; i < buffer_size; i += kByteGroupSize)
|
||||||
{
|
{
|
||||||
if (size_t(data_end - data) < kByteGroupDecodeLimit)
|
if (size_t(data_end - data) < kByteGroupDecodeLimit)
|
||||||
return 0;
|
return NULL;
|
||||||
|
|
||||||
size_t header_offset = i / kByteGroupSize;
|
size_t header_offset = i / kByteGroupSize;
|
||||||
|
|
||||||
@ -988,7 +988,7 @@ static const unsigned char* decodeVertexBlockSimd(const unsigned char* data, con
|
|||||||
{
|
{
|
||||||
data = decodeBytesSimd(data, data_end, buffer + j * vertex_count_aligned, vertex_count_aligned);
|
data = decodeBytesSimd(data, data_end, buffer + j * vertex_count_aligned, vertex_count_aligned);
|
||||||
if (!data)
|
if (!data)
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(SIMD_SSE) || defined(SIMD_AVX)
|
#if defined(SIMD_SSE) || defined(SIMD_AVX)
|
||||||
@ -1182,7 +1182,7 @@ int meshopt_decodeVertexBuffer(void* destination, size_t vertex_count, size_t ve
|
|||||||
assert(vertex_size > 0 && vertex_size <= 256);
|
assert(vertex_size > 0 && vertex_size <= 256);
|
||||||
assert(vertex_size % 4 == 0);
|
assert(vertex_size % 4 == 0);
|
||||||
|
|
||||||
const unsigned char* (*decode)(const unsigned char*, const unsigned char*, unsigned char*, size_t, size_t, unsigned char[256]) = 0;
|
const unsigned char* (*decode)(const unsigned char*, const unsigned char*, unsigned char*, size_t, size_t, unsigned char[256]) = NULL;
|
||||||
|
|
||||||
#if defined(SIMD_SSE) && defined(SIMD_FALLBACK)
|
#if defined(SIMD_SSE) && defined(SIMD_FALLBACK)
|
||||||
decode = (cpuid & (1 << 9)) ? decodeVertexBlockSimd : decodeVertexBlock;
|
decode = (cpuid & (1 << 9)) ? decodeVertexBlockSimd : decodeVertexBlock;
|
||||||
|
Loading…
Reference in New Issue
Block a user