@@ -39,25 +39,25 @@ const int MAX_TRIS = 100;
39
39
// We will use struct arrays for representing
40
40
// the data for each box and intersecting
41
41
// triangles
42
- typedef struct {
42
+ struct FaceVerts {
43
43
float3 v0;
44
44
float3 v1;
45
45
float3 v2;
46
46
float3 v3; // Can be empty for triangles
47
- } FaceVerts ;
47
+ };
48
48
49
- typedef struct {
49
+ struct FaceVertsIdx {
50
50
int v0;
51
51
int v1;
52
52
int v2;
53
53
int v3; // Can be empty for triangles
54
- } FaceVertsIdx ;
54
+ };
55
55
56
56
// This is used when deciding which faces to
57
57
// keep that are not coplanar
58
- typedef struct {
58
+ struct Keep {
59
59
bool keep;
60
- } Keep ;
60
+ };
61
61
62
62
__device__ FaceVertsIdx _PLANES[] = {
63
63
{0 , 1 , 2 , 3 },
@@ -128,64 +128,64 @@ __device__ inline void GetBoxPlanes(
128
128
}
129
129
}
130
130
131
- // The normal of a plane spanned by vectors e0 and e1
131
+ // The geometric center of a list of vertices.
132
132
//
133
133
// Args
134
- // e0, e1: float3 vectors defining a plane
134
+ // vertices: A list of float3 vertices {v0, ..., vN}.
135
135
//
136
136
// Returns
137
- // float3: normal of the plane
137
+ // float3: Geometric center of the vertices.
138
138
//
139
- __device__ inline float3 GetNormal (const float3 e0 , const float3 e1 ) {
140
- float3 n = cross (e0 , e1 );
141
- n = n / std::fmaxf (norm (n), kEpsilon );
142
- return n;
139
+ __device__ inline float3 FaceCenter (
140
+ std::initializer_list<const float3 > vertices) {
141
+ auto sumVertices = float3 {};
142
+ for (const auto & vertex : vertices) {
143
+ sumVertices = sumVertices + vertex;
144
+ }
145
+ return sumVertices / vertices.size ();
143
146
}
144
147
145
- // The center of a triangle defined by vertices (v0, v1, v2)
148
+ // The normal of a plane spanned by vectors e0 and e1
146
149
//
147
150
// Args
148
- // v0, v1, v2 : float3 coordinates of the vertices of the triangle
151
+ // e0, e1 : float3 vectors defining a plane
149
152
//
150
153
// Returns
151
- // float3: center of the triangle
154
+ // float3: normal of the plane
152
155
//
153
- __device__ inline float3
154
- TriCenter ( const float3 v0, const float3 v1, const float3 v2) {
155
- float3 ctr = (v0 + v1 + v2) / 3 . 0f ;
156
- return ctr ;
156
+ __device__ inline float3 GetNormal ( const float3 e0 , const float3 e1 ) {
157
+ float3 n = cross ( e0 , e1 );
158
+ n = n / std::fmaxf ( norm (n), kEpsilon ) ;
159
+ return n ;
157
160
}
158
161
159
- // The normal of the triangle defined by vertices (v0, v1, v2)
162
+ // The normal of a face with vertices (v0, v1, v2) or (v0, ..., v3).
160
163
// We find the "best" edges connecting the face center to the vertices,
161
164
// such that the cross product between the edges is maximized.
162
165
//
163
166
// Args
164
- // v0, v1, v2: float3 coordinates of the vertices of the face
167
+ // vertices: a list of float3 coordinates of the vertices.
165
168
//
166
169
// Returns
167
- // float3: normal for the face
170
+ // float3: center of the plane
168
171
//
169
- __device__ inline float3
170
- TriNormal (const float3 v0, const float3 v1, const float3 v2) {
171
- const float3 ctr = TriCenter (v0, v1, v2);
172
-
173
- const float d01 = norm (cross (v0 - ctr, v1 - ctr));
174
- const float d02 = norm (cross (v0 - ctr, v2 - ctr));
175
- const float d12 = norm (cross (v1 - ctr, v2 - ctr));
176
-
177
- float3 n = GetNormal (v0 - ctr, v1 - ctr);
178
- float max_dist = d01;
179
-
180
- if (d02 > max_dist) {
181
- max_dist = d02;
182
- n = GetNormal (v0 - ctr, v2 - ctr);
183
- }
184
- if (d12 > max_dist) {
185
- n = GetNormal (v1 - ctr, v2 - ctr);
172
+ __device__ inline float3 FaceNormal (
173
+ std::initializer_list<const float3 > vertices) {
174
+ const auto faceCenter = FaceCenter (vertices);
175
+ auto normal = float3 ();
176
+ auto maxDist = -1 ;
177
+ for (auto v1 = vertices.begin (); v1 != vertices.end () - 1 ; ++v1) {
178
+ for (auto v2 = std::next (v1); v2 != vertices.end (); ++v2) {
179
+ const auto v1ToCenter = *v1 - faceCenter;
180
+ const auto v2ToCenter = *v2 - faceCenter;
181
+ const auto dist = norm (cross (v1ToCenter, v2ToCenter));
182
+ if (dist > maxDist) {
183
+ normal = GetNormal (v1ToCenter, v2ToCenter);
184
+ maxDist = dist;
185
+ }
186
+ }
186
187
}
187
-
188
- return n;
188
+ return normal;
189
189
}
190
190
191
191
// The area of the face defined by vertices (v0, v1, v2)
@@ -201,79 +201,10 @@ TriNormal(const float3 v0, const float3 v1, const float3 v2) {
201
201
//
202
202
__device__ inline float FaceArea (const FaceVerts& tri) {
203
203
// Get verts for face 1
204
- const float3 v0 = tri.v0 ;
205
- const float3 v1 = tri.v1 ;
206
- const float3 v2 = tri.v2 ;
207
- const float3 n = cross (v1 - v0, v2 - v0);
204
+ const float3 n = cross (tri.v1 - tri.v0 , tri.v2 - tri.v0 );
208
205
return norm (n) / 2.0 ;
209
206
}
210
207
211
- // The center of a plane defined by vertices (v0, v1, v2, v3)
212
- //
213
- // Args
214
- // v0, v1, v2, v3: float3 coordinates of the vertices of the plane
215
- //
216
- // Returns
217
- // float3: center of the plane
218
- //
219
- __device__ inline float3 PlaneCenter (
220
- const float3 v0,
221
- const float3 v1,
222
- const float3 v2,
223
- const float3 v3) {
224
- float3 ctr = (v0 + v1 + v2 + v3) / 4 .0f ;
225
- return ctr;
226
- }
227
-
228
- // The normal of a planar face with vertices (v0, v1, v2, v3)
229
- // We find the "best" edges connecting the face center to the vertices,
230
- // such that the cross product between the edges is maximized.
231
- //
232
- // Args
233
- // e0, e1: float3 coordinates of the vertices of the plane
234
- //
235
- // Returns
236
- // float3: center of the plane
237
- //
238
- __device__ inline float3 PlaneNormal (
239
- const float3 v0,
240
- const float3 v1,
241
- const float3 v2,
242
- const float3 v3) {
243
- const float3 ctr = PlaneCenter (v0, v1, v2, v3);
244
-
245
- const float d01 = norm (cross (v0 - ctr, v1 - ctr));
246
- const float d02 = norm (cross (v0 - ctr, v2 - ctr));
247
- const float d03 = norm (cross (v0 - ctr, v3 - ctr));
248
- const float d12 = norm (cross (v1 - ctr, v2 - ctr));
249
- const float d13 = norm (cross (v1 - ctr, v3 - ctr));
250
- const float d23 = norm (cross (v2 - ctr, v3 - ctr));
251
-
252
- float max_dist = d01;
253
- float3 n = GetNormal (v0 - ctr, v1 - ctr);
254
-
255
- if (d02 > max_dist) {
256
- max_dist = d02;
257
- n = GetNormal (v0 - ctr, v2 - ctr);
258
- }
259
- if (d03 > max_dist) {
260
- max_dist = d03;
261
- n = GetNormal (v0 - ctr, v3 - ctr);
262
- }
263
- if (d12 > max_dist) {
264
- max_dist = d12;
265
- n = GetNormal (v1 - ctr, v2 - ctr);
266
- }
267
- if (d13 > max_dist) {
268
- max_dist = d13;
269
- n = GetNormal (v1 - ctr, v3 - ctr);
270
- }
271
- if (d23 > max_dist) {
272
- n = GetNormal (v2 - ctr, v3 - ctr);
273
- }
274
- return n;
275
- }
276
-
277
208
// The normal of a box plane defined by the verts in `plane` such that it
278
209
// points toward the centroid of the box given by `center`.
279
210
//
@@ -290,17 +221,12 @@ template <typename FaceVertsPlane>
290
221
__device__ inline float3 PlaneNormalDirection (
291
222
const FaceVertsPlane& plane,
292
223
const float3 & center) {
293
- // The plane's vertices
294
- const float3 v0 = plane.v0 ;
295
- const float3 v1 = plane.v1 ;
296
- const float3 v2 = plane.v2 ;
297
- const float3 v3 = plane.v3 ;
298
-
299
224
// The plane's center
300
- const float3 plane_center = PlaneCenter (v0, v1, v2, v3);
225
+ const float3 plane_center =
226
+ FaceCenter ({plane.v0 , plane.v1 , plane.v2 , plane.v3 });
301
227
302
228
// The plane's normal
303
- float3 n = PlaneNormal ( v0, v1, v2, v3 );
229
+ float3 n = FaceNormal ({plane. v0 , plane. v1 , plane. v2 , plane. v3 } );
304
230
305
231
// We project the center on the plane defined by (v0, v1, v2, v3)
306
232
// We can write center = plane_center + a * e0 + b * e1 + c * n
@@ -442,14 +368,8 @@ __device__ inline float3 PolyhedronCenter(
442
368
//
443
369
__device__ inline bool
444
370
IsInside (const FaceVerts& plane, const float3 & normal, const float3 & point) {
445
- // Vertices of the plane
446
- const float3 v0 = plane.v0 ;
447
- const float3 v1 = plane.v1 ;
448
- const float3 v2 = plane.v2 ;
449
- const float3 v3 = plane.v3 ;
450
-
451
371
// The center of the plane
452
- const float3 plane_ctr = PlaneCenter ( v0, v1, v2, v3 );
372
+ const float3 plane_ctr = FaceCenter ({plane. v0 , plane. v1 , plane. v2 , plane. v3 } );
453
373
454
374
// Every point p can be written as p = plane_ctr + a e0 + b e1 + c n
455
375
// Solving for c:
@@ -478,14 +398,8 @@ __device__ inline float3 PlaneEdgeIntersection(
478
398
const float3 & normal,
479
399
const float3 & p0,
480
400
const float3 & p1) {
481
- // Vertices of the plane
482
- const float3 v0 = plane.v0 ;
483
- const float3 v1 = plane.v1 ;
484
- const float3 v2 = plane.v2 ;
485
- const float3 v3 = plane.v3 ;
486
-
487
401
// The center of the plane
488
- const float3 plane_ctr = PlaneCenter ( v0, v1, v2, v3 );
402
+ const float3 plane_ctr = FaceCenter ({plane. v0 , plane. v1 , plane. v2 , plane. v3 } );
489
403
490
404
// The point of intersection can be parametrized
491
405
// p = p0 + a (p1 - p0) where a in [0, 1]
@@ -548,30 +462,18 @@ __device__ inline std::tuple<float3, float3> ArgMaxVerts(
548
462
__device__ inline bool IsCoplanarTriTri (
549
463
const FaceVerts& tri1,
550
464
const FaceVerts& tri2) {
551
- // Get verts for face 1
552
- const float3 v0_1 = tri1.v0 ;
553
- const float3 v1_1 = tri1.v1 ;
554
- const float3 v2_1 = tri1.v2 ;
465
+ const float3 tri1_ctr = FaceCenter ({tri1.v0 , tri1.v1 , tri1.v2 });
466
+ const float3 tri1_n = FaceNormal ({tri1.v0 , tri1.v1 , tri1.v2 });
555
467
556
- const float3 tri1_ctr = TriCenter (v0_1, v1_1, v2_1);
557
- const float3 tri1_n = TriNormal (v0_1, v1_1, v2_1);
558
-
559
- // Get verts for face 2
560
- const float3 v0_2 = tri2.v0 ;
561
- const float3 v1_2 = tri2.v1 ;
562
- const float3 v2_2 = tri2.v2 ;
563
-
564
- const float3 tri2_ctr = TriCenter (v0_2, v1_2, v2_2);
565
- const float3 tri2_n = TriNormal (v0_2, v1_2, v2_2);
468
+ const float3 tri2_ctr = FaceCenter ({tri2.v0 , tri2.v1 , tri2.v2 });
469
+ const float3 tri2_n = FaceNormal ({tri2.v0 , tri2.v1 , tri2.v2 });
566
470
567
471
// Check if parallel
568
472
const bool check1 = abs (dot (tri1_n, tri2_n)) > 1 - dEpsilon;
569
473
570
474
// Compute most distant points
571
- auto argvs =
475
+ const auto [v1m, v2m] =
572
476
ArgMaxVerts ({tri1.v0 , tri1.v1 , tri1.v2 }, {tri2.v0 , tri2.v1 , tri2.v2 });
573
- const float3 v1m = std::get<0 >(argvs);
574
- const float3 v2m = std::get<1 >(argvs);
575
477
576
478
float3 n12m = v1m - v2m;
577
479
n12m = n12m / fmaxf (norm (n12m), kEpsilon );
@@ -597,22 +499,15 @@ __device__ inline bool IsCoplanarTriPlane(
597
499
const FaceVerts& tri,
598
500
const FaceVerts& plane,
599
501
const float3 & normal) {
600
- // Get verts for tri
601
- const float3 v0t = tri.v0 ;
602
- const float3 v1t = tri.v1 ;
603
- const float3 v2t = tri.v2 ;
604
-
605
- const float3 tri_ctr = TriCenter (v0t, v1t, v2t);
606
- const float3 nt = TriNormal (v0t, v1t, v2t);
502
+ const float3 tri_ctr = FaceCenter ({tri.v0 , tri.v1 , tri.v2 });
503
+ const float3 nt = FaceNormal ({tri.v0 , tri.v1 , tri.v2 });
607
504
608
505
// check if parallel
609
506
const bool check1 = abs (dot (nt, normal)) > 1 - dEpsilon;
610
507
611
508
// Compute most distant points
612
- auto argvs = ArgMaxVerts (
509
+ const auto [v1m, v2m] = ArgMaxVerts (
613
510
{tri.v0 , tri.v1 , tri.v2 }, {plane.v0 , plane.v1 , plane.v2 , plane.v3 });
614
- const float3 v1m = std::get<0 >(argvs);
615
- const float3 v2m = std::get<1 >(argvs);
616
511
617
512
float3 n12m = v1m - v2m;
618
513
n12m = n12m / fmaxf (norm (n12m), kEpsilon );
0 commit comments