Skip to content

Commit ccaebbc

Browse files
committed
clusterizer: Expose sphere bounds computation
The existing functions for computing cluster bounds, meshopt_computeMeshletBounds and meshopt_computeClusterBounds, rely on an internal computeBoundingSphere algorithm. This algorithm can be useful in a few other cases: - The cluster functions limit the input size to avoid allocations, as they need to reshape the inputs into a form that can be consumed by the internal function; sometimes it's convenient to compute a bounding sphere of what is essentially an unbounded point cloud - For hierarchical simplification, it's useful to be able to compute a bounding sphere for an input set of spheres instead of just points. This change exposes a basic implementation of both of the above with one function that takes a set of points and, optionally, a per-point radius. The current implementation uses computeBoundingSphere to compute the center of the resulting sphere ignoring the radii; this results in suboptimal output and will be changed separately, just as the extra allocations that are unnecessary and will be removed.
1 parent a938600 commit ccaebbc

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

src/clusterizer.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,56 @@ meshopt_Bounds meshopt_computeMeshletBounds(const unsigned int* meshlet_vertices
973973
return meshopt_computeClusterBounds(indices, triangle_count * 3, vertex_positions, vertex_count, vertex_positions_stride);
974974
}
975975

976+
meshopt_Bounds meshopt_computeSphereBounds(const float* positions, size_t count, size_t positions_stride, const float* radii, size_t radii_stride)
977+
{
978+
using namespace meshopt;
979+
980+
assert(positions_stride >= 12 && positions_stride <= 256);
981+
assert(positions_stride % sizeof(float) == 0);
982+
assert(radii == NULL || radii_stride >= 4);
983+
assert(radii_stride % sizeof(float) == 0);
984+
985+
meshopt_Bounds bounds = {};
986+
987+
if (count == 0)
988+
return bounds;
989+
990+
meshopt_Allocator allocator;
991+
float* centers = allocator.allocate<float>(count * 3); // TBD
992+
993+
for (size_t i = 0; i < count; ++i)
994+
{
995+
const float* position = positions + i * (positions_stride / sizeof(float));
996+
997+
centers[i * 3 + 0] = position[0];
998+
centers[i * 3 + 1] = position[1];
999+
centers[i * 3 + 2] = position[2];
1000+
}
1001+
1002+
float psphere[4] = {};
1003+
computeBoundingSphere(psphere, (float(*)[3])centers, count);
1004+
1005+
float pradius = 0;
1006+
1007+
for (size_t i = 0; i < count; ++i)
1008+
{
1009+
const float* position = positions + i * (positions_stride / sizeof(float));
1010+
float radius = radii ? radii[i * (radii_stride / sizeof(float))] : 0;
1011+
1012+
float dx = position[0] - psphere[0], dy = position[1] - psphere[1], dz = position[2] - psphere[2];
1013+
float distance = sqrtf(dx * dx + dy * dy + dz * dz) + radius;
1014+
1015+
pradius = pradius < distance ? distance : pradius;
1016+
}
1017+
1018+
bounds.center[0] = psphere[0];
1019+
bounds.center[1] = psphere[1];
1020+
bounds.center[2] = psphere[2];
1021+
bounds.radius = pradius;
1022+
1023+
return bounds;
1024+
}
1025+
9761026
void meshopt_optimizeMeshlet(unsigned int* meshlet_vertices, unsigned char* meshlet_triangles, size_t triangle_count, size_t vertex_count)
9771027
{
9781028
using namespace meshopt;

src/meshoptimizer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,8 @@ struct meshopt_Bounds
619619
MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeClusterBounds(const unsigned int* indices, size_t index_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
620620
MESHOPTIMIZER_API struct meshopt_Bounds meshopt_computeMeshletBounds(const unsigned int* meshlet_vertices, const unsigned char* meshlet_triangles, size_t triangle_count, const float* vertex_positions, size_t vertex_count, size_t vertex_positions_stride);
621621

622+
MESHOPTIMIZER_EXPERIMENTAL struct meshopt_Bounds meshopt_computeSphereBounds(const float* positions, size_t count, size_t positions_stride, const float* radii, size_t radii_stride);
623+
622624
/**
623625
* Experimental: Cluster partitioner
624626
* Partitions clusters into groups of similar size, prioritizing grouping clusters that share vertices.

0 commit comments

Comments
 (0)