Updated meshoptimizer.
This commit is contained in:
parent
0c5b986faf
commit
bae9021d05
15
3rdparty/meshoptimizer/src/meshoptimizer.h
vendored
15
3rdparty/meshoptimizer/src/meshoptimizer.h
vendored
@ -304,13 +304,22 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_decodeFilterExp(void* buffer, size_t cou
|
|||||||
* Input data must contain 4 floats for every quaternion (count*4 total).
|
* 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).
|
* 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.
|
* Exponent can be shared between all components of a given vector as defined by stride or all values of a given component; stride must be divisible by 4.
|
||||||
* Input data must contain stride/4 floats for every vector (count*stride/4 total).
|
* 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.
|
|
||||||
*/
|
*/
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterOct(void* destination, size_t count, size_t stride, int bits, const float* data);
|
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_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);
|
MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_t count, size_t stride, int bits, const float* data, enum meshopt_EncodeExpMode mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplification options
|
* Simplification options
|
||||||
|
96
3rdparty/meshoptimizer/src/vertexfilter.cpp
vendored
96
3rdparty/meshoptimizer/src/vertexfilter.cpp
vendored
@ -63,6 +63,10 @@
|
|||||||
#define wasmx_unziphi_v32x4(a, b) wasm_v32x4_shuffle(a, b, 1, 3, 5, 7)
|
#define wasmx_unziphi_v32x4(a, b) wasm_v32x4_shuffle(a, b, 1, 3, 5, 7)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __has_builtin
|
||||||
|
#define __has_builtin(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace meshopt
|
namespace meshopt
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -185,9 +189,7 @@ inline uint64_t rotateleft64(uint64_t v, int x)
|
|||||||
{
|
{
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
return _rotl64(v, x);
|
return _rotl64(v, x);
|
||||||
// Apple's Clang 8 is actually vanilla Clang 3.9, there we need to look for
|
#elif defined(__clang__) && __has_builtin(__builtin_rotateleft64)
|
||||||
// version 11 instead: https://en.wikipedia.org/wiki/Xcode#Toolchain_versions
|
|
||||||
#elif defined(__clang__) && ((!defined(__apple_build_version__) && __clang_major__ >= 8) || __clang_major__ >= 11)
|
|
||||||
return __builtin_rotateleft64(v, x);
|
return __builtin_rotateleft64(v, x);
|
||||||
#else
|
#else
|
||||||
return (v << (x & 63)) | (v >> ((64 - x) & 63));
|
return (v << (x & 63)) | (v >> ((64 - x) & 63));
|
||||||
@ -791,6 +793,33 @@ static void decodeFilterExpSimd(unsigned int* data, size_t count)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// optimized variant of frexp
|
||||||
|
inline int optlog2(float v)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
unsigned int ui;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
u.f = v;
|
||||||
|
// +1 accounts for implicit 1. in mantissa; denormalized numbers will end up clamped to min_exp by calling code
|
||||||
|
return u.ui == 0 ? 0 : int((u.ui >> 23) & 0xff) - 127 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// optimized variant of ldexp
|
||||||
|
inline float optexp2(int e)
|
||||||
|
{
|
||||||
|
union
|
||||||
|
{
|
||||||
|
float f;
|
||||||
|
unsigned int ui;
|
||||||
|
} u;
|
||||||
|
|
||||||
|
u.ui = unsigned(e + 127) << 23;
|
||||||
|
return u.f;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace meshopt
|
} // namespace meshopt
|
||||||
|
|
||||||
void meshopt_decodeFilterOct(void* buffer, size_t count, size_t stride)
|
void meshopt_decodeFilterOct(void* buffer, size_t count, size_t stride)
|
||||||
@ -918,29 +947,70 @@ void meshopt_encodeFilterQuat(void* destination_, size_t count, size_t stride, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void meshopt_encodeFilterExp(void* destination_, size_t count, size_t stride, int bits, const float* data)
|
void meshopt_encodeFilterExp(void* destination_, size_t count, size_t stride, int bits, const float* data, enum meshopt_EncodeExpMode mode)
|
||||||
{
|
{
|
||||||
assert(stride > 0 && stride % 4 == 0);
|
using namespace meshopt;
|
||||||
|
|
||||||
|
assert(stride > 0 && stride % 4 == 0 && stride <= 256);
|
||||||
assert(bits >= 1 && bits <= 24);
|
assert(bits >= 1 && bits <= 24);
|
||||||
|
|
||||||
unsigned int* destination = static_cast<unsigned int*>(destination_);
|
unsigned int* destination = static_cast<unsigned int*>(destination_);
|
||||||
size_t stride_float = stride / sizeof(float);
|
size_t stride_float = stride / sizeof(float);
|
||||||
|
|
||||||
|
int component_exp[64];
|
||||||
|
assert(stride_float <= sizeof(component_exp) / sizeof(int));
|
||||||
|
|
||||||
|
const int min_exp = -100;
|
||||||
|
|
||||||
|
if (mode == meshopt_EncodeExpSharedComponent)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < stride_float; ++j)
|
||||||
|
component_exp[j] = min_exp;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
const float* v = &data[i * stride_float];
|
||||||
|
|
||||||
|
// use maximum exponent to encode values; this guarantees that mantissa is [-1, 1]
|
||||||
|
for (size_t j = 0; j < stride_float; ++j)
|
||||||
|
{
|
||||||
|
int e = optlog2(v[j]);
|
||||||
|
|
||||||
|
component_exp[j] = (component_exp[j] < e) ? e : component_exp[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < count; ++i)
|
for (size_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
const float* v = &data[i * stride_float];
|
const float* v = &data[i * stride_float];
|
||||||
unsigned int* d = &destination[i * stride_float];
|
unsigned int* d = &destination[i * stride_float];
|
||||||
|
|
||||||
|
int vector_exp = min_exp;
|
||||||
|
|
||||||
|
if (mode == meshopt_EncodeExpSharedVector)
|
||||||
|
{
|
||||||
// use maximum exponent to encode values; this guarantees that mantissa is [-1, 1]
|
// use maximum exponent to encode values; this guarantees that mantissa is [-1, 1]
|
||||||
int exp = -100;
|
for (size_t j = 0; j < stride_float; ++j)
|
||||||
|
{
|
||||||
|
int e = optlog2(v[j]);
|
||||||
|
|
||||||
|
vector_exp = (vector_exp < e) ? e : vector_exp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (mode == meshopt_EncodeExpSeparate)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < stride_float; ++j)
|
||||||
|
{
|
||||||
|
int e = optlog2(v[j]);
|
||||||
|
|
||||||
|
component_exp[j] = (min_exp < e) ? e : min_exp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t j = 0; j < stride_float; ++j)
|
for (size_t j = 0; j < stride_float; ++j)
|
||||||
{
|
{
|
||||||
int e;
|
int exp = (mode == meshopt_EncodeExpSharedVector) ? vector_exp : component_exp[j];
|
||||||
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)
|
// note that we additionally scale the mantissa to make it a K-bit signed integer (K-1 bits for magnitude)
|
||||||
exp -= (bits - 1);
|
exp -= (bits - 1);
|
||||||
@ -948,9 +1018,7 @@ void meshopt_encodeFilterExp(void* destination_, size_t count, size_t stride, in
|
|||||||
// compute renormalized rounded mantissa for each component
|
// compute renormalized rounded mantissa for each component
|
||||||
int mmask = (1 << 24) - 1;
|
int mmask = (1 << 24) - 1;
|
||||||
|
|
||||||
for (size_t j = 0; j < stride_float; ++j)
|
int m = int(v[j] * optexp2(-exp) + (v[j] >= 0 ? 0.5f : -0.5f));
|
||||||
{
|
|
||||||
int m = int(ldexp(v[j], -exp) + (v[j] >= 0 ? 0.5f : -0.5f));
|
|
||||||
|
|
||||||
d[j] = (m & mmask) | (unsigned(exp) << 24);
|
d[j] = (m & mmask) | (unsigned(exp) << 24);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user