mirror of https://github.com/bkaradzic/bgfx
Updated meshoptimizer.
This commit is contained in:
parent
f9e9a56879
commit
05862b9695
|
@ -312,6 +312,15 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterOct(void* destination, size_
|
|||
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);
|
||||
|
||||
/**
|
||||
* Simplification options
|
||||
*/
|
||||
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,
|
||||
};
|
||||
|
||||
/**
|
||||
* Experimental: Mesh simplifier
|
||||
* Reduces the number of triangles in the mesh, attempting to preserve mesh appearance as much as possible
|
||||
|
@ -324,9 +333,10 @@ MESHOPTIMIZER_EXPERIMENTAL void meshopt_encodeFilterExp(void* destination, size_
|
|||
* destination must contain enough space for the target index buffer, worst case is index_count elements (*not* target_index_count)!
|
||||
* vertex_positions should have float3 position in the first 12 bytes of each vertex - similar to glVertexPointer
|
||||
* target_error represents the error relative to mesh extents that can be tolerated, e.g. 0.01 = 1% deformation
|
||||
* options must be a bitmask composed of meshopt_SimplifyX options; 0 is a safe default
|
||||
* result_error can be NULL; when it's not NULL, it will contain the resulting (relative) error after simplification
|
||||
*/
|
||||
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* 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);
|
||||
MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplify(unsigned int* destination, const unsigned int* 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);
|
||||
|
||||
/**
|
||||
* Experimental: Mesh simplifier (sloppy)
|
||||
|
@ -605,7 +615,7 @@ inline size_t meshopt_encodeIndexSequence(unsigned char* buffer, size_t buffer_s
|
|||
template <typename T>
|
||||
inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const unsigned char* buffer, size_t buffer_size);
|
||||
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, 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 = 0);
|
||||
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);
|
||||
template <typename T>
|
||||
|
@ -940,12 +950,12 @@ inline int meshopt_decodeIndexSequence(T* destination, size_t index_count, const
|
|||
}
|
||||
|
||||
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, 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> out(destination, 0, index_count);
|
||||
|
||||
return meshopt_simplify(out.data, in.data, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, 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);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
|
@ -252,7 +252,7 @@ static bool hasEdge(const EdgeAdjacency& adjacency, unsigned int a, unsigned int
|
|||
return false;
|
||||
}
|
||||
|
||||
static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge)
|
||||
static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned int* loopback, size_t vertex_count, const EdgeAdjacency& adjacency, const unsigned int* remap, const unsigned int* wedge, unsigned int options)
|
||||
{
|
||||
memset(loop, -1, vertex_count * sizeof(unsigned int));
|
||||
memset(loopback, -1, vertex_count * sizeof(unsigned int));
|
||||
|
@ -274,7 +274,15 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
|
|||
{
|
||||
unsigned int target = edges[j].next;
|
||||
|
||||
if (!hasEdge(adjacency, target, vertex))
|
||||
if (target == vertex)
|
||||
{
|
||||
// degenerate triangles have two distinct edges instead of three, and the self edge
|
||||
// is bi-directional by definition; this can break border/seam classification by "closing"
|
||||
// the open edge from another triangle and falsely marking the vertex as manifold
|
||||
// instead we mark the vertex as having >1 open edges which turns it into locked/complex
|
||||
openinc[vertex] = openout[vertex] = vertex;
|
||||
}
|
||||
else if (!hasEdge(adjacency, target, vertex))
|
||||
{
|
||||
openinc[target] = (openinc[target] == ~0u) ? vertex : target;
|
||||
openout[vertex] = (openout[vertex] == ~0u) ? target : vertex;
|
||||
|
@ -354,6 +362,11 @@ static void classifyVertices(unsigned char* result, unsigned int* loop, unsigned
|
|||
}
|
||||
}
|
||||
|
||||
if (options & meshopt_SimplifyLockBorder)
|
||||
for (size_t i = 0; i < vertex_count; ++i)
|
||||
if (result[i] == Kind_Border)
|
||||
result[i] = Kind_Locked;
|
||||
|
||||
#if TRACE
|
||||
printf("locked: many open edges %d, disconnected seam %d, many seam edges %d, many wedges %d\n",
|
||||
int(stats[0]), int(stats[1]), int(stats[2]), int(stats[3]));
|
||||
|
@ -1264,7 +1277,7 @@ MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoop = 0;
|
|||
MESHOPTIMIZER_API unsigned int* meshopt_simplifyDebugLoopBack = 0;
|
||||
#endif
|
||||
|
||||
size_t meshopt_simplify(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, size_t target_index_count, float target_error, float* out_result_error)
|
||||
size_t meshopt_simplify(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, size_t target_index_count, float target_error, unsigned int options, float* out_result_error)
|
||||
{
|
||||
using namespace meshopt;
|
||||
|
||||
|
@ -1272,6 +1285,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
|
|||
assert(vertex_positions_stride > 0 && vertex_positions_stride <= 256);
|
||||
assert(vertex_positions_stride % sizeof(float) == 0);
|
||||
assert(target_index_count <= index_count);
|
||||
assert((options & ~(meshopt_SimplifyLockBorder)) == 0);
|
||||
|
||||
meshopt_Allocator allocator;
|
||||
|
||||
|
@ -1291,7 +1305,7 @@ size_t meshopt_simplify(unsigned int* destination, const unsigned int* indices,
|
|||
unsigned char* vertex_kind = allocator.allocate<unsigned char>(vertex_count);
|
||||
unsigned int* loop = allocator.allocate<unsigned int>(vertex_count);
|
||||
unsigned int* loopback = allocator.allocate<unsigned int>(vertex_count);
|
||||
classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge);
|
||||
classifyVertices(vertex_kind, loop, loopback, vertex_count, adjacency, remap, wedge, options);
|
||||
|
||||
#if TRACE
|
||||
size_t unique_positions = 0;
|
||||
|
|
Loading…
Reference in New Issue