Skip to content

Commit 4006da2

Browse files
committed
demo: Replace boundsMerge function with a more precise variant
Instead of an ad-hoc sphere merge that sometimes produces suboptimal results we use meshopt_copmuteSphereBounds to compute a much tighter sphere. This probably is not crucial in practice since this sphere is not used for culling, but there might be cases where it's more efficient to just keep a single sphere, and it's a convenient use of the algorithm.
1 parent 8c42037 commit 4006da2

File tree

1 file changed

+8
-26
lines changed

1 file changed

+8
-26
lines changed

demo/nanite.cpp

Lines changed: 8 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -86,35 +86,17 @@ static LODBounds bounds(const std::vector<Vertex>& vertices, const std::vector<u
8686

8787
static LODBounds boundsMerge(const std::vector<Cluster>& clusters, const std::vector<int>& group)
8888
{
89-
LODBounds result = {};
90-
91-
// we approximate merged bounds center as weighted average of cluster centers
92-
// (could also use bounds() center, but we can't use bounds() radius so might as well just merge manually)
93-
float weight = 0.f;
89+
std::vector<LODBounds> bounds(group.size());
9490
for (size_t j = 0; j < group.size(); ++j)
95-
{
96-
result.center[0] += clusters[group[j]].self.center[0] * clusters[group[j]].self.radius;
97-
result.center[1] += clusters[group[j]].self.center[1] * clusters[group[j]].self.radius;
98-
result.center[2] += clusters[group[j]].self.center[2] * clusters[group[j]].self.radius;
99-
weight += clusters[group[j]].self.radius;
100-
}
91+
bounds[j] = clusters[group[j]].self;
10192

102-
if (weight > 0)
103-
{
104-
result.center[0] /= weight;
105-
result.center[1] /= weight;
106-
result.center[2] /= weight;
107-
}
93+
meshopt_Bounds merged = meshopt_computeSphereBounds(&bounds[0].center[0], bounds.size(), sizeof(LODBounds), &bounds[0].radius, sizeof(LODBounds));
10894

109-
// merged bounds must strictly contain all cluster bounds
110-
result.radius = 0.f;
111-
for (size_t j = 0; j < group.size(); ++j)
112-
{
113-
float dx = clusters[group[j]].self.center[0] - result.center[0];
114-
float dy = clusters[group[j]].self.center[1] - result.center[1];
115-
float dz = clusters[group[j]].self.center[2] - result.center[2];
116-
result.radius = std::max(result.radius, clusters[group[j]].self.radius + sqrtf(dx * dx + dy * dy + dz * dz));
117-
}
95+
LODBounds result = {};
96+
result.center[0] = merged.center[0];
97+
result.center[1] = merged.center[1];
98+
result.center[2] = merged.center[2];
99+
result.radius = merged.radius;
118100

119101
// merged bounds error must be conservative wrt cluster errors
120102
result.error = 0.f;

0 commit comments

Comments
 (0)