mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-10-28 11:45:26 +00:00
Updated meshoptimizer.
This commit is contained in:
committed by
Branimir Karadžić
parent
0292095363
commit
c35f437910
+64
-26
@@ -620,7 +620,7 @@ static void rescaleAttributes(float* result, const float* vertex_attributes_data
|
||||
}
|
||||
}
|
||||
|
||||
static void finalizeVertices(float* vertex_positions_data, size_t vertex_positions_stride, float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t vertex_count, const Vector3* vertex_positions, const float* vertex_attributes, const unsigned int* sparse_remap, const unsigned int* attribute_remap, float vertex_scale, const float* vertex_offset, const unsigned char* vertex_update)
|
||||
static void finalizeVertices(float* vertex_positions_data, size_t vertex_positions_stride, float* vertex_attributes_data, size_t vertex_attributes_stride, const float* attribute_weights, size_t attribute_count, size_t vertex_count, const Vector3* vertex_positions, const float* vertex_attributes, const unsigned int* sparse_remap, const unsigned int* attribute_remap, float vertex_scale, const float* vertex_offset, const unsigned char* vertex_kind, const unsigned char* vertex_update, const unsigned char* vertex_lock)
|
||||
{
|
||||
size_t vertex_positions_stride_float = vertex_positions_stride / sizeof(float);
|
||||
size_t vertex_attributes_stride_float = vertex_attributes_stride / sizeof(float);
|
||||
@@ -632,12 +632,20 @@ static void finalizeVertices(float* vertex_positions_data, size_t vertex_positio
|
||||
|
||||
unsigned int ri = sparse_remap ? sparse_remap[i] : unsigned(i);
|
||||
|
||||
const Vector3& p = vertex_positions[i];
|
||||
float* v = vertex_positions_data + ri * vertex_positions_stride_float;
|
||||
// updating externally locked vertices is not allowed
|
||||
if (vertex_lock && (vertex_lock[ri] & meshopt_SimplifyVertex_Lock) != 0)
|
||||
continue;
|
||||
|
||||
v[0] = p.x * vertex_scale + vertex_offset[0];
|
||||
v[1] = p.y * vertex_scale + vertex_offset[1];
|
||||
v[2] = p.z * vertex_scale + vertex_offset[2];
|
||||
// moving locked vertices may result in floating point drift
|
||||
if (vertex_kind[i] != Kind_Locked)
|
||||
{
|
||||
const Vector3& p = vertex_positions[i];
|
||||
float* v = vertex_positions_data + ri * vertex_positions_stride_float;
|
||||
|
||||
v[0] = p.x * vertex_scale + vertex_offset[0];
|
||||
v[1] = p.y * vertex_scale + vertex_offset[1];
|
||||
v[2] = p.z * vertex_scale + vertex_offset[2];
|
||||
}
|
||||
|
||||
if (attribute_count)
|
||||
{
|
||||
@@ -1637,10 +1645,10 @@ static void updateQuadrics(const unsigned int* collapse_remap, size_t vertex_cou
|
||||
}
|
||||
}
|
||||
|
||||
static void solveQuadrics(Vector3* vertex_positions, float* vertex_attributes, size_t vertex_count, const Quadric* vertex_quadrics, const QuadricGrad* volume_gradients, const Quadric* attribute_quadrics, const QuadricGrad* attribute_gradients, size_t attribute_count, const unsigned int* remap, const unsigned int* wedge, const EdgeAdjacency& adjacency, const unsigned char* vertex_kind, const unsigned char* vertex_update)
|
||||
static void solvePositions(Vector3* vertex_positions, size_t vertex_count, const Quadric* vertex_quadrics, const QuadricGrad* volume_gradients, const Quadric* attribute_quadrics, const QuadricGrad* attribute_gradients, size_t attribute_count, const unsigned int* remap, const unsigned int* wedge, const EdgeAdjacency& adjacency, const unsigned char* vertex_kind, const unsigned char* vertex_update)
|
||||
{
|
||||
#if TRACE
|
||||
size_t stats[5] = {};
|
||||
size_t stats[6] = {};
|
||||
#endif
|
||||
|
||||
for (size_t i = 0; i < vertex_count; ++i)
|
||||
@@ -1648,7 +1656,6 @@ static void solveQuadrics(Vector3* vertex_positions, float* vertex_attributes, s
|
||||
if (!vertex_update[i])
|
||||
continue;
|
||||
|
||||
// moving externally locked vertices is prohibited
|
||||
// moving vertices on an attribute discontinuity may result in extrapolating UV outside of the chart bounds
|
||||
// moving vertices on a border requires a stronger edge quadric to preserve the border geometry
|
||||
if (vertex_kind[i] == Kind_Locked || vertex_kind[i] == Kind_Seam || vertex_kind[i] == Kind_Border)
|
||||
@@ -1712,36 +1719,64 @@ static void solveQuadrics(Vector3* vertex_positions, float* vertex_attributes, s
|
||||
continue;
|
||||
}
|
||||
|
||||
// reject updates that increase positional error too much; allow some tolerance to improve attribute quality
|
||||
if (quadricError(vertex_quadrics[i], p) > quadricError(vertex_quadrics[i], vp) * 1.5f + 1e-6f)
|
||||
{
|
||||
TRACESTATS(5);
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACESTATS(1);
|
||||
vertex_positions[i] = p;
|
||||
}
|
||||
|
||||
#if TRACE
|
||||
printf("updated %d/%d positions; failed solve %d bounds %d flip %d\n", int(stats[1]), int(stats[0]), int(stats[2]), int(stats[3]), int(stats[4]));
|
||||
printf("updated %d/%d positions; failed solve %d bounds %d flip %d error %d\n", int(stats[1]), int(stats[0]), int(stats[2]), int(stats[3]), int(stats[4]), int(stats[5]));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (attribute_count == 0)
|
||||
return;
|
||||
|
||||
static void solveAttributes(Vector3* vertex_positions, float* vertex_attributes, size_t vertex_count, const Quadric* attribute_quadrics, const QuadricGrad* attribute_gradients, size_t attribute_count, const unsigned int* remap, const unsigned int* wedge, const unsigned char* vertex_kind, const unsigned char* vertex_update)
|
||||
{
|
||||
for (size_t i = 0; i < vertex_count; ++i)
|
||||
{
|
||||
if (!vertex_update[i])
|
||||
continue;
|
||||
|
||||
// updating externally locked vertices is prohibited
|
||||
if (vertex_kind[i] == Kind_Locked)
|
||||
if (remap[i] != i)
|
||||
continue;
|
||||
|
||||
const Vector3& p = vertex_positions[remap[i]];
|
||||
const Quadric& A = attribute_quadrics[i];
|
||||
|
||||
float iw = A.w == 0 ? 0.f : 1.f / A.w;
|
||||
|
||||
for (size_t k = 0; k < attribute_count; ++k)
|
||||
{
|
||||
const QuadricGrad& G = attribute_gradients[i * attribute_count + k];
|
||||
unsigned int shared = ~0u;
|
||||
|
||||
vertex_attributes[i * attribute_count + k] = (G.gx * p.x + G.gy * p.y + G.gz * p.z + G.gw) * iw;
|
||||
// for complex vertices, preserve attribute continuity and use highest weight wedge if values were shared
|
||||
if (vertex_kind[i] == Kind_Complex)
|
||||
{
|
||||
shared = unsigned(i);
|
||||
|
||||
for (unsigned int v = wedge[i]; v != i; v = wedge[v])
|
||||
if (vertex_attributes[v * attribute_count + k] != vertex_attributes[i * attribute_count + k])
|
||||
shared = ~0u;
|
||||
else if (shared != ~0u && attribute_quadrics[v].w > attribute_quadrics[shared].w)
|
||||
shared = v;
|
||||
}
|
||||
|
||||
// update attributes for all wedges
|
||||
unsigned int v = unsigned(i);
|
||||
do
|
||||
{
|
||||
unsigned int r = (shared == ~0u) ? v : shared;
|
||||
|
||||
const Vector3& p = vertex_positions[i]; // same for all wedges
|
||||
const Quadric& A = attribute_quadrics[r];
|
||||
const QuadricGrad& G = attribute_gradients[r * attribute_count + k];
|
||||
|
||||
float iw = A.w == 0 ? 0.f : 1.f / A.w;
|
||||
float av = (G.gx * p.x + G.gy * p.y + G.gz * p.z + G.gw) * iw;
|
||||
|
||||
vertex_attributes[v * attribute_count + k] = av;
|
||||
v = wedge[v];
|
||||
} while (v != i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2522,16 +2557,19 @@ size_t meshopt_simplifyEdge(unsigned int* destination, const unsigned int* indic
|
||||
{
|
||||
unsigned int v = result[i];
|
||||
|
||||
// recomputing externally locked vertices may result in floating point drift
|
||||
vertex_update[v] = vertex_kind[v] != Kind_Locked;
|
||||
// mark the vertex for finalizeVertices and root vertex for solve*
|
||||
vertex_update[remap[v]] = vertex_update[v] = 1;
|
||||
}
|
||||
|
||||
// edge adjacency may be stale as we haven't updated it after last series of edge collapses
|
||||
updateEdgeAdjacency(adjacency, result, result_count, vertex_count, remap);
|
||||
|
||||
solveQuadrics(vertex_positions, vertex_attributes, vertex_count, vertex_quadrics, volume_gradients, attribute_quadrics, attribute_gradients, attribute_count, remap, wedge, adjacency, vertex_kind, vertex_update);
|
||||
solvePositions(vertex_positions, vertex_count, vertex_quadrics, volume_gradients, attribute_quadrics, attribute_gradients, attribute_count, remap, wedge, adjacency, vertex_kind, vertex_update);
|
||||
|
||||
finalizeVertices(const_cast<float*>(vertex_positions_data), vertex_positions_stride, const_cast<float*>(vertex_attributes_data), vertex_attributes_stride, attribute_weights, attribute_count, vertex_count, vertex_positions, vertex_attributes, sparse_remap, attribute_remap, vertex_scale, vertex_offset, vertex_update);
|
||||
if (attribute_count)
|
||||
solveAttributes(vertex_positions, vertex_attributes, vertex_count, attribute_quadrics, attribute_gradients, attribute_count, remap, wedge, vertex_kind, vertex_update);
|
||||
|
||||
finalizeVertices(const_cast<float*>(vertex_positions_data), vertex_positions_stride, const_cast<float*>(vertex_attributes_data), vertex_attributes_stride, attribute_weights, attribute_count, vertex_count, vertex_positions, vertex_attributes, sparse_remap, attribute_remap, vertex_scale, vertex_offset, vertex_kind, vertex_update, vertex_lock);
|
||||
}
|
||||
|
||||
// if debug visualization data is requested, fill it instead of index data; for simplicity, this doesn't work with sparsity
|
||||
|
||||
Reference in New Issue
Block a user