PeriDyno 1.0.0
Loading...
Searching...
No Matches
CollistionDetectionBoundingBox.cu
Go to the documentation of this file.
1#include "CollistionDetectionBoundingBox.h"
2
3#include "Primitive/Primitive3D.h"
4#include "Topology/DiscreteElements.h"
5
6namespace dyno
7{
8 typedef typename ::dyno::TOrientedBox3D<Real> Box3D;
9
10 template<typename TDataType>
11 CollistionDetectionBoundingBox<TDataType>::CollistionDetectionBoundingBox()
12 : ComputeModule()
13 {
14 }
15
16 template<typename TDataType>
17 CollistionDetectionBoundingBox<TDataType>::~CollistionDetectionBoundingBox()
18 {
19
20 }
21
22 template <typename Coord>
23 __global__ void CountContactsWithBoundary(
24 DArray<Sphere3D> sphere,
25 DArray<Box3D> box,
26 DArray<Tet3D> tet,
27 DArray<Capsule3D> cap,
28 DArray<int> count,
29 Coord hi,
30 Coord lo,
31 ElementOffset elementOffset)
32 {
33 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
34 if (pId >= count.size()) return;
35
36 ElementType eleType = elementOffset.checkElementType(pId);
37
38 if (eleType == ET_SPHERE)//sphere
39 {
40 int cnt = 0;
41
42 Sphere3D sp = sphere[pId - elementOffset.sphereIndex()];
43
44 Real radius = sp.radius;
45 Coord center = sp.center;
46
47 if (center.x + radius >= hi.x)
48 {
49 cnt++;
50 }
51 if (center.x - radius <= lo.x)
52 {
53 cnt++;
54 }
55
56 if (center.y + radius >= hi.y)
57 {
58 cnt++;
59 }
60 if (center.y - radius <= lo.y)
61 {
62 cnt++;
63 }
64
65 if (center.z + radius >= hi.z)
66 {
67 cnt++;
68 }
69 if (center.z - radius <= lo.z)
70 {
71 cnt++;
72 }
73
74 count[pId] = cnt;
75 }
76 else if (eleType == ET_BOX)//box
77 {
78 //int idx = pId - start_box;
79 int cnt = 0;
80 // int start_i;
81 Coord center = box[pId - elementOffset.boxIndex()].center;
82 Coord u = box[pId - elementOffset.boxIndex()].u;
83 Coord v = box[pId - elementOffset.boxIndex()].v;
84 Coord w = box[pId - elementOffset.boxIndex()].w;
85 Coord extent = box[pId - elementOffset.boxIndex()].extent;
86 Point3D p[8];
87 p[0] = Point3D(center - u * extent[0] - v * extent[1] - w * extent[2]);
88 p[1] = Point3D(center - u * extent[0] - v * extent[1] + w * extent[2]);
89 p[2] = Point3D(center - u * extent[0] + v * extent[1] - w * extent[2]);
90 p[3] = Point3D(center - u * extent[0] + v * extent[1] + w * extent[2]);
91 p[4] = Point3D(center + u * extent[0] - v * extent[1] - w * extent[2]);
92 p[5] = Point3D(center + u * extent[0] - v * extent[1] + w * extent[2]);
93 p[6] = Point3D(center + u * extent[0] + v * extent[1] - w * extent[2]);
94 p[7] = Point3D(center + u * extent[0] + v * extent[1] + w * extent[2]);
95 bool c1, c2, c3, c4, c5, c6;
96 c1 = c2 = c3 = c4 = c5 = c6 = true;
97 for (int i = 0; i < 8; i++)
98 {
99 Coord pos = p[i].origin;
100 if (pos[0] > hi[0] && c1)
101 {
102 c1 = true;
103 cnt++;
104 }
105 if (pos[1] > hi[1] && c2)
106 {
107 c2 = true;
108 cnt++;
109 }
110 if (pos[2] > hi[2] && c3)
111 {
112 c3 = true;
113 cnt++;
114 }
115 if (pos[0] < lo[0] && c4)
116 {
117 c4 = true;
118 cnt++;
119 }
120 if (pos[1] < lo[1] && c5)
121 {
122 c5 = true;
123 cnt++;
124 }
125 if (pos[2] < lo[2] && c6)
126 {
127 c6 = true;
128 cnt++;
129 }
130 }
131 count[pId] = cnt;
132 }
133 else if (eleType == ET_TET) // tets
134 {
135 int cnt = 0;
136 int start_i = count[pId];
137
138 Tet3D tet_i = tet[pId - elementOffset.tetIndex()];
139
140 for (int i = 0; i < 4; i++)
141 {
142 Coord vertex = tet_i.v[i];
143 if (vertex.x >= hi.x)
144 {
145 cnt++;
146 }
147 if (vertex.x <= lo.x)
148 {
149 cnt++;
150 }
151
152 if (vertex.y >= hi.y)
153 {
154 cnt++;
155 }
156 if (vertex.y <= lo.y)
157 {
158 cnt++;
159 }
160
161 if (vertex.z >= hi.z)
162 {
163 cnt++;
164 }
165 if (vertex.z <= lo.z)
166 {
167 cnt++;
168 }
169 }
170
171 count[pId] = cnt;
172 }
173 else if (eleType == ET_CAPSULE)//segments
174 {
175 int cnt = 0;
176
177 Capsule3D cap_i = cap[pId - elementOffset.capsuleIndex()];
178
179 Coord v0 = cap_i.startPoint();
180 Coord v1 = cap_i.endPoint();
181
182 Real radius = cap_i.radius;
183
184 if (v0.x + radius >= hi.x)
185 {
186 cnt++;
187 }
188 if (v0.x - radius <= lo.x)
189 {
190 cnt++;
191 }
192
193 if (v0.y + radius >= hi.y)
194 {
195 cnt++;
196 }
197 if (v0.y - radius <= lo.y)
198 {
199 cnt++;
200 }
201
202 if (v0.z + radius >= hi.z)
203 {
204 cnt++;
205 }
206 if (v0.z - radius <= lo.z)
207 {
208 cnt++;
209 }
210
211
212 //v1
213 if (v1.x + radius >= hi.x)
214 {
215 cnt++;
216 }
217 if (v1.x - radius <= lo.x)
218 {
219 cnt++;
220 }
221
222 if (v1.y + radius >= hi.y)
223 {
224 cnt++;
225 }
226 if (v1.y - radius <= lo.y)
227 {
228 cnt++;
229 }
230
231 if (v1.z + radius >= hi.z)
232 {
233 cnt++;
234 }
235 if (v1.z - radius <= lo.z)
236 {
237 cnt++;
238 }
239
240 count[pId] = cnt;
241 }
242 }
243
244 template <typename Coord, typename ContactPair>
245 __global__ void SetupContactsWithBoundary(
246 DArray<Sphere3D> sphere,
247 DArray<Box3D> box,
248 DArray<Tet3D> tet,
249 DArray<Capsule3D> cap,
250 DArray<int> count,
251 DArray<ContactPair> nbq,
252 DArray<Pair<uint, uint>> mapping,
253 Coord hi,
254 Coord lo,
255 ElementOffset elementOffset)
256 {
257 int pId = threadIdx.x + (blockIdx.x * blockDim.x);
258 if (pId >= count.size()) return;
259
260 ElementType eleType = elementOffset.checkElementType(pId);
261
262 uint rbId = mapping[pId].second;
263
264 if (eleType == ET_SPHERE)//sphere
265 {
266 int cnt = 0;
267 int start_i = count[pId];
268
269 Sphere3D sp = sphere[pId - elementOffset.sphereIndex()];
270
271 Real radius = sp.radius;
272 Coord center = sp.center;
273
274 if (center.x + radius >= hi.x)
275 {
276 nbq[cnt + start_i].bodyId1 = rbId;
277 nbq[cnt + start_i].bodyId2 = -1;
278 nbq[cnt + start_i].normal1 = Coord(-1, 0, 0);
279 nbq[cnt + start_i].pos1 = center + Coord(radius, 0, 0);
280 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
281 nbq[cnt + start_i].interpenetration = center.x + radius - hi.x;
282 cnt++;
283 }
284 if (center.x - radius <= lo.x)
285 {
286 nbq[cnt + start_i].bodyId1 = rbId;
287 nbq[cnt + start_i].bodyId2 = -1;
288 nbq[cnt + start_i].normal1 = Coord(1, 0, 0);
289 nbq[cnt + start_i].pos1 = center - Coord(radius, 0, 0);
290 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
291 nbq[cnt + start_i].interpenetration = lo.x - (center.x - radius);
292 cnt++;
293 }
294
295 if (center.y + radius >= hi.y)
296 {
297 nbq[cnt + start_i].bodyId1 = rbId;
298 nbq[cnt + start_i].bodyId2 = -1;
299 nbq[cnt + start_i].normal1 = Coord(0, -1, 0);
300 nbq[cnt + start_i].pos1 = center + Coord(0, radius, 0);
301 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
302 nbq[cnt + start_i].interpenetration = center.y + radius - hi.y;
303 cnt++;
304 }
305 if (center.y - radius <= lo.y)
306 {
307 nbq[cnt + start_i].bodyId1 = rbId;
308 nbq[cnt + start_i].bodyId2 = -1;
309 nbq[cnt + start_i].normal1 = Coord(0, 1, 0);
310 nbq[cnt + start_i].pos1 = center - Coord(0, radius, 0);
311 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
312 nbq[cnt + start_i].interpenetration = lo.y - (center.y - radius);
313 cnt++;
314 }
315
316 if (center.z + radius >= hi.z)
317 {
318 nbq[cnt + start_i].bodyId1 = rbId;
319 nbq[cnt + start_i].bodyId2 = -1;
320 nbq[cnt + start_i].normal1 = Coord(0, 0, -1);
321 nbq[cnt + start_i].pos1 = center + Coord(0, 0, radius);
322 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
323 nbq[cnt + start_i].interpenetration = center.z + radius - hi.z;
324 cnt++;
325 }
326 if (center.z - radius <= lo.z)
327 {
328 nbq[cnt + start_i].bodyId1 = rbId;
329 nbq[cnt + start_i].bodyId2 = -1;
330 nbq[cnt + start_i].normal1 = Coord(0, 0, 1);
331 nbq[cnt + start_i].pos1 = center - Coord(0, 0, radius);
332 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
333 nbq[cnt + start_i].interpenetration = lo.z - (center.z - radius);
334 cnt++;
335 }
336 }
337 else if (eleType == ET_BOX)//box
338 {
339 //int idx = pId - start_box;
340 int cnt = 0;
341 int start_i = count[pId];
342 Coord center = box[pId - elementOffset.boxIndex()].center;
343 Coord u = box[pId - elementOffset.boxIndex()].u;
344 Coord v = box[pId - elementOffset.boxIndex()].v;
345 Coord w = box[pId - elementOffset.boxIndex()].w;
346 Coord extent = box[pId - elementOffset.boxIndex()].extent;
347 Point3D p[8];
348 p[0] = Point3D(center - u * extent[0] - v * extent[1] - w * extent[2]);
349 p[1] = Point3D(center - u * extent[0] - v * extent[1] + w * extent[2]);
350 p[2] = Point3D(center - u * extent[0] + v * extent[1] - w * extent[2]);
351 p[3] = Point3D(center - u * extent[0] + v * extent[1] + w * extent[2]);
352 p[4] = Point3D(center + u * extent[0] - v * extent[1] - w * extent[2]);
353 p[5] = Point3D(center + u * extent[0] - v * extent[1] + w * extent[2]);
354 p[6] = Point3D(center + u * extent[0] + v * extent[1] - w * extent[2]);
355 p[7] = Point3D(center + u * extent[0] + v * extent[1] + w * extent[2]);
356 bool c1, c2, c3, c4, c5, c6;
357 c1 = c2 = c3 = c4 = c5 = c6 = true;
358 for (int i = 0; i < 8; i++)
359 {
360 Coord pos = p[i].origin;
361 if (pos[0] > hi[0] && c1)
362 {
363 c1 = true;
364 nbq[cnt + start_i].bodyId1 = rbId;
365 nbq[cnt + start_i].bodyId2 = -1;
366 nbq[cnt + start_i].normal1 = Coord(-1, 0, 0);
367 nbq[cnt + start_i].pos1 = pos;
368 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
369 nbq[cnt + start_i].interpenetration = pos[0] - hi[0];
370 cnt++;
371 }
372 if (pos[1] > hi[1] && c2)
373 {
374 c2 = true;
375 nbq[cnt + start_i].bodyId1 = rbId;
376 nbq[cnt + start_i].bodyId2 = -1;
377 nbq[cnt + start_i].normal1 = Coord(0, -1, 0);
378 nbq[cnt + start_i].pos1 = pos;
379 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
380 nbq[cnt + start_i].interpenetration = pos[1] - hi[1];
381 cnt++;
382 }
383 if (pos[2] > hi[2] && c3)
384 {
385 c3 = true;
386 nbq[cnt + start_i].bodyId1 = rbId;
387 nbq[cnt + start_i].bodyId2 = -1;
388 nbq[cnt + start_i].normal1 = Coord(0, 0, -1);
389 nbq[cnt + start_i].pos1 = pos;
390 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
391 nbq[cnt + start_i].interpenetration = pos[2] - hi[2];
392 cnt++;
393 }
394 if (pos[0] < lo[0] && c4)
395 {
396 c4 = true;
397 nbq[cnt + start_i].bodyId1 = rbId;
398 nbq[cnt + start_i].bodyId2 = -1;
399 nbq[cnt + start_i].normal1 = Coord(1, 0, 0);
400 nbq[cnt + start_i].pos1 = pos;
401 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
402 nbq[cnt + start_i].interpenetration = lo[0] - pos[0];
403 cnt++;
404 }
405 if (pos[1] < lo[1] && c5)
406 {
407 c5 = true;
408 nbq[cnt + start_i].bodyId1 = rbId;
409 nbq[cnt + start_i].bodyId2 = -1;
410 nbq[cnt + start_i].normal1 = Coord(0, 1, 0);
411 nbq[cnt + start_i].pos1 = pos;
412 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
413 nbq[cnt + start_i].interpenetration = lo[1] - pos[1];
414 cnt++;
415 }
416 if (pos[2] < lo[2] && c6)
417 {
418 c6 = true;
419 nbq[cnt + start_i].bodyId1 = rbId;
420 nbq[cnt + start_i].bodyId2 = -1;
421 nbq[cnt + start_i].normal1 = Coord(0, 0, 1);
422 nbq[cnt + start_i].pos1 = pos;
423 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
424 nbq[cnt + start_i].interpenetration = lo[2] - pos[2];
425 cnt++;
426 }
427
428 }
429 }
430 else if (eleType == ET_TET) // tets
431 {
432 int cnt = 0;
433 int start_i = count[pId];
434
435 Tet3D tet_i = tet[pId - elementOffset.tetIndex()];
436
437 for (int i = 0; i < 4; i++)
438 {
439 Coord vertex = tet_i.v[i];
440 if (vertex.x >= hi.x)
441 {
442 nbq[cnt + start_i].bodyId1 = rbId;
443 nbq[cnt + start_i].bodyId2 = -1;
444 nbq[cnt + start_i].normal1 = Coord(-1, 0, 0);
445 nbq[cnt + start_i].pos1 = vertex;
446 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
447 nbq[cnt + start_i].interpenetration = vertex.x - hi.x;
448 cnt++;
449 }
450 if (vertex.x <= lo.x)
451 {
452 nbq[cnt + start_i].bodyId1 = rbId;
453 nbq[cnt + start_i].bodyId2 = -1;
454 nbq[cnt + start_i].normal1 = Coord(1, 0, 0);
455 nbq[cnt + start_i].pos1 = vertex;
456 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
457 nbq[cnt + start_i].interpenetration = lo.x - (vertex.x);
458 cnt++;
459 }
460
461 if (vertex.y >= hi.y)
462 {
463 nbq[cnt + start_i].bodyId1 = rbId;
464 nbq[cnt + start_i].bodyId2 = -1;
465 nbq[cnt + start_i].normal1 = Coord(0, -1, 0);
466 nbq[cnt + start_i].pos1 = vertex;
467 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
468 nbq[cnt + start_i].interpenetration = vertex.y - hi.y;
469 cnt++;
470 }
471 if (vertex.y <= lo.y)
472 {
473 nbq[cnt + start_i].bodyId1 = rbId;
474 nbq[cnt + start_i].bodyId2 = -1;
475 nbq[cnt + start_i].normal1 = Coord(0, 1, 0);
476 nbq[cnt + start_i].pos1 = vertex;
477 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
478 nbq[cnt + start_i].interpenetration = lo.y - (vertex.y);
479 cnt++;
480 }
481
482 if (vertex.z >= hi.z)
483 {
484 nbq[cnt + start_i].bodyId1 = rbId;
485 nbq[cnt + start_i].bodyId2 = -1;
486 nbq[cnt + start_i].normal1 = Coord(0, 0, -1);
487 nbq[cnt + start_i].pos1 = vertex;
488 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
489 nbq[cnt + start_i].interpenetration = vertex.z - hi.z;
490 cnt++;
491 }
492 if (vertex.z <= lo.z)
493 {
494 nbq[cnt + start_i].bodyId1 = rbId;
495 nbq[cnt + start_i].bodyId2 = -1;
496 nbq[cnt + start_i].normal1 = Coord(0, 0, 1);
497 nbq[cnt + start_i].pos1 = vertex;
498 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
499 nbq[cnt + start_i].interpenetration = lo.z - (vertex.z);
500 cnt++;
501 }
502 }
503 }
504 else if (eleType == ET_CAPSULE)
505 {
506 int cnt = 0;
507 int start_i = count[pId];
508
509 Capsule3D cap_i = cap[pId - elementOffset.capsuleIndex()];
510
511 Coord v0 = cap_i.startPoint();
512 Coord v1 = cap_i.endPoint();
513
514 Real radius = cap_i.radius;
515
516 //v0
517 if (v0.x + radius >= hi.x)
518 {
519 nbq[cnt + start_i].bodyId1 = rbId;
520 nbq[cnt + start_i].bodyId2 = -1;
521 nbq[cnt + start_i].normal1 = Coord(-1, 0, 0);
522 nbq[cnt + start_i].pos1 = v0 + Coord(radius, 0, 0);
523 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
524 nbq[cnt + start_i].interpenetration = v0.x + radius - hi.x;
525 cnt++;
526 }
527 if (v0.x - radius <= lo.x)
528 {
529 nbq[cnt + start_i].bodyId1 = rbId;
530 nbq[cnt + start_i].bodyId2 = -1;
531 nbq[cnt + start_i].normal1 = Coord(1, 0, 0);
532 nbq[cnt + start_i].pos1 = v0 - Coord(radius, 0, 0);
533 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
534 nbq[cnt + start_i].interpenetration = lo.x - (v0.x - radius);
535 cnt++;
536 }
537
538 if (v0.y + radius >= hi.y)
539 {
540 nbq[cnt + start_i].bodyId1 = rbId;
541 nbq[cnt + start_i].bodyId2 = -1;
542 nbq[cnt + start_i].normal1 = Coord(0, -1, 0);
543 nbq[cnt + start_i].pos1 = v0 + Coord(0, radius, 0);
544 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
545 nbq[cnt + start_i].interpenetration = v0.y + radius - hi.y;
546 cnt++;
547 }
548 if (v0.y - radius <= lo.y)
549 {
550 nbq[cnt + start_i].bodyId1 = rbId;
551 nbq[cnt + start_i].bodyId2 = -1;
552 nbq[cnt + start_i].normal1 = Coord(0, 1, 0);
553 nbq[cnt + start_i].pos1 = v0 - Coord(0, radius, 0);
554 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
555 nbq[cnt + start_i].interpenetration = lo.y - (v0.y - radius);
556 cnt++;
557 }
558
559 if (v0.z + radius >= hi.z)
560 {
561 nbq[cnt + start_i].bodyId1 = rbId;
562 nbq[cnt + start_i].bodyId2 = -1;
563 nbq[cnt + start_i].normal1 = Coord(0, 0, -1);
564 nbq[cnt + start_i].pos1 = v0 + Coord(0, 0, radius);
565 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
566 nbq[cnt + start_i].interpenetration = v0.z + radius - hi.z;
567 cnt++;
568 }
569 if (v0.z - radius <= lo.z)
570 {
571 nbq[cnt + start_i].bodyId1 = rbId;
572 nbq[cnt + start_i].bodyId2 = -1;
573 nbq[cnt + start_i].normal1 = Coord(0, 0, 1);
574 nbq[cnt + start_i].pos1 = v0 - Coord(0, 0, radius);
575 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
576 nbq[cnt + start_i].interpenetration = lo.z - (v0.z - radius);
577 cnt++;
578 }
579
580 //v1
581 if (v1.x + radius >= hi.x)
582 {
583 nbq[cnt + start_i].bodyId1 = rbId;
584 nbq[cnt + start_i].bodyId2 = -1;
585 nbq[cnt + start_i].normal1 = Coord(-1, 0, 0);
586 nbq[cnt + start_i].pos1 = v1 + Coord(radius, 0, 0);
587 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
588 nbq[cnt + start_i].interpenetration = v1.x + radius - hi.x;
589 cnt++;
590 }
591 if (v1.x - radius <= lo.x)
592 {
593 nbq[cnt + start_i].bodyId1 = rbId;
594 nbq[cnt + start_i].bodyId2 = -1;
595 nbq[cnt + start_i].normal1 = Coord(1, 0, 0);
596 nbq[cnt + start_i].pos1 = v1 - Coord(radius, 0, 0);
597 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
598 nbq[cnt + start_i].interpenetration = lo.x - (v1.x - radius);
599 cnt++;
600 }
601
602 if (v1.y + radius >= hi.y)
603 {
604 nbq[cnt + start_i].bodyId1 = rbId;
605 nbq[cnt + start_i].bodyId2 = -1;
606 nbq[cnt + start_i].normal1 = Coord(0, -1, 0);
607 nbq[cnt + start_i].pos1 = v1 + Coord(0, radius, 0);
608 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
609 nbq[cnt + start_i].interpenetration = v1.y + radius - hi.y;
610 cnt++;
611 }
612 if (v1.y - radius <= lo.y)
613 {
614 nbq[cnt + start_i].bodyId1 = rbId;
615 nbq[cnt + start_i].bodyId2 = -1;
616 nbq[cnt + start_i].normal1 = Coord(0, 1, 0);
617 nbq[cnt + start_i].pos1 = v1 - Coord(0, radius, 0);
618 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
619 nbq[cnt + start_i].interpenetration = lo.y - (v1.y - radius);
620 cnt++;
621 }
622
623 if (v1.z + radius >= hi.z)
624 {
625 nbq[cnt + start_i].bodyId1 = rbId;
626 nbq[cnt + start_i].bodyId2 = -1;
627 nbq[cnt + start_i].normal1 = Coord(0, 0, -1);
628 nbq[cnt + start_i].pos1 = v1 + Coord(0, 0, radius);
629 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
630 nbq[cnt + start_i].interpenetration = v1.z + radius - hi.z;
631 cnt++;
632 }
633 if (v1.z - radius <= lo.z)
634 {
635 nbq[cnt + start_i].bodyId1 = rbId;
636 nbq[cnt + start_i].bodyId2 = -1;
637 nbq[cnt + start_i].normal1 = Coord(0, 0, 1);
638 nbq[cnt + start_i].pos1 = v1 - Coord(0, 0, radius);
639 nbq[cnt + start_i].contactType = ContactType::CT_BOUDNARY;
640 nbq[cnt + start_i].interpenetration = lo.z - (v1.z - radius);
641 cnt++;
642 }
643 }
644 }
645
646 template<typename TDataType>
647 void CollistionDetectionBoundingBox<TDataType>::compute()
648 {
649 int sum = 0;
650
651 auto upperBound = this->varUpperBound()->getData();
652 auto lowerBound = this->varLowerBound()->getData();
653
654 auto discreteSet = this->inDiscreteElements()->getDataPtr();
655 uint totalSize = discreteSet->totalSize();
656
657 DArray<Box3D>& boxInGlobal = discreteSet->boxesInGlobal();
658 DArray<Sphere3D>& sphereInGlobal = discreteSet->spheresInGlobal();
659 DArray<Tet3D>& tetInGlobal = discreteSet->tetsInGlobal();
660 DArray<Capsule3D>& capsuleInGlobal = discreteSet->capsulesInGlobal();
661
662 ElementOffset offset = discreteSet->calculateElementOffset();
663
664 mBoundaryContactCounter.resize(discreteSet->totalSize());
665 mBoundaryContactCounter.reset();
666 if (discreteSet->totalSize() > 0)
667 {
668 cuExecute(totalSize,
669 CountContactsWithBoundary,
670 sphereInGlobal,
671 boxInGlobal,
672 tetInGlobal,
673 capsuleInGlobal,
674 mBoundaryContactCounter,
675 upperBound,
676 lowerBound,
677 offset);
678
679 sum += mReduce.accumulate(mBoundaryContactCounter.begin(), mBoundaryContactCounter.size());
680 mScan.exclusive(mBoundaryContactCounter, true);
681
682 this->outContacts()->resize(sum);
683
684 if (sum > 0) {
685 cuExecute(totalSize,
686 SetupContactsWithBoundary,
687 sphereInGlobal,
688 boxInGlobal,
689 tetInGlobal,
690 capsuleInGlobal,
691 mBoundaryContactCounter,
692 this->outContacts()->getData(),
693 discreteSet->shape2RigidBodyMapping(),
694 upperBound,
695 lowerBound,
696 offset);
697 }
698 }
699 else
700 this->outContacts()->resize(0);
701 }
702
703 DEFINE_CLASS(CollistionDetectionBoundingBox);
704}