3
3
4
4
#include " BvhQueryImpl.cuh"
5
5
#include " pbat/HostDevice.h"
6
+ #include " pbat/geometry/DistanceQueries.h"
7
+ #include " pbat/geometry/OverlapQueries.h"
6
8
#include " pbat/gpu/Aliases.h"
7
9
#include " pbat/gpu/common/Morton.cuh"
8
10
#include " pbat/gpu/common/Queue.cuh"
@@ -18,6 +20,8 @@ namespace gpu {
18
20
namespace geometry {
19
21
namespace BvhQueryImplKernels {
20
22
23
+ namespace mini = pbat::math::linalg::mini;
24
+
21
25
struct FComputeAabb
22
26
{
23
27
PBAT_DEVICE void operator ()(int s)
@@ -70,7 +74,6 @@ struct FComputeMortonCode
70
74
struct FDetectOverlaps
71
75
{
72
76
using OverlapType = typename BvhQueryImpl::OverlapType;
73
- using Vector3 = pbat::math::linalg::mini::SMatrix<GpuScalar, 3 >;
74
77
75
78
PBAT_DEVICE bool AreSimplicesTopologicallyAdjacent (GpuIndex si, GpuIndex sj) const
76
79
{
@@ -90,32 +93,16 @@ struct FDetectOverlaps
90
93
// clang-format on
91
94
}
92
95
93
- PBAT_DEVICE Vector3 Position (auto v) const
94
- {
95
- Vector3 P;
96
- P (0 ) = x[0 ][v];
97
- P (1 ) = x[1 ][v];
98
- P (2 ) = x[2 ][v];
99
- return P;
100
- }
101
-
102
96
PBAT_DEVICE bool VertexTetrahedronOverlap (GpuIndex v, GpuIndex t) const
103
97
{
104
- Vector3 P = Position (queryInds[0 ][v]);
105
- Vector3 A = Position (inds[0 ][t]);
106
- Vector3 B = Position (inds[1 ][t]);
107
- Vector3 C = Position (inds[2 ][t]);
108
- Vector3 D = Position (inds[3 ][t]);
109
- auto const PointOutsidePlane =
110
- [](auto const & p, auto const & a, auto const & b, auto const & c) {
111
- using namespace pbat ::math::linalg::mini;
112
- GpuScalar const d = Dot (p - a, Cross (b - a, c - a));
113
- return d > GpuScalar{0 };
114
- };
115
- bool const bOverlaps =
116
- not (PointOutsidePlane (P, A, B, D) or PointOutsidePlane (P, B, C, D) or
117
- PointOutsidePlane (P, C, A, D) or PointOutsidePlane (P, A, C, B));
118
- return bOverlaps;
98
+ using namespace mini ;
99
+ SVector<GpuScalar, 3 > P = FromBuffers<3 , 1 >(x, queryInds[0 ][v]);
100
+ SVector<GpuScalar, 3 > A = FromBuffers<3 , 1 >(x, inds[0 ][t]);
101
+ SVector<GpuScalar, 3 > B = FromBuffers<3 , 1 >(x, inds[1 ][t]);
102
+ SVector<GpuScalar, 3 > C = FromBuffers<3 , 1 >(x, inds[2 ][t]);
103
+ SVector<GpuScalar, 3 > D = FromBuffers<3 , 1 >(x, inds[3 ][t]);
104
+ using pbat::geometry::OverlapQueries::PointTetrahedron3D;
105
+ return PointTetrahedron3D (P, A, B, C, D);
119
106
}
120
107
121
108
PBAT_DEVICE bool AreSimplicesOverlapping (GpuIndex si, GpuIndex sj) const
@@ -197,140 +184,41 @@ struct FContactPairs
197
184
{
198
185
using OverlapType = typename BvhQueryImpl::OverlapType;
199
186
using NearestNeighbourPairType = typename BvhQueryImpl::NearestNeighbourPairType;
200
- using Vector3 = pbat::math::linalg::mini::SMatrix<GpuScalar, 3 >;
201
187
202
- PBAT_DEVICE Vector3 Position (auto v) const
188
+ PBAT_DEVICE GpuScalar MinDistance (
189
+ mini::SVector<GpuScalar, 3 > const & X,
190
+ mini::SVector<GpuScalar, 3 > const & L,
191
+ mini::SVector<GpuScalar, 3 > const & U) const
203
192
{
204
- Vector3 P{};
205
- P (0 ) = x[0 ][v];
206
- P (1 ) = x[1 ][v];
207
- P (2 ) = x[2 ][v];
208
- return P;
209
- }
210
- PBAT_DEVICE Vector3 Lower (auto s) const
211
- {
212
- Vector3 P{};
213
- P (0 ) = b[0 ][s];
214
- P (1 ) = b[1 ][s];
215
- P (2 ) = b[2 ][s];
216
- return P;
217
- }
218
- PBAT_DEVICE Vector3 Upper (auto s) const
219
- {
220
- Vector3 P{};
221
- P (0 ) = e[0 ][s];
222
- P (1 ) = e[1 ][s];
223
- P (2 ) = e[2 ][s];
224
- return P;
225
- }
226
- PBAT_DEVICE GpuScalar MinDistance (Vector3 const & X, Vector3 const & L, Vector3 const & U) const
227
- {
228
- using namespace pbat ::math::linalg::mini;
229
- Vector3 const DX = Min (U, Max (L, X)) - X;
193
+ using namespace mini ;
194
+ SVector<GpuScalar, 3 > const DX = Min (U, Max (L, X)) - X;
230
195
return SquaredNorm (DX);
231
196
}
232
- PBAT_DEVICE GpuScalar MinMaxDistance (Vector3 const & X, Vector3 const & L, Vector3 const & U) const
197
+ PBAT_DEVICE GpuScalar MinMaxDistance (
198
+ mini::SVector<GpuScalar, 3 > const & X,
199
+ mini::SVector<GpuScalar, 3 > const & L,
200
+ mini::SVector<GpuScalar, 3 > const & U) const
233
201
{
234
- using namespace pbat ::math::linalg:: mini;
235
- Vector3 const DXL = Squared (L - X);
236
- Vector3 const DXU = Squared (U - X);
237
- Vector3 const rm = Min (DXL, DXU);
238
- Vector3 const rM = Max (DXL, DXU);
239
- std::array <GpuScalar, 3 > const d{
202
+ using namespace mini ;
203
+ SVector<GpuScalar, 3 > DXL = Squared (L - X);
204
+ SVector<GpuScalar, 3 > DXU = Squared (U - X);
205
+ SVector<GpuScalar, 3 > rm = Min (DXL, DXU);
206
+ SVector<GpuScalar, 3 > rM = Max (DXL, DXU);
207
+ SVector <GpuScalar, 3 > d{
240
208
rm (0 ) + rM (1 ) + rM (2 ),
241
209
rM (0 ) + rm (1 ) + rM (2 ),
242
210
rM (0 ) + rM (1 ) + rm (2 ),
243
211
};
244
- return min (d[ 0 ], min (d[ 1 ], d[ 2 ]) );
212
+ return Min (d );
245
213
}
246
- PBAT_DEVICE GpuScalar Distance (Vector3 const & P, GpuIndex s) const
214
+ PBAT_DEVICE GpuScalar Distance (mini::SVector<GpuScalar, 3 > const & P, GpuIndex s) const
247
215
{
248
- using namespace pbat ::math::linalg::mini;
249
- SMatrix<GpuScalar, 3 , 3 > ABC;
250
- auto A = ABC.Col (0 );
251
- auto B = ABC.Col (1 );
252
- auto C = ABC.Col (2 );
253
- A = Position (targetInds[0 ][s]);
254
- B = Position (targetInds[1 ][s]);
255
- C = Position (targetInds[2 ][s]);
256
-
257
- /* *
258
- * Ericson, Christer. Real-time collision detection. Crc Press, 2004. section 5.1.5
259
- */
260
-
261
- // Check if P in vertex region outside A
262
- Vector3 const AB = B - A;
263
- Vector3 const AC = C - A;
264
- Vector3 const AP = P - A;
265
- GpuScalar const d1 = Dot (AB, AP);
266
- GpuScalar const d2 = Dot (AC, AP);
267
- bool const bIsInVertexRegionOutsideA = d1 <= GpuScalar{0 } and d2 <= GpuScalar{0 };
268
- if (bIsInVertexRegionOutsideA)
269
- {
270
- // barycentric coordinates (1,0,0)
271
- return SquaredNorm (P - A);
272
- }
273
-
274
- // Check if P in vertex region outside B
275
- Vector3 const BP = P - B;
276
- GpuScalar const d3 = Dot (AB, BP);
277
- GpuScalar const d4 = Dot (AC, BP);
278
- bool const bIsInVertexRegionOutsideB = d3 >= GpuScalar{0 } and d4 <= d3;
279
- if (bIsInVertexRegionOutsideB)
280
- {
281
- // barycentric coordinates (0,1,0)
282
- return SquaredNorm (P - B);
283
- }
284
-
285
- // Check if P in edge region of AB, if so return projection of P onto AB
286
- GpuScalar const vc = d1 * d4 - d3 * d2;
287
- bool const bIsInEdgeRegionOfAB =
288
- vc <= GpuScalar{0 } and d1 >= GpuScalar{0 } and d3 <= GpuScalar{0 };
289
- if (bIsInEdgeRegionOfAB)
290
- {
291
- GpuScalar const v = d1 / (d1 - d3);
292
- // barycentric coordinates (1-v,v,0)
293
- return SquaredNorm (P - ((GpuScalar{1 } - v) * A + v * B));
294
- }
295
-
296
- // Check if P in vertex region outside C
297
- Vector3 const CP = P - C;
298
- GpuScalar const d5 = Dot (AB, CP);
299
- GpuScalar const d6 = Dot (AC, CP);
300
- bool const bIsInVertexRegionOutsideC = d6 >= GpuScalar{0 } and d5 <= d6;
301
- if (bIsInVertexRegionOutsideC)
302
- {
303
- // barycentric coordinates (0,0,1)
304
- return SquaredNorm (P - C);
305
- }
306
-
307
- // Check if P in edge region of AC, if so return projection of P onto AC
308
- GpuScalar const vb = d5 * d2 - d1 * d6;
309
- bool const bIsInEdgeRegionOfAC =
310
- (vb <= GpuScalar{0 } and d2 >= GpuScalar{0 } and d6 <= GpuScalar{0 });
311
- if (bIsInEdgeRegionOfAC)
312
- {
313
- GpuScalar const w = d2 / (d2 - d6);
314
- // barycentric coordinates (1-w,0,w)
315
- return SquaredNorm (P - (GpuScalar{1 } - w) * A + w * C);
316
- }
317
- // Check if P in edge region of BC, if so return projection of P onto BC
318
- GpuScalar const va = d3 * d6 - d5 * d4;
319
- bool const bIsInEdgeRegionOfBC =
320
- va <= GpuScalar{0 } and (d4 - d3) >= GpuScalar{0 } and (d5 - d6) >= GpuScalar{0 };
321
- if (bIsInEdgeRegionOfBC)
322
- {
323
- GpuScalar const w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
324
- // barycentric coordinates (0,1-w,w)
325
- return SquaredNorm (P - ((GpuScalar{1 } - w) * B + w * C));
326
- }
327
- // P inside face region. Compute Q through its barycentric coordinates (u,v,w)
328
- GpuScalar const denom = GpuScalar{1 } / (va + vb + vc);
329
- SMatrix<GpuScalar, 3 > uvw;
330
- uvw (1 ) = vb * denom;
331
- uvw (2 ) = vc * denom;
332
- uvw (0 ) = GpuScalar{1 } - uvw (1 ) - uvw (2 );
333
- return SquaredNorm (P - ABC * uvw);
216
+ using namespace mini ;
217
+ auto A = FromBuffers<3 , 1 >(x, targetInds[0 ][s]);
218
+ auto B = FromBuffers<3 , 1 >(x, targetInds[1 ][s]);
219
+ auto C = FromBuffers<3 , 1 >(x, targetInds[2 ][s]);
220
+ using pbat::geometry::DistanceQueries::PointTriangle;
221
+ return PointTriangle (P, A, B, C);
334
222
}
335
223
336
224
struct BoxOrSimplex
@@ -342,14 +230,19 @@ struct FContactPairs
342
230
struct BranchAndBound
343
231
{
344
232
PBAT_DEVICE
345
- BranchAndBound (Vector3 const & X, GpuScalar R, GpuScalar dzero, GpuIndex sv, GpuIndex v)
233
+ BranchAndBound (
234
+ mini::SVector<GpuScalar, 3 > const & X,
235
+ GpuScalar R,
236
+ GpuScalar dzero,
237
+ GpuIndex sv,
238
+ GpuIndex v)
346
239
: stack{}, nearest{}, X(X), R(R), dzero(dzero), sv(sv), v(v)
347
240
{
348
241
}
349
242
350
243
common::Stack<BoxOrSimplex, 64 > stack;
351
244
common::Queue<GpuIndex, 8 > nearest;
352
- Vector3 X;
245
+ mini::SVector<GpuScalar, 3 > X;
353
246
GpuScalar R;
354
247
GpuScalar dzero;
355
248
GpuIndex sv;
@@ -396,10 +289,14 @@ struct FContactPairs
396
289
397
290
PBAT_DEVICE void operator ()(OverlapType const & o)
398
291
{
292
+ using namespace mini ;
399
293
// Branch and bound over BVH
400
294
GpuIndex const v = queryInds[0 ][o.first ];
401
- BranchAndBound traversal{Position (v), R, dzero, o.first , v};
402
- Push (traversal, 0 , MinDistance (traversal.X , Lower (0 ), Upper (0 )));
295
+ BranchAndBound traversal{FromBuffers<3 , 1 >(x, v), R, dzero, o.first , v};
296
+ Push (
297
+ traversal,
298
+ 0 ,
299
+ MinDistance (traversal.X , FromBuffers<3 , 1 >(b, 0 ), FromBuffers<3 , 1 >(e, 0 )));
403
300
do
404
301
{
405
302
assert (not traversal.stack .IsFull ());
@@ -410,10 +307,10 @@ struct FContactPairs
410
307
GpuIndex const lc = child[0 ][bos.node ];
411
308
GpuIndex const rc = child[1 ][bos.node ];
412
309
413
- Vector3 const LL = Lower ( lc);
414
- Vector3 const LU = Upper ( lc);
415
- Vector3 const RL = Lower ( rc);
416
- Vector3 const RU = Upper ( rc);
310
+ mini::SVector<GpuScalar, 3 > const LL = FromBuffers< 3 , 1 >(b, lc);
311
+ mini::SVector<GpuScalar, 3 > const LU = FromBuffers< 3 , 1 >(e, lc);
312
+ mini::SVector<GpuScalar, 3 > const RL = FromBuffers< 3 , 1 >(b, rc);
313
+ mini::SVector<GpuScalar, 3 > const RU = FromBuffers< 3 , 1 >(e, rc);
417
314
418
315
GpuScalar Ldmin = MinDistance (traversal.X , LL, LU);
419
316
GpuScalar Rdmin = MinDistance (traversal.X , RL, RU);
0 commit comments