mirror of
https://github.com/openharmony/third_party_meshoptimizer.git
synced 2026-07-20 23:46:19 -04:00
Merge pull request #619 from zeux/simp-pcol
simplify: Add color support to simplifyPoints
This commit is contained in:
+1
-1
@@ -524,7 +524,7 @@ void simplifyPoints(const Mesh& mesh, float threshold = 0.2f)
|
||||
size_t target_vertex_count = size_t(mesh.vertices.size() * threshold);
|
||||
|
||||
std::vector<unsigned int> indices(target_vertex_count);
|
||||
indices.resize(meshopt_simplifyPoints(&indices[0], &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), target_vertex_count));
|
||||
indices.resize(meshopt_simplifyPoints(&indices[0], &mesh.vertices[0].px, mesh.vertices.size(), sizeof(Vertex), NULL, 0, 0, target_vertex_count));
|
||||
|
||||
double end = timestamp();
|
||||
|
||||
|
||||
+1
-1
@@ -1004,7 +1004,7 @@ static void simplifyPointsStuck()
|
||||
const float vb[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
|
||||
// simplifying down to 0 points results in 0 immediately
|
||||
assert(meshopt_simplifyPoints(0, vb, 3, 12, 0) == 0);
|
||||
assert(meshopt_simplifyPoints(0, vb, 3, 12, 0, 0, 0, 0) == 0);
|
||||
}
|
||||
|
||||
static void simplifyFlip()
|
||||
|
||||
+5
-1
@@ -696,6 +696,8 @@ static void simplifyPointMesh(Mesh& mesh, float threshold)
|
||||
if (!positions)
|
||||
return;
|
||||
|
||||
const Stream* colors = getStream(mesh, cgltf_attribute_type_color);
|
||||
|
||||
size_t vertex_count = mesh.streams[0].data.size();
|
||||
|
||||
size_t target_vertex_count = size_t(double(vertex_count) * threshold);
|
||||
@@ -703,8 +705,10 @@ static void simplifyPointMesh(Mesh& mesh, float threshold)
|
||||
if (target_vertex_count < 1)
|
||||
return;
|
||||
|
||||
const float color_weight = 1e-2f;
|
||||
|
||||
std::vector<unsigned int> indices(target_vertex_count);
|
||||
indices.resize(meshopt_simplifyPoints(&indices[0], positions->data[0].f, vertex_count, sizeof(Attr), target_vertex_count));
|
||||
indices.resize(meshopt_simplifyPoints(&indices[0], positions->data[0].f, vertex_count, sizeof(Attr), colors ? colors->data[0].f : NULL, sizeof(Attr), color_weight, target_vertex_count));
|
||||
|
||||
std::vector<Attr> scratch(indices.size());
|
||||
|
||||
|
||||
+2
-1
@@ -382,8 +382,9 @@ MESHOPTIMIZER_EXPERIMENTAL size_t meshopt_simplifySloppy(unsigned int* destinati
|
||||
*
|
||||
* 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_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
|
||||
|
||||
+33
-11
@@ -461,6 +461,7 @@ struct QuadricGrad
|
||||
struct Reservoir
|
||||
{
|
||||
float x, y, z;
|
||||
float r, g, b;
|
||||
float w;
|
||||
};
|
||||
|
||||
@@ -1322,20 +1323,27 @@ static void fillCellQuadrics(Quadric* cell_quadrics, const unsigned int* indices
|
||||
}
|
||||
}
|
||||
|
||||
static void fillCellReservoirs(Reservoir* cell_reservoirs, size_t cell_count, 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)
|
||||
{
|
||||
unsigned int cell = vertex_cells[i];
|
||||
const Vector3& v = vertex_positions[i];
|
||||
Reservoir& r = cell_reservoirs[cell];
|
||||
|
||||
float w = 1.f;
|
||||
const float* color = vertex_colors ? &vertex_colors[i * vertex_colors_stride_float] : dummy_color;
|
||||
|
||||
r.x += v.x * w;
|
||||
r.y += v.y * w;
|
||||
r.z += v.z * w;
|
||||
r.w += w;
|
||||
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)
|
||||
@@ -1347,6 +1355,9 @@ static void fillCellReservoirs(Reservoir* cell_reservoirs, size_t cell_count, co
|
||||
r.x *= iw;
|
||||
r.y *= iw;
|
||||
r.z *= iw;
|
||||
r.r *= iw;
|
||||
r.g *= iw;
|
||||
r.b *= iw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1367,8 +1378,12 @@ 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, size_t vertex_count)
|
||||
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)
|
||||
@@ -1377,7 +1392,11 @@ static void fillCellRemap(unsigned int* cell_remap, float* cell_errors, size_t c
|
||||
const Vector3& v = vertex_positions[i];
|
||||
const Reservoir& r = cell_reservoirs[cell];
|
||||
|
||||
float 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);
|
||||
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)
|
||||
{
|
||||
@@ -1755,12 +1774,15 @@ size_t meshopt_simplifySloppy(unsigned int* destination, const unsigned int* ind
|
||||
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;
|
||||
|
||||
assert(vertex_positions_stride >= 12 && vertex_positions_stride <= 256);
|
||||
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);
|
||||
|
||||
size_t target_cell_count = target_vertex_count;
|
||||
@@ -1848,13 +1870,13 @@ size_t meshopt_simplifyPoints(unsigned int* destination, const float* vertex_pos
|
||||
Reservoir* cell_reservoirs = allocator.allocate<Reservoir>(cell_count);
|
||||
memset(cell_reservoirs, 0, cell_count * sizeof(Reservoir));
|
||||
|
||||
fillCellReservoirs(cell_reservoirs, cell_count, 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
|
||||
unsigned int* cell_remap = allocator.allocate<unsigned int>(cell_count);
|
||||
float* cell_errors = allocator.allocate<float>(cell_count);
|
||||
|
||||
fillCellRemap(cell_remap, cell_errors, cell_count, vertex_cells, cell_reservoirs, 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
|
||||
assert(cell_count <= target_vertex_count);
|
||||
|
||||
Reference in New Issue
Block a user