PeriDyno 1.0.0
Loading...
Searching...
No Matches
NeighborElementQuery.cu
Go to the documentation of this file.
1#include "NeighborElementQuery.h"
2#include "CollisionDetectionAlgorithm.h"
3
4#include "Collision/CollisionDetectionBroadPhase.h"
5
6#include "Primitive/Primitive3D.h"
7
8#include "Timer.h"
9
10namespace dyno
11{
12 IMPLEMENT_TCLASS(NeighborElementQuery, TDataType)
13
14 struct ContactId
15 {
16 int bodyId1 = INVLIDA_ID;
17 int bodyId2 = INVLIDA_ID;
18 };
19
20 template<typename TDataType>
21 NeighborElementQuery<TDataType>::NeighborElementQuery()
22 : ComputeModule()
23 {
24 this->inCollisionMask()->tagOptional(true);
25
26 this->inAttribute()->tagOptional(true);
27
28 mBroadPhaseCD = std::make_shared<CollisionDetectionBroadPhase<TDataType>>();
29
30 this->varGridSizeLimit()->attach(
31 std::make_shared<FCallBackFunc>(
32 [=]() {
33 mBroadPhaseCD->varGridSizeLimit()->setValue(this->varGridSizeLimit()->getValue());
34 })
35 );
36
37 this->varSelfCollision()->attach(
38 std::make_shared<FCallBackFunc>(
39 [=]() {
40 mBroadPhaseCD->varSelfCollision()->setValue(this->varSelfCollision()->getValue());
41 })
42 );
43
44 this->varGridSizeLimit()->setValue(Real(0.011));
45 this->varSelfCollision()->setValue(true);
46 }
47
48 template<typename TDataType>
49 NeighborElementQuery<TDataType>::~NeighborElementQuery()
50 {
51 }
52
53 template<typename Real, typename Coord>
54 __global__ void NEQ_SetupAABB(
55 DArray<AABB> boundingBox,
56 DArray<Coord> position,
57 Real radius)
58 {
59 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
60 if (pId >= position.size()) return;
61
62 AABB box;
63 Coord p = position[pId];
64 box.v0 = p - radius;
65 box.v1 = p + radius;
66
67 boundingBox[pId] = box;
68 }
69
70 template<typename Box3D>
71 __global__ void NEQ_SetupAABB(
72 DArray<AABB> boundingBox,
73 DArray<Box3D> boxes,
74 DArray<Sphere3D> spheres,
75 DArray<Tet3D> tets,
76 DArray<Capsule3D> caps,
77 DArray<Triangle3D> tris,
78 ElementOffset elementOffset,
79 Real boundary_expand)
80 {
81 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
82 if (tId >= boundingBox.size()) return;
83
84 ElementType eleType = elementOffset.checkElementType(tId);
85
86 AABB box;
87 switch (eleType)
88 {
89 case ET_SPHERE:
90 {
91 box = spheres[tId].aabb();
92 break;
93 }
94 case ET_BOX:
95 {
96 box = boxes[tId - elementOffset.boxIndex()].aabb();
97 break;
98 }
99 case ET_TET:
100 {
101 box = tets[tId - elementOffset.tetIndex()].aabb();
102 break;
103 }
104 case ET_CAPSULE:
105 {
106 box = caps[tId - elementOffset.capsuleIndex()].aabb();
107 break;
108 }
109 case ET_TRI:
110 {
111 boundary_expand = 0.01;
112 box = tris[tId - elementOffset.triangleIndex()].aabb();
113 break;
114 }
115 default:
116 break;
117 }
118
119 box.v0 -= boundary_expand;
120 box.v1 += boundary_expand;
121
122 boundingBox[tId] = box;
123 }
124
125 __device__ inline bool checkCollision(CollisionMask cType0, CollisionMask cType1, ElementType eleType0, ElementType eleType1)
126 {
127 bool canCollide = (cType0 & eleType1) != 0 && (cType1 & eleType0) > 0;
128 if (!canCollide)
129 return false;
130
131 return true;
132 }
133
134 template<typename Box3D, typename ContactPair>
135 __global__ void NEQ_Narrow_Count(
136 DArray<int> count,
137 DArray<ContactPair> nbr_cons,
138 DArray<ContactId> nbr,
139 DArray<CollisionMask> mask,
140 DArray<Box3D> boxes,
141 DArray<Sphere3D> spheres,
142 DArray<Tet3D> tets,
143 DArray<Real> tets_sdf,
144 DArray<int> tet_body_ids,
145 DArray<TopologyModule::Tetrahedron> tet_element_ids,
146 DArray<Capsule3D> caps,
147 DArray<Triangle3D> triangles,
148 DArray<Attribute> attribute,
149 DArray<Pair<uint, uint>> shape2RigidBodyMapping,
150 ElementOffset elementOffset,
151 Real dHat,
152 bool enableSelfCollision,
153 bool enableCollisionMask)
154 {
155 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
156 if (tId >= nbr.size()) return;
157
158 ContactId ids = nbr[tId];
159 ElementType eleType_i = elementOffset.checkElementType(ids.bodyId1);
160 ElementType eleType_j = elementOffset.checkElementType(ids.bodyId2);
161
162 TManifold<Real> manifold;
163
164 // Convert primitive id into rigid body id
165 int mappedId1 = ids.bodyId1 == INVALID ? ids.bodyId1 : shape2RigidBodyMapping[ids.bodyId1].second;
166 int mappedId2 = ids.bodyId2 == INVALID ? ids.bodyId2 : shape2RigidBodyMapping[ids.bodyId2].second;
167
168 // TODO: check whether it is plausible to define collision mask on rigid bodies
169 CollisionMask mask_i = enableCollisionMask ? mask[mappedId1] : CollisionMask::CT_AllObjects;
170 CollisionMask mask_j = enableCollisionMask ? mask[mappedId2] : CollisionMask::CT_AllObjects;
171
172 // If two primitives belong to the same rigid body, disable collision detection
173 if (mappedId1 == mappedId2)
174 return;
175
176 if (!enableSelfCollision)
177 {
178 Attribute att_i = attribute[mappedId1];
179 Attribute att_j = attribute[mappedId2];
180
181 if (att_i.objectId() == att_j.objectId())
182 return;
183 }
184
185 if (eleType_i == ET_BOX && eleType_j == ET_BOX && checkCollision(mask_i, mask_j, ET_BOX, ET_BOX))
186 {
187 auto boxA = boxes[ids.bodyId1 - elementOffset.boxIndex()];
188 auto boxB = boxes[ids.bodyId2 - elementOffset.boxIndex()];
189
190 boxA.extent += dHat;
191 boxB.extent += dHat;
192
193 CollisionDetection<Real>::request(manifold, boxA, boxB);
194 //CollisionDetection<Real>::request(manifold, boxA, boxB, dHat, dHat);
195 //printf("Box - Box dHat:%f\n", dHat);
196 //printf("Collision: %d\n", manifold.contactCount);
197 //for (int i = 0; i < manifold.contactCount; i++)
198 //{
199 // printf("dep: %f\n", manifold.contacts[i].penetration);
200 //}
201 }
202 else if (eleType_i == ET_SPHERE && eleType_j == ET_BOX && checkCollision(mask_i, mask_j, ET_SPHERE, ET_BOX))
203 {
204 auto sphere = spheres[ids.bodyId1];
205 auto box = boxes[ids.bodyId2 - elementOffset.boxIndex()];
206
207 //sphere.radius += dHat;
208 //box.extent += dHat;
209 //CollisionDetection<Real>::request(manifold, sphere, box);
210 CollisionDetection<Real>::request(manifold, sphere, box, dHat, dHat);
211
212 //printf("SPhere - Box dHat:%f\n", dHat);
213 //printf("Collision: %d\n", manifold.contactCount);
214 //for (int i = 0; i < manifold.contactCount; i++)
215 //{
216 // printf("dep: %f\n", manifold.contacts[i].penetration);
217 //}
218 }
219 else if (eleType_i == ET_BOX && eleType_j == ET_SPHERE && checkCollision(mask_i, mask_j, ET_BOX, ET_SPHERE))
220 {
221 auto box = boxes[ids.bodyId1 - elementOffset.boxIndex()];
222 auto sphere = spheres[ids.bodyId2];
223
224 //box.extent += dHat;
225 //sphere.radius += dHat;
226 //CollisionDetection<Real>::request(manifold, box, sphere);
227 CollisionDetection<Real>::request(manifold, box, sphere, dHat, dHat);
228
229 //printf("Box - SPhere dHat:%f\n", dHat);
230 //printf("Collision: %d\n", manifold.contactCount);
231 //for (int i = 0; i < manifold.contactCount; i++)
232 //{
233 // printf("dep: %f\n", manifold.contacts[i].penetration);
234 //}
235 }
236 else if (eleType_i == ET_SPHERE && eleType_j == ET_SPHERE && checkCollision(mask_i, mask_j, ET_SPHERE, ET_SPHERE))
237 {
238 auto sphereA = spheres[ids.bodyId1];
239 auto sphereB = spheres[ids.bodyId2];
240
241 sphereA.radius += dHat;
242 sphereB.radius += dHat;
243
244 //CollisionDetection<Real>::request(manifold, sphereA, sphereB);
245 CollisionDetection<Real>::request(manifold, sphereA, sphereB, dHat, dHat);
246 }
247 else if(eleType_i == ET_TET && eleType_j == ET_TET && checkCollision(mask_i, mask_j, ET_TET, ET_TET))
248 {
249 //TODO: consider dHat
250 auto tetA = tets[ids.bodyId1 - elementOffset.tetIndex()];
251 auto tetB = tets[ids.bodyId2 - elementOffset.tetIndex()];
252 //CollisionDetection<Real>::request(manifold, tetA, tetB);
253
254 CollisionDetection<Real>::request(manifold, tetA, tetB, dHat, dHat);
255 }
256 else if (eleType_i == ET_TET && eleType_j == ET_BOX && checkCollision(mask_i, mask_j, ET_TET, ET_BOX))
257 {
258 //TODO: consider dHat
259 auto tetA = tets[ids.bodyId1 - elementOffset.tetIndex()];
260 auto boxB = boxes[ids.bodyId2 - elementOffset.boxIndex()];
261 //CollisionDetection<Real>::request(manifold, tetA, boxB);
262
263 CollisionDetection<Real>::request(manifold, tetA, boxB, dHat, dHat);
264 }
265 else if (eleType_i == ET_BOX && eleType_j == ET_TET && checkCollision(mask_i, mask_j, ET_BOX, ET_TET))
266 {
267 //TODO: consider dHat
268 auto boxA = boxes[ids.bodyId1 - elementOffset.boxIndex()];
269 auto tetB = tets[ids.bodyId2 - elementOffset.tetIndex()];
270 //CollisionDetection<Real>::request(manifold, boxA, tetB);
271
272 CollisionDetection<Real>::request(manifold, boxA, tetB, dHat, dHat);
273 }
274 else if (eleType_i == ET_SPHERE && eleType_j == ET_TET && checkCollision(mask_i, mask_j, ET_SPHERE, ET_TET))
275 {
276 //TODO: consider dHat
277 auto sphere = spheres[ids.bodyId1];
278 auto tet = tets[ids.bodyId2 - elementOffset.tetIndex()];
279 //CollisionDetection<Real>::request(manifold, sphere, tet);
280
281 CollisionDetection<Real>::request(manifold, sphere, tet, dHat, dHat);
282 }
283 else if (eleType_i == ET_TET && eleType_j == ET_SPHERE && checkCollision(mask_i, mask_j, ET_TET, ET_SPHERE))
284 {
285 //TODO: consider dHat
286 auto tet = tets[ids.bodyId1 - elementOffset.tetIndex()];
287 auto sphere = spheres[ids.bodyId2];
288 //CollisionDetection<Real>::request(manifold, tet, sphere);
289
290 CollisionDetection<Real>::request(manifold, tet, sphere, dHat, dHat);
291 }
292 else if (eleType_i == ET_TRI && eleType_j == ET_SPHERE && checkCollision(mask_i, mask_j, ET_TRI, ET_SPHERE))
293 {
294 //TODO: consider dHat
295 auto tri = triangles[ids.bodyId1 - elementOffset.triangleIndex()];
296 auto sphere = spheres[ids.bodyId2];
297 sphere.radius += 0.01f;
298 //CollisionDetection<Real>::request(manifold, sphere, tri);
299
300 CollisionDetection<Real>::request(manifold, sphere, tri, dHat, dHat);
301 }
302 else if (eleType_i == ET_SPHERE && eleType_j == ET_TRI && checkCollision(mask_i, mask_j, ET_SPHERE, ET_TRI))
303 {
304 //TODO: consider dHat
305 auto tri = triangles[ids.bodyId2 - elementOffset.triangleIndex()];
306 auto sphere = spheres[ids.bodyId1];
307 sphere.radius += 0.01f;
308 //CollisionDetection<Real>::request(manifold, sphere, tri);
309
310 CollisionDetection<Real>::request(manifold, sphere, tri, dHat, dHat);
311 }
312 else if (eleType_i == ET_TET && eleType_j == ET_TRI && checkCollision(mask_i, mask_j, ET_TET, ET_TRI))
313 {
314 //TODO: consider dHat
315 auto tri = triangles[ids.bodyId2 - elementOffset.triangleIndex()];
316 auto tet = tets[ids.bodyId1 - elementOffset.tetIndex()];
317 //CollisionDetection<Real>::request(manifold, tet, tri);
318
319 CollisionDetection<Real>::request(manifold, tet, tri, dHat, dHat);
320 }
321 else if (eleType_i == ET_TRI && eleType_j == ET_TET && checkCollision(mask_i, mask_j, ET_TRI, ET_TET))
322 {
323 //TODO: consider dHat
324 auto tri = triangles[ids.bodyId1 - elementOffset.triangleIndex()];
325 auto tet = tets[ids.bodyId2 - elementOffset.tetIndex()];
326 //CollisionDetection<Real>::request(manifold, tri, tet);
327
328 CollisionDetection<Real>::request(manifold, tri, tet, dHat, dHat);
329
330 }
331 //Capsule with other primitives
332 else if (eleType_i == ET_TET && eleType_j == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_TET, ET_CAPSULE)) //tet-capsule
333 {
334 //TODO: consider dHat
335 auto cap = caps[ids.bodyId2 - elementOffset.capsuleIndex()];
336 auto tet = tets[ids.bodyId1 - elementOffset.tetIndex()];
337 //CollisionDetection<Real>::request(manifold, tet, cap);
338
339 Segment3D seg = cap.centerline();
340 Real radius = cap.radius;
341 CollisionDetection<Real>::request(manifold, tet, seg, dHat, radius + dHat);
342 }
343 else if (eleType_j == ET_TET && eleType_i == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_CAPSULE, ET_TET))
344 {
345 //TODO: consider dHat
346 auto cap = caps[ids.bodyId1 - elementOffset.capsuleIndex()];
347 auto tet = tets[ids.bodyId2 - elementOffset.tetIndex()];
348 //CollisionDetection<Real>::request(manifold, cap, tet);
349
350 Segment3D seg = cap.centerline();
351 Real radius = cap.radius;
352 CollisionDetection<Real>::request(manifold, seg, tet, radius + dHat, dHat);
353 }
354 else if (eleType_i == ET_CAPSULE && eleType_j == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_CAPSULE, ET_CAPSULE)) //capsule-capsule
355 {
356 auto cap1 = caps[ids.bodyId1 - elementOffset.capsuleIndex()];
357 auto cap2 = caps[ids.bodyId2 - elementOffset.capsuleIndex()];
358
359 //cap1.radius += dHat;
360 //cap2.radius += dHat;
361 //CollisionDetection<Real>::request(manifold, cap1, cap2);
362
363 Segment3D seg1 = cap1.centerline(); Real radius1 = cap1.radius;
364 Segment3D seg2 = cap2.centerline(); Real radius2 = cap2.radius;
365 CollisionDetection<Real>::request(manifold, seg1, seg2, radius1 + dHat, radius2 + dHat);
366
367 }
368 else if (eleType_i == ET_BOX && eleType_j == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_BOX, ET_CAPSULE)) //box-capsule
369 {
370 auto cap = caps[ids.bodyId2 - elementOffset.capsuleIndex()];
371 auto box = boxes[ids.bodyId1 - elementOffset.boxIndex()];
372
373 //cap.radius += dHat;
374 //box.extent += dHat;
375 //CollisionDetection<Real>::request(manifold, box, cap);
376
377 Segment3D seg = cap.centerline();
378 Real radius = cap.radius;
379 CollisionDetection<Real>::request(manifold, box, seg, dHat, radius + dHat);
380 }
381 else if (eleType_j == ET_BOX && eleType_i == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_CAPSULE, ET_BOX))
382 {
383 auto cap = caps[ids.bodyId1 - elementOffset.capsuleIndex()];
384 auto box = boxes[ids.bodyId2 - elementOffset.boxIndex()];
385
386 //cap.radius += dHat;
387 //box.extent += dHat;
388 //CollisionDetection<Real>::request(manifold, cap, box);
389
390 Segment3D seg = cap.centerline();
391 Real radius = cap.radius;
392 CollisionDetection<Real>::request(manifold, seg, box, radius + dHat, dHat);
393 }
394 else if (eleType_i == ET_SPHERE && eleType_j == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_SPHERE, ET_CAPSULE)) //sphere-capsule
395 {
396 auto cap = caps[ids.bodyId2 - elementOffset.capsuleIndex()];
397 auto sphere = spheres[ids.bodyId1 - elementOffset.sphereIndex()];
398
399 //cap.radius += dHat;
400 //sphere.radius += dHat;
401 //CollisionDetection<Real>::request(manifold, sphere, cap);
402
403 Segment3D seg = cap.centerline();
404 Real radius = cap.radius;
405 CollisionDetection<Real>::request(manifold, sphere, seg, dHat, radius + dHat);
406
407 }
408 else if (eleType_j == ET_SPHERE && eleType_i == ET_CAPSULE && checkCollision(mask_i, mask_j, ET_CAPSULE, ET_SPHERE))
409 {
410 auto cap = caps[ids.bodyId1 - elementOffset.capsuleIndex()];
411 auto sphere = spheres[ids.bodyId2 - elementOffset.sphereIndex()];
412
413 //cap.radius += dHat;
414 //sphere.radius += dHat;
415 //CollisionDetection<Real>::request(manifold, cap, sphere);
416
417 Segment3D seg = cap.centerline();
418 Real radius = cap.radius;
419 CollisionDetection<Real>::request(manifold, seg, sphere, radius + dHat, dHat);
420 }
421
422 count[tId] = manifold.contactCount;
423
424 //printf("%d %d; num: %d \n", mappedId1, mappedId2, manifold.contactCount);
425
426 int offset = 8 * tId;
427 for (int n = 0; n < manifold.contactCount; n++)
428 {
429 ContactPair cp;
430 //cp.pos1 = manifold.contacts[n].position + dHat * manifold.normal;
431 //cp.pos2 = manifold.contacts[n].position + dHat * manifold.normal;
432 cp.pos1 = manifold.contacts[n].position;
433 cp.pos2 = manifold.contacts[n].position;
434 cp.normal1 = -manifold.normal;
435 cp.normal2 = manifold.normal;
436 cp.bodyId1 = mappedId1;
437 cp.bodyId2 = mappedId2;
438 cp.contactType = ContactType::CT_NONPENETRATION;
439 //cp.interpenetration = -manifold.contacts[n].penetration - 2 * dHat;
440 cp.interpenetration = -manifold.contacts[n].penetration;
441 nbr_cons[offset + n] = cp;
442 }
443 }
444
445 template<typename ContactPair>
446 __global__ void NEQ_Narrow_Set(
447 DArray<ContactPair> nbr_cons,
448 DArray<ContactPair> nbr_cons_all,
449 DArray<ContactId> nbr,
450 DArray<int> prefix,
451 DArray<int> sum)
452 {
453 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
454 if (tId >= nbr.size()) return;
455
456 ContactId ids = nbr[tId];
457
458 int offset = prefix[tId];
459 int size = sum[tId];
460 for (int n = 0; n < size; n++)
461 {
462 nbr_cons[offset + n] = nbr_cons_all[8 * tId + n];
463 }
464 }
465
466 __global__ void CCL_CountListSize(
467 DArray<int> num,
468 DArrayList<int> contactList)
469 {
470 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
471 if (tId >= contactList.size()) return;
472
473 num[tId] = contactList[tId].size();
474 }
475
476 __global__ void CCL_SetupContactIds(
477 DArray<ContactId> ids,
478 DArray<int> index,
479 DArrayList<int> contactList)
480 {
481 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
482 if (tId >= contactList.size()) return;
483
484 int base = index[tId];
485
486 auto& list_i = contactList[tId];
487 for (int j = 0; j < list_i.size(); j++)
488 {
489 ContactId id;
490 id.bodyId1 = tId;
491 id.bodyId2 = list_i[j];
492
493 ids[base + j] = id;
494 }
495 }
496
497 template<typename TDataType>
498 void NeighborElementQuery<TDataType>::compute()
499 {
500 auto inTopo = this->inDiscreteElements()->getDataPtr();
501
502 if (this->outContacts()->isEmpty())
503 this->outContacts()->allocate();
504
505 this->outContacts()->clear();
506
507 int t_num = inTopo->totalSize();
508
509 if (t_num == 0)
510 {
511 auto& contacts = this->outContacts()->getData();
512 contacts.resize(0);
513 return;
514 }
515
516 if (mQueriedAABB.size() != t_num){
517 mQueriedAABB.resize(t_num);
518 }
519
520 if (mQueryAABB.size() != t_num){
521 mQueryAABB.resize(t_num);
522 }
523 //printf("=========== ============= INSIDE SELF COLLISION %d\n", t_num);
524 ElementOffset elementOffset = inTopo->calculateElementOffset();
525
526 Real dHat = this->varDHead()->getValue();
527
528 auto& position = inTopo->position();
529 auto& rotation = inTopo->rotation();
530
531 DArray<Box3D>& boxInGlobal = inTopo->boxesInGlobal();
532 DArray<Sphere3D>& sphereInGlobal = inTopo->spheresInGlobal();
533 DArray<Tet3D>& tetInGlobal = inTopo->tetsInGlobal();
534 DArray<Capsule3D>& capsuleInGlobal = inTopo->capsulesInGlobal();
535 DArray<Triangle3D>& triangleInGlobal = inTopo->trianglesInGlobal();
536
537 cuExecute(t_num,
538 NEQ_SetupAABB,
539 mQueriedAABB,
540 boxInGlobal,
541 sphereInGlobal,
542 tetInGlobal,
543 capsuleInGlobal,
544 triangleInGlobal,
545 elementOffset,
546 dHat);
547
548 mQueryAABB.assign(mQueriedAABB);
549
550 mBroadPhaseCD->inSource()->assign(mQueryAABB);
551 mBroadPhaseCD->inTarget()->assign(mQueriedAABB);
552 //
553 mBroadPhaseCD->update();
554
555 auto& contactList = mBroadPhaseCD->outContactList()->getData();
556 if (contactList.elementSize() == 0) {
557 return;
558 }
559
560 DArray<int> count(contactList.size());
561 cuExecute(contactList.size(),
562 CCL_CountListSize,
563 count,
564 contactList);
565
566 int totalSize = mReduce.accumulate(count.begin(), count.size());
567
568 if (totalSize <= 0) {
569 this->outContacts()->clear();
570 return;
571 }
572
573 mScan.exclusive(count);
574
575 DArray<ContactId> deviceIds(totalSize);
576
577 cuExecute(contactList.size(),
578 CCL_SetupContactIds,
579 deviceIds,
580 count,
581 contactList);
582
583 count.clear();
584
585 Real zero = 0;
586
587 DArray<int> contactNum;
588 DArray<int> contactNumCpy;
589
590 contactNum.resize(deviceIds.size());
591 contactNum.reset();
592 contactNumCpy.resize(deviceIds.size());
593 contactNumCpy.reset();
594
595 DArray<TContactPair<Real>> nbr_cons_tmp;
596 nbr_cons_tmp.resize(deviceIds.size() * 8);
597 nbr_cons_tmp.reset();
598
599 if (this->inCollisionMask()->isEmpty())
600 {
601 DArray<CollisionMask> dummyCollisionMask;
602 if (!this->varSelfCollision()->getValue() && !this->inAttribute()->isEmpty())
603 {
604 cuExecute(deviceIds.size(),
605 NEQ_Narrow_Count,
606 contactNum,
607 nbr_cons_tmp,
608 deviceIds,
609 dummyCollisionMask,
610 boxInGlobal,
611 sphereInGlobal,
612 tetInGlobal,
613 inTopo->getTetSDF(),
614 inTopo->getTetBodyMapping(),
615 inTopo->getTetElementMapping(),
616 capsuleInGlobal,
617 triangleInGlobal,
618 this->inAttribute()->getData(),
619 inTopo->shape2RigidBodyMapping(),
620 elementOffset,
621 dHat,
622 false,
623 false);
624 }
625 else
626 {
627 DArray<Attribute> dummyAttribute;
628 cuExecute(deviceIds.size(),
629 NEQ_Narrow_Count,
630 contactNum,
631 nbr_cons_tmp,
632 deviceIds,
633 dummyCollisionMask,
634 boxInGlobal,
635 sphereInGlobal,
636 tetInGlobal,
637 inTopo->getTetSDF(),
638 inTopo->getTetBodyMapping(),
639 inTopo->getTetElementMapping(),
640 capsuleInGlobal,
641 triangleInGlobal,
642 dummyAttribute,
643 inTopo->shape2RigidBodyMapping(),
644 elementOffset,
645 dHat,
646 true,
647 false);
648 }
649
650 }
651 else
652 {
653 if (!this->varSelfCollision()->getValue() && !this->inAttribute()->isEmpty())
654 {
655 cuExecute(deviceIds.size(),
656 NEQ_Narrow_Count,
657 contactNum,
658 nbr_cons_tmp,
659 deviceIds,
660 this->inCollisionMask()->getData(),
661 boxInGlobal,
662 sphereInGlobal,
663 tetInGlobal,
664 inTopo->getTetSDF(),
665 inTopo->getTetBodyMapping(),
666 inTopo->getTetElementMapping(),
667 capsuleInGlobal,
668 triangleInGlobal,
669 this->inAttribute()->getData(),
670 inTopo->shape2RigidBodyMapping(),
671 elementOffset,
672 dHat,
673 false,
674 true);
675 }
676 else
677 {
678 DArray<Attribute> dummyAttribute;
679 cuExecute(deviceIds.size(),
680 NEQ_Narrow_Count,
681 contactNum,
682 nbr_cons_tmp,
683 deviceIds,
684 this->inCollisionMask()->getData(),
685 boxInGlobal,
686 sphereInGlobal,
687 tetInGlobal,
688 inTopo->getTetSDF(),
689 inTopo->getTetBodyMapping(),
690 inTopo->getTetElementMapping(),
691 capsuleInGlobal,
692 triangleInGlobal,
693 dummyAttribute,
694 inTopo->shape2RigidBodyMapping(),
695 elementOffset,
696 dHat,
697 true,
698 true);
699 }
700 }
701
702 contactNumCpy.assign(contactNum);
703
704 int sum = mReduce.accumulate(contactNum.begin(), contactNum.size());
705
706 auto& contacts = this->outContacts()->getData();
707 mScan.exclusive(contactNum, true);
708 contacts.resize(sum);
709 contacts.reset();
710 if (sum > 0)
711 {
712 cuExecute(deviceIds.size(),
713 NEQ_Narrow_Set,
714 contacts,
715 nbr_cons_tmp,
716 deviceIds,
717 contactNum,
718 contactNumCpy);
719 }
720
721 contactNumCpy.clear();
722 contactNum.clear();
723 deviceIds.clear();
724 nbr_cons_tmp.clear();
725 }
726
727 DEFINE_CLASS(NeighborElementQuery);
728}