@@ -141,11 +141,12 @@ static void buildTriangleAdjacencySparse(TriangleAdjacency2& adjacency, const un
141
141
}
142
142
}
143
143
144
- static void computeBoundingSphere (float result[4 ], const float * points, size_t count, size_t points_stride)
144
+ static void computeBoundingSphere (float result[4 ], const float * points, size_t count, size_t points_stride, const float * radii, size_t radii_stride )
145
145
{
146
146
assert (count > 0 );
147
147
148
148
size_t points_stride_float = points_stride / sizeof (float );
149
+ size_t radii_stride_float = radii_stride / sizeof (float );
149
150
150
151
// find extremum points along all 3 axes; for each axis we get a pair of points with min/max coordinates
151
152
size_t pmin[3 ] = {0 , 0 , 0 };
@@ -154,28 +155,35 @@ static void computeBoundingSphere(float result[4], const float* points, size_t c
154
155
for (size_t i = 0 ; i < count; ++i)
155
156
{
156
157
const float * p = points + i * points_stride_float;
158
+ float r = radii[i * radii_stride_float];
157
159
158
160
for (int axis = 0 ; axis < 3 ; ++axis)
159
161
{
160
- pmin[axis] = (p[axis] < points[pmin[axis] * points_stride_float + axis]) ? i : pmin[axis];
161
- pmax[axis] = (p[axis] > points[pmax[axis] * points_stride_float + axis]) ? i : pmax[axis];
162
+ float bmin = points[pmin[axis] * points_stride_float + axis] - radii[pmin[axis] * radii_stride_float];
163
+ float bmax = points[pmax[axis] * points_stride_float + axis] + radii[pmax[axis] * radii_stride_float];
164
+
165
+ pmin[axis] = (p[axis] - r < bmin) ? i : pmin[axis];
166
+ pmax[axis] = (p[axis] + r > bmax) ? i : pmax[axis];
162
167
}
163
168
}
164
169
165
170
// find the pair of points with largest distance
166
- float paxisd2 = 0 ;
167
171
int paxis = 0 ;
172
+ float paxisdr = 0 ;
168
173
169
174
for (int axis = 0 ; axis < 3 ; ++axis)
170
175
{
171
176
const float * p1 = points + pmin[axis] * points_stride_float;
172
177
const float * p2 = points + pmax[axis] * points_stride_float;
178
+ float r1 = radii[pmin[axis] * radii_stride_float];
179
+ float r2 = radii[pmax[axis] * radii_stride_float];
173
180
174
181
float d2 = (p2[0 ] - p1[0 ]) * (p2[0 ] - p1[0 ]) + (p2[1 ] - p1[1 ]) * (p2[1 ] - p1[1 ]) + (p2[2 ] - p1[2 ]) * (p2[2 ] - p1[2 ]);
182
+ float dr = sqrtf (d2) + r1 + r2;
175
183
176
- if (d2 > paxisd2 )
184
+ if (dr > paxisdr )
177
185
{
178
- paxisd2 = d2 ;
186
+ paxisdr = dr ;
179
187
paxis = axis;
180
188
}
181
189
}
@@ -185,25 +193,25 @@ static void computeBoundingSphere(float result[4], const float* points, size_t c
185
193
const float * p2 = points + pmax[paxis] * points_stride_float;
186
194
187
195
float center[3 ] = {(p1[0 ] + p2[0 ]) / 2 , (p1[1 ] + p2[1 ]) / 2 , (p1[2 ] + p2[2 ]) / 2 };
188
- float radius = sqrtf (paxisd2) / 2 ;
196
+ float radius = paxisdr / 2 ;
189
197
190
198
// iteratively adjust the sphere up until all points fit
191
199
for (size_t i = 0 ; i < count; ++i)
192
200
{
193
201
const float * p = points + i * points_stride_float;
202
+ float r = radii[i * radii_stride_float];
203
+
194
204
float d2 = (p[0 ] - center[0 ]) * (p[0 ] - center[0 ]) + (p[1 ] - center[1 ]) * (p[1 ] - center[1 ]) + (p[2 ] - center[2 ]) * (p[2 ] - center[2 ]);
205
+ float dr = sqrtf (d2) + r;
195
206
196
- if (d2 > radius * radius)
207
+ if (dr > radius)
197
208
{
198
- float d = sqrtf (d2);
199
- assert (d > 0 );
200
-
201
- float k = 0 .5f + (radius / d) / 2 ;
209
+ float k = 0 .5f + (radius / dr) / 2 ;
202
210
203
211
center[0 ] = center[0 ] * k + p[0 ] * (1 - k);
204
212
center[1 ] = center[1 ] * k + p[1 ] * (1 - k);
205
213
center[2 ] = center[2 ] * k + p[2 ] * (1 - k);
206
- radius = (radius + d ) / 2 ;
214
+ radius = (radius + dr ) / 2 ;
207
215
}
208
216
}
209
217
@@ -857,15 +865,17 @@ meshopt_Bounds meshopt_computeClusterBounds(const unsigned int* indices, size_t
857
865
if (triangles == 0 )
858
866
return bounds;
859
867
868
+ const float rzero = 0 .f ;
869
+
860
870
// compute cluster bounding sphere; we'll use the center to determine normal cone apex as well
861
871
float psphere[4 ] = {};
862
- computeBoundingSphere (psphere, corners[0 ][0 ], triangles * 3 , sizeof (float ) * 3 );
872
+ computeBoundingSphere (psphere, corners[0 ][0 ], triangles * 3 , sizeof (float ) * 3 , &rzero, 0 );
863
873
864
874
float center[3 ] = {psphere[0 ], psphere[1 ], psphere[2 ]};
865
875
866
876
// treating triangle normals as points, find the bounding sphere - the sphere center determines the optimal cone axis
867
877
float nsphere[4 ] = {};
868
- computeBoundingSphere (nsphere, normals[0 ], triangles, sizeof (float ) * 3 );
878
+ computeBoundingSphere (nsphere, normals[0 ], triangles, sizeof (float ) * 3 , &rzero, 0 );
869
879
870
880
float axis[3 ] = {nsphere[0 ], nsphere[1 ], nsphere[2 ]};
871
881
float axislength = sqrtf (axis[0 ] * axis[0 ] + axis[1 ] * axis[1 ] + axis[2 ] * axis[2 ]);
@@ -981,16 +991,18 @@ meshopt_Bounds meshopt_computeSphereBounds(const float* positions, size_t count,
981
991
982
992
assert (positions_stride >= 12 && positions_stride <= 256 );
983
993
assert (positions_stride % sizeof (float ) == 0 );
984
- assert (radii == NULL || radii_stride >= 4 );
994
+ assert ((radii_stride >= 4 && radii_stride <= 256 ) || radii == NULL );
985
995
assert (radii_stride % sizeof (float ) == 0 );
986
996
987
997
meshopt_Bounds bounds = {};
988
998
989
999
if (count == 0 )
990
1000
return bounds;
991
1001
1002
+ const float rzero = 0 .f ;
1003
+
992
1004
float psphere[4 ] = {};
993
- computeBoundingSphere (psphere, positions, count, positions_stride);
1005
+ computeBoundingSphere (psphere, positions, count, positions_stride, radii ? radii : &rzero, radii ? radii_stride : 0 );
994
1006
995
1007
float pradius = 0 ;
996
1008
0 commit comments