Merge pull request #55128 from akien-mga/meshoptimizer-f4c356d79
This commit is contained in:
commit
2b287509eb
2
thirdparty/README.md
vendored
2
thirdparty/README.md
vendored
@ -333,7 +333,7 @@ File extracted from upstream release tarball:
|
|||||||
## meshoptimizer
|
## meshoptimizer
|
||||||
|
|
||||||
- Upstream: https://github.com/zeux/meshoptimizer
|
- Upstream: https://github.com/zeux/meshoptimizer
|
||||||
- Version: git (f5d83e879c48f8664783a69b4f50711d27549b66, 2021)
|
- Version: git (f4c356d79fadb99cbf432f7e199d823581b0e19e, 2021)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from upstream repository:
|
Files extracted from upstream repository:
|
||||||
|
3
thirdparty/meshoptimizer/clusterizer.cpp
vendored
3
thirdparty/meshoptimizer/clusterizer.cpp
vendored
@ -368,8 +368,7 @@ static size_t kdtreeBuild(size_t offset, KDNode* nodes, size_t node_count, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// split axis is one where the variance is largest
|
// split axis is one where the variance is largest
|
||||||
unsigned int axis = vars[0] >= vars[1] && vars[0] >= vars[2] ? 0 : vars[1] >= vars[2] ? 1
|
unsigned int axis = vars[0] >= vars[1] && vars[0] >= vars[2] ? 0 : vars[1] >= vars[2] ? 1 : 2;
|
||||||
: 2;
|
|
||||||
|
|
||||||
float split = mean[axis];
|
float split = mean[axis];
|
||||||
size_t middle = kdtreePartition(indices, count, points, stride, axis, split);
|
size_t middle = kdtreePartition(indices, count, points, stride, axis, split);
|
||||||
|
29
thirdparty/meshoptimizer/meshoptimizer.h
vendored
29
thirdparty/meshoptimizer/meshoptimizer.h
vendored
@ -278,9 +278,30 @@ 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 vertex_count, size_t vertex_size);
|
MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterOct(void* buffer, size_t count, size_t stride);
|
||||||
MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterQuat(void* buffer, size_t vertex_count, size_t vertex_size);
|
MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterQuat(void* buffer, size_t count, size_t stride);
|
||||||
MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t vertex_count, size_t vertex_size);
|
MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t count, size_t stride);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertex buffer filter encoders
|
||||||
|
* These functions can be used to encode data in a format that meshopt_decodeFilter can decode
|
||||||
|
*
|
||||||
|
* meshopt_encodeFilterOct encodes unit vectors with K-bit (K <= 16) signed X/Y as an output.
|
||||||
|
* Each component is stored as an 8-bit or 16-bit normalized integer; stride must be equal to 4 or 8. W is preserved as is.
|
||||||
|
* Input data must contain 4 floats for every vector (count*4 total).
|
||||||
|
*
|
||||||
|
* meshopt_encodeFilterQuat encodes unit quaternions with K-bit (4 <= K <= 16) component encoding.
|
||||||
|
* Each component is stored as an 16-bit integer; stride must be equal to 8.
|
||||||
|
* Input data must contain 4 floats for every quaternion (count*4 total).
|
||||||
|
*
|
||||||
|
* meshopt_encodeFilterExp encodes arbitrary (finite) floating-point data with 8-bit exponent and K-bit integer mantissa (1 <= K <= 24).
|
||||||
|
* Mantissa is shared between all components of a given vector as defined by stride; stride must be divisible by 4.
|
||||||
|
* Input data must contain stride/4 floats for every vector (count*stride/4 total).
|
||||||
|
* When individual (scalar) encoding is desired, simply pass stride=4 and adjust count accordingly.
|
||||||
|
*/
|
||||||
|
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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Experimental: Mesh simplifier
|
* Experimental: Mesh simplifier
|
||||||
@ -305,7 +326,7 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifyWithAttributes(unsigned int* d
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Experimental: Mesh simplifier (sloppy)
|
* Experimental: Mesh simplifier (sloppy)
|
||||||
* Reduces the number of triangles in the mesh, sacrificing mesh apperance for simplification performance
|
* Reduces the number of triangles in the mesh, sacrificing mesh appearance for simplification performance
|
||||||
* The algorithm doesn't preserve mesh topology but can stop short of the target goal based on target error.
|
* The algorithm doesn't preserve mesh topology but can stop short of the target goal based on target error.
|
||||||
* 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.
|
||||||
|
4
thirdparty/meshoptimizer/vertexcodec.cpp
vendored
4
thirdparty/meshoptimizer/vertexcodec.cpp
vendored
@ -77,6 +77,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SIMD_WASM
|
#ifdef SIMD_WASM
|
||||||
|
#undef __DEPRECATED
|
||||||
|
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||||
#include <wasm_simd128.h>
|
#include <wasm_simd128.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1028,7 +1030,7 @@ static unsigned int getCpuFeatures()
|
|||||||
return cpuinfo[2];
|
return cpuinfo[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int cpuid = getCpuFeatures();
|
static unsigned int cpuid = getCpuFeatures();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace meshopt
|
} // namespace meshopt
|
||||||
|
156
thirdparty/meshoptimizer/vertexfilter.cpp
vendored
156
thirdparty/meshoptimizer/vertexfilter.cpp
vendored
@ -52,6 +52,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SIMD_WASM
|
#ifdef SIMD_WASM
|
||||||
|
#undef __DEPRECATED
|
||||||
#include <wasm_simd128.h>
|
#include <wasm_simd128.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -160,7 +161,8 @@ static void decodeFilterExp(unsigned int* data, size_t count)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
|
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
|
||||||
template <typename T> static void dispatchSimd(void (*process)(T*, size_t), T* data, size_t count, size_t stride)
|
template <typename T>
|
||||||
|
static void dispatchSimd(void (*process)(T*, size_t), T* data, size_t count, size_t stride)
|
||||||
{
|
{
|
||||||
assert(stride <= 4);
|
assert(stride <= 4);
|
||||||
|
|
||||||
@ -791,52 +793,170 @@ static void decodeFilterExpSimd(unsigned int* data, size_t count)
|
|||||||
|
|
||||||
} // namespace meshopt
|
} // namespace meshopt
|
||||||
|
|
||||||
void meshopt_decodeFilterOct(void* buffer, size_t vertex_count, size_t vertex_size)
|
void meshopt_decodeFilterOct(void* buffer, size_t count, size_t stride)
|
||||||
{
|
{
|
||||||
using namespace meshopt;
|
using namespace meshopt;
|
||||||
|
|
||||||
assert(vertex_size == 4 || vertex_size == 8);
|
assert(stride == 4 || stride == 8);
|
||||||
|
|
||||||
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
|
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
|
||||||
if (vertex_size == 4)
|
if (stride == 4)
|
||||||
dispatchSimd(decodeFilterOctSimd, static_cast<signed char*>(buffer), vertex_count, 4);
|
dispatchSimd(decodeFilterOctSimd, static_cast<signed char*>(buffer), count, 4);
|
||||||
else
|
else
|
||||||
dispatchSimd(decodeFilterOctSimd, static_cast<short*>(buffer), vertex_count, 4);
|
dispatchSimd(decodeFilterOctSimd, static_cast<short*>(buffer), count, 4);
|
||||||
#else
|
#else
|
||||||
if (vertex_size == 4)
|
if (stride == 4)
|
||||||
decodeFilterOct(static_cast<signed char*>(buffer), vertex_count);
|
decodeFilterOct(static_cast<signed char*>(buffer), count);
|
||||||
else
|
else
|
||||||
decodeFilterOct(static_cast<short*>(buffer), vertex_count);
|
decodeFilterOct(static_cast<short*>(buffer), count);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void meshopt_decodeFilterQuat(void* buffer, size_t vertex_count, size_t vertex_size)
|
void meshopt_decodeFilterQuat(void* buffer, size_t count, size_t stride)
|
||||||
{
|
{
|
||||||
using namespace meshopt;
|
using namespace meshopt;
|
||||||
|
|
||||||
assert(vertex_size == 8);
|
assert(stride == 8);
|
||||||
(void)vertex_size;
|
(void)stride;
|
||||||
|
|
||||||
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
|
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
|
||||||
dispatchSimd(decodeFilterQuatSimd, static_cast<short*>(buffer), vertex_count, 4);
|
dispatchSimd(decodeFilterQuatSimd, static_cast<short*>(buffer), count, 4);
|
||||||
#else
|
#else
|
||||||
decodeFilterQuat(static_cast<short*>(buffer), vertex_count);
|
decodeFilterQuat(static_cast<short*>(buffer), count);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void meshopt_decodeFilterExp(void* buffer, size_t vertex_count, size_t vertex_size)
|
void meshopt_decodeFilterExp(void* buffer, size_t count, size_t stride)
|
||||||
{
|
{
|
||||||
using namespace meshopt;
|
using namespace meshopt;
|
||||||
|
|
||||||
assert(vertex_size % 4 == 0);
|
assert(stride > 0 && stride % 4 == 0);
|
||||||
|
|
||||||
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
|
#if defined(SIMD_SSE) || defined(SIMD_NEON) || defined(SIMD_WASM)
|
||||||
dispatchSimd(decodeFilterExpSimd, static_cast<unsigned int*>(buffer), vertex_count * (vertex_size / 4), 1);
|
dispatchSimd(decodeFilterExpSimd, static_cast<unsigned int*>(buffer), count * (stride / 4), 1);
|
||||||
#else
|
#else
|
||||||
decodeFilterExp(static_cast<unsigned int*>(buffer), vertex_count * (vertex_size / 4));
|
decodeFilterExp(static_cast<unsigned int*>(buffer), count * (stride / 4));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void meshopt_encodeFilterOct(void* destination, size_t count, size_t stride, int bits, const float* data)
|
||||||
|
{
|
||||||
|
assert(stride == 4 || stride == 8);
|
||||||
|
assert(bits >= 1 && bits <= 16);
|
||||||
|
|
||||||
|
signed char* d8 = static_cast<signed char*>(destination);
|
||||||
|
short* d16 = static_cast<short*>(destination);
|
||||||
|
|
||||||
|
int bytebits = int(stride * 2);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
const float* n = &data[i * 4];
|
||||||
|
|
||||||
|
// octahedral encoding of a unit vector
|
||||||
|
float nx = n[0], ny = n[1], nz = n[2], nw = n[3];
|
||||||
|
float nl = fabsf(nx) + fabsf(ny) + fabsf(nz);
|
||||||
|
float ns = nl == 0.f ? 0.f : 1.f / nl;
|
||||||
|
|
||||||
|
nx *= ns;
|
||||||
|
ny *= ns;
|
||||||
|
|
||||||
|
float u = (nz >= 0.f) ? nx : (1 - fabsf(ny)) * (nx >= 0.f ? 1.f : -1.f);
|
||||||
|
float v = (nz >= 0.f) ? ny : (1 - fabsf(nx)) * (ny >= 0.f ? 1.f : -1.f);
|
||||||
|
|
||||||
|
int fu = meshopt_quantizeSnorm(u, bits);
|
||||||
|
int fv = meshopt_quantizeSnorm(v, bits);
|
||||||
|
int fo = meshopt_quantizeSnorm(1.f, bits);
|
||||||
|
int fw = meshopt_quantizeSnorm(nw, bytebits);
|
||||||
|
|
||||||
|
if (stride == 4)
|
||||||
|
{
|
||||||
|
d8[i * 4 + 0] = (signed char)(fu);
|
||||||
|
d8[i * 4 + 1] = (signed char)(fv);
|
||||||
|
d8[i * 4 + 2] = (signed char)(fo);
|
||||||
|
d8[i * 4 + 3] = (signed char)(fw);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d16[i * 4 + 0] = short(fu);
|
||||||
|
d16[i * 4 + 1] = short(fv);
|
||||||
|
d16[i * 4 + 2] = short(fo);
|
||||||
|
d16[i * 4 + 3] = short(fw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void meshopt_encodeFilterQuat(void* destination_, size_t count, size_t stride, int bits, const float* data)
|
||||||
|
{
|
||||||
|
assert(stride == 8);
|
||||||
|
assert(bits >= 4 && bits <= 16);
|
||||||
|
(void)stride;
|
||||||
|
|
||||||
|
short* destination = static_cast<short*>(destination_);
|
||||||
|
|
||||||
|
const float scaler = sqrtf(2.f);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
const float* q = &data[i * 4];
|
||||||
|
short* d = &destination[i * 4];
|
||||||
|
|
||||||
|
// establish maximum quaternion component
|
||||||
|
int qc = 0;
|
||||||
|
qc = fabsf(q[1]) > fabsf(q[qc]) ? 1 : qc;
|
||||||
|
qc = fabsf(q[2]) > fabsf(q[qc]) ? 2 : qc;
|
||||||
|
qc = fabsf(q[3]) > fabsf(q[qc]) ? 3 : qc;
|
||||||
|
|
||||||
|
// we use double-cover properties to discard the sign
|
||||||
|
float sign = q[qc] < 0.f ? -1.f : 1.f;
|
||||||
|
|
||||||
|
// note: we always encode a cyclical swizzle to be able to recover the order via rotation
|
||||||
|
d[0] = short(meshopt_quantizeSnorm(q[(qc + 1) & 3] * scaler * sign, bits));
|
||||||
|
d[1] = short(meshopt_quantizeSnorm(q[(qc + 2) & 3] * scaler * sign, bits));
|
||||||
|
d[2] = short(meshopt_quantizeSnorm(q[(qc + 3) & 3] * scaler * sign, bits));
|
||||||
|
d[3] = short((meshopt_quantizeSnorm(1.f, bits) & ~3) | qc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void meshopt_encodeFilterExp(void* destination_, size_t count, size_t stride, int bits, const float* data)
|
||||||
|
{
|
||||||
|
assert(stride > 0 && stride % 4 == 0);
|
||||||
|
assert(bits >= 1 && bits <= 24);
|
||||||
|
|
||||||
|
unsigned int* destination = static_cast<unsigned int*>(destination_);
|
||||||
|
size_t stride_float = stride / sizeof(float);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
const float* v = &data[i * stride_float];
|
||||||
|
unsigned int* d = &destination[i * stride_float];
|
||||||
|
|
||||||
|
// use maximum exponent to encode values; this guarantess that mantissa is [-1, 1]
|
||||||
|
int exp = -100;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < stride_float; ++j)
|
||||||
|
{
|
||||||
|
int e;
|
||||||
|
frexp(v[j], &e);
|
||||||
|
|
||||||
|
exp = (exp < e) ? e : exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note that we additionally scale the mantissa to make it a K-bit signed integer (K-1 bits for magnitude)
|
||||||
|
exp -= (bits - 1);
|
||||||
|
|
||||||
|
// compute renormalized rounded mantissa for each component
|
||||||
|
int mmask = (1 << 24) - 1;
|
||||||
|
|
||||||
|
for (size_t j = 0; j < stride_float; ++j)
|
||||||
|
{
|
||||||
|
int m = int(ldexp(v[j], -exp) + (v[j] >= 0 ? 0.5f : -0.5f));
|
||||||
|
|
||||||
|
d[j] = (m & mmask) | (unsigned(exp) << 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#undef SIMD_SSE
|
#undef SIMD_SSE
|
||||||
#undef SIMD_NEON
|
#undef SIMD_NEON
|
||||||
#undef SIMD_WASM
|
#undef SIMD_WASM
|
||||||
|
Loading…
Reference in New Issue
Block a user