PeriDyno 1.0.0
Loading...
Searching...
No Matches
DiscreteElements.cu
Go to the documentation of this file.
1#include "DiscreteElements.h"
2
3#include <thrust/sort.h>
4
5namespace dyno
6{
7 IMPLEMENT_TCLASS(DiscreteElements, TDataType)
8
9 template<typename TDataType>
10 DiscreteElements<TDataType>::DiscreteElements()
11 : TopologyModule()
12 {
13 }
14
15 template<typename TDataType>
16 DiscreteElements<TDataType>::~DiscreteElements()
17 {
18// m_hostBoxes.clear();
19// m_hostSpheres.clear();
20 }
21
22 template<typename TDataType>
23 void DiscreteElements<TDataType>::scale(Real s)
24 {
25 }
26
27 template<typename TDataType>
28 uint DiscreteElements<TDataType>::totalSize()
29 {
30 return mBoxesInLocal.size() + mSpheresInLocal.size() + mTetsInLocal.size() + mCapsulesInLocal.size() + mTrianglesInLocal.size();
31 }
32
33 template<typename TDataType>
34 uint DiscreteElements<TDataType>::totalJointSize()
35 {
36 return mBallAndSocketJoints.size() + mSliderJoints.size() + mHingeJoints.size() + mFixedJoints.size() + mPointJoints.size();
37 }
38
39 template<typename TDataType>
40 uint DiscreteElements<TDataType>::sphereIndex()
41 {
42 return 0;
43 }
44
45 template<typename TDataType>
46 uint DiscreteElements<TDataType>::triangleIndex()
47 {
48 return capsuleIndex() + this->capsulesInLocal().size();
49 }
50
51 template<typename TDataType>
52 uint DiscreteElements<TDataType>::tetIndex()
53 {
54 return boxIndex() + this->boxesInLocal().size();
55 }
56
57 template<typename TDataType>
58 uint DiscreteElements<TDataType>::capsuleIndex()
59 {
60 return tetIndex() + this->tetsInLocal().size();
61 }
62
63 template<typename TDataType>
64 uint DiscreteElements<TDataType>::boxIndex()
65 {
66 return sphereIndex() + this->spheresInLocal().size();
67 }
68
69 template<typename TDataType>
70 ElementOffset DiscreteElements<TDataType>::calculateElementOffset()
71 {
72 ElementOffset elementOffset;
73 elementOffset.setSphereRange(sphereIndex(), sphereIndex() + this->spheresInLocal().size());
74 elementOffset.setBoxRange(boxIndex(), boxIndex() + this->boxesInLocal().size());
75 elementOffset.setTetRange(tetIndex(), tetIndex() + this->tetsInLocal().size());
76 elementOffset.setCapsuleRange(capsuleIndex(), capsuleIndex() + this->capsulesInLocal().size());
77 elementOffset.setTriangleRange(triangleIndex(), triangleIndex() + this->trianglesInLocal().size());
78
79 return elementOffset;
80 }
81
82 template<typename TDataType>
83 void DiscreteElements<TDataType>::setBoxes(DArray<Box3D>& boxes)
84 {
85 mBoxesInLocal.assign(boxes);
86 }
87
88 template<typename TDataType>
89 void DiscreteElements<TDataType>::setSpheres(DArray<Sphere3D>& spheres)
90 {
91 mSpheresInLocal.assign(spheres);
92 }
93
94 template<typename TDataType>
95 void DiscreteElements<TDataType>::setTetSDF(DArray<Real>& sdf)
96 {
97 m_tet_sdf.assign(sdf);
98 }
99
100 template<typename TDataType>
101 void DiscreteElements<TDataType>::setTets(DArray<Tet3D>& tets)
102 {
103 mTetsInLocal.assign(tets);
104 }
105
106 template<typename TDataType>
107 void DiscreteElements<TDataType>::setCapsules(DArray<Capsule3D>& capsules)
108 {
109 mCapsulesInLocal.assign(capsules);
110 }
111
112 template<typename TDataType>
113 void DiscreteElements<TDataType>::setTetBodyId(DArray<int>& body_id)
114 {
115 m_tet_body_mapping.assign(body_id);
116 }
117
118 template<typename TDataType>
119 void DiscreteElements<TDataType>::setTetElementId(DArray<TopologyModule::Tetrahedron>& element_id)
120 {
121 m_tet_element_id.assign(element_id);
122 }
123
124 template<typename TDataType>
125 void DiscreteElements<TDataType>::setTriangles(DArray<Triangle3D>& triangles)
126 {
127 mTrianglesInLocal.assign(triangles);
128 }
129
130 template<typename TDataType>
131 void DiscreteElements<TDataType>::copyFrom(DiscreteElements<TDataType>& de)
132 {
133 mSpheresInLocal.assign(de.mSpheresInLocal);
134 mBoxesInLocal.assign(de.mBoxesInLocal);
135 mTetsInLocal.assign(de.mTetsInLocal);
136 mCapsulesInLocal.assign(de.mCapsulesInLocal);
137 mTrianglesInLocal.assign(de.mTrianglesInLocal);
138
139 mSphereInGlobal.assign(de.mSphereInGlobal);
140 mBoxInGlobal.assign(de.mBoxInGlobal);
141 mTetInGlobal.assign(de.mTetInGlobal);
142 mCapsuleInGlobal.assign(de.mCapsuleInGlobal);
143 mTriangleInGlobal.assign(de.mTriangleInGlobal);
144
145 mShape2RigidBody.assign(de.mShape2RigidBody);
146 mPosition.assign(de.mPosition);
147 mRotation.assign(de.mRotation);
148
149 mBallAndSocketJoints.assign(de.mBallAndSocketJoints);
150 mSliderJoints.assign(de.mSliderJoints);
151 mHingeJoints.assign(de.mHingeJoints);
152 mFixedJoints.assign(de.mFixedJoints);
153 mPointJoints.assign(de.mPointJoints);
154 mDistanceJoints.assign(de.mDistanceJoints);
155
156 m_tet_sdf.assign(de.m_tet_sdf);
157 m_tet_body_mapping.assign(de.m_tet_body_mapping);
158 m_tet_element_id.assign(de.m_tet_element_id);
159 }
160
161 template<typename Joint>
162 __global__ void DE_UpdateJointIds(
163 DArray<Joint> joints,
164 uint size,
165 uint offsetJoint,
166 uint offsetRigidBody)
167 {
168 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
169 if (tId >= size) return;
170
171 Joint joint = joints[tId + offsetJoint];
172 joint.bodyId1 += offsetRigidBody;
173 joint.bodyId2 += offsetRigidBody;
174
175 joints[tId + offsetJoint] = joint;
176 }
177
178 __global__ void DE_UpdateShape2RigidBodyMapping(
179 DArray<Pair<uint, uint>> mapping,
180 DArray<uint> offsetShape, //with a constant array size of 5
181 uint size,
182 uint offsetMapping,
183 uint offsetRigidBody,
184 ElementOffset elementOffset)
185 {
186 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
187 if (tId >= size) return;
188
189 Pair<uint, uint> pair = mapping[tId + offsetMapping];
190
191 pair.second += offsetRigidBody;
192
193 //Sphere id
194 if (tId < elementOffset.boxIndex())
195 {
196 pair.first = tId + offsetShape[0];
197 }
198 //Box id
199 else if (tId < elementOffset.tetIndex())
200 {
201 pair.first = (tId - elementOffset.boxIndex()) + offsetShape[1];
202 }
203 //Tet id
204 else if (tId < elementOffset.capsuleIndex())
205 {
206 pair.first = (tId - elementOffset.tetIndex()) + offsetShape[2];
207 }
208 //Capsule id
209 else if (tId < elementOffset.triangleIndex())
210 {
211 pair.first = (tId - elementOffset.tetIndex()) + offsetShape[3];
212 }
213 else
214 {
215 pair.first = (tId - elementOffset.triangleIndex()) + offsetShape[4];
216 }
217
218 mapping[tId + offsetMapping] = pair;
219 }
220
221 template<typename TDataType>
222 void DiscreteElements<TDataType>::merge(CArray<std::shared_ptr<DiscreteElements<TDataType>>>& topos)
223 {
224 //Merge shapes
225 uint sizeOfSpheres = 0;
226 uint sizeOfBoxes = 0;
227 uint sizeOfCapsules = 0;
228 uint sizeOfTets = 0;
229 uint sizeOfTriangles = 0;
230
231 for (uint i = 0; i < topos.size(); i++)
232 {
233 auto topo = topos[i];
234
235 sizeOfSpheres += topo->spheresInLocal().size();
236 sizeOfBoxes += topo->boxesInLocal().size();
237 sizeOfCapsules += topo->capsulesInLocal().size();
238 sizeOfTets += topo->tetsInLocal().size();
239 sizeOfTriangles += topo->trianglesInLocal().size();
240 }
241
242 mSpheresInLocal.resize(sizeOfSpheres);
243 mBoxesInLocal.resize(sizeOfBoxes);
244 mCapsulesInLocal.resize(sizeOfCapsules);
245 mTetsInLocal.resize(sizeOfTets);
246 mTrianglesInLocal.resize(sizeOfTriangles);
247
248 uint offsetOfSpheres = 0;
249 uint offsetOfBoxes = 0;
250 uint offsetOfTets = 0;
251 uint offsetOfCapsules = 0;
252 uint offsetOfTriangles = 0;
253 for (uint i = 0; i < topos.size(); i++)
254 {
255 auto topo = topos[i];
256
257 mSpheresInLocal.assign(topo->spheresInLocal(), topo->spheresInLocal().size(), offsetOfSpheres, 0);
258 mBoxesInLocal.assign(topo->boxesInLocal(), topo->boxesInLocal().size(), offsetOfBoxes, 0);
259 mCapsulesInLocal.assign(topo->capsulesInLocal(), topo->capsulesInLocal().size(), offsetOfCapsules, 0);
260 mTetsInLocal.assign(topo->tetsInLocal(), topo->tetsInLocal().size(), offsetOfTets, 0);
261 mTrianglesInLocal.assign(topo->trianglesInLocal(), topo->trianglesInLocal().size(), offsetOfTriangles, 0);
262
263 offsetOfSpheres += topo->spheresInLocal().size();
264 offsetOfBoxes += topo->boxesInLocal().size();
265 offsetOfCapsules += topo->capsulesInLocal().size();
266 offsetOfTets += topo->tetsInLocal().size();
267 offsetOfTriangles += topo->trianglesInLocal().size();
268 }
269
270 //Merge rigid body states
271 uint sizeOfRigidBodies = 0;
272
273 for (uint i = 0; i < topos.size(); i++)
274 {
275 auto topo = topos[i];
276
277 sizeOfRigidBodies += topo->position().size();
278 }
279
280 mPosition.resize(sizeOfRigidBodies);
281 mRotation.resize(sizeOfRigidBodies);
282
283 uint offsetOfRigidBodies = 0;
284 for (uint i = 0; i < topos.size(); i++)
285 {
286 auto topo = topos[i];
287
288 mPosition.assign(topo->position(), topo->position().size(), offsetOfRigidBodies, 0);
289 mRotation.assign(topo->rotation(), topo->rotation().size(), offsetOfRigidBodies, 0);
290
291 offsetOfRigidBodies += topo->position().size();
292 }
293
294 //Merge shape to rigid body mapping
295 uint sizeOfMapping = 0;
296 for (uint i = 0; i < topos.size(); i++)
297 {
298 auto topo = topos[i];
299
300 sizeOfMapping += topo->shape2RigidBodyMapping().size();
301 }
302
303 mShape2RigidBody.resize(sizeOfMapping);
304
305 uint offsetOfMapping = 0;
306 offsetOfRigidBodies = 0;
307 CArray<uint> offsetArrayInHost(5);
308 offsetArrayInHost[0] = 0;
309 offsetArrayInHost[1] = offsetArrayInHost[0] + sizeOfSpheres;
310 offsetArrayInHost[2] = offsetArrayInHost[1] + sizeOfBoxes;
311 offsetArrayInHost[3] = offsetArrayInHost[2] + sizeOfTets;
312 offsetArrayInHost[4] = offsetArrayInHost[3] + sizeOfCapsules;
313
314 DArray<uint> offsetArrayInDevice(5);
315 for (uint i = 0; i < topos.size(); i++)
316 {
317 auto topo = topos[i];
318
319 uint sizeOfShape = topo->shape2RigidBodyMapping().size();
320
321 mShape2RigidBody.assign(topo->shape2RigidBodyMapping(), sizeOfShape, offsetOfMapping, 0);
322
323 offsetArrayInDevice.assign(offsetArrayInHost);
324
325 cuExecute(sizeOfShape, DE_UpdateShape2RigidBodyMapping, mShape2RigidBody, offsetArrayInDevice, sizeOfShape, offsetOfMapping, offsetOfRigidBodies, topo->calculateElementOffset());
326
327 offsetOfMapping += sizeOfShape;
328 offsetOfRigidBodies += topo->position().size();
329
330 offsetArrayInHost[0] += topo->spheresInLocal().size();
331 offsetArrayInHost[1] += topo->boxesInLocal().size();
332 offsetArrayInHost[2] += topo->tetsInLocal().size();
333 offsetArrayInHost[3] += topo->capsulesInLocal().size();
334 offsetArrayInHost[4] += topo->trianglesInLocal().size();
335 }
336
337 thrust::sort(thrust::device, mShape2RigidBody.begin(), mShape2RigidBody.begin() + mShape2RigidBody.size(), thrust::less<Pair<uint, uint>>());
338
339 //Merge joints
340 uint sizeOfBallAndSocketJoints = 0;
341 uint sizeOfSliderJoints = 0;
342 uint sizeOfHingeJoints = 0;
343 uint sizeOfFixedJoints = 0;
344 uint sizeOfPointJoints = 0;
345 uint sizeOfDistanceJoints = 0;
346
347 for (uint i = 0; i < topos.size(); i++)
348 {
349 auto topo = topos[i];
350
351 sizeOfBallAndSocketJoints += topo->ballAndSocketJoints().size();
352 sizeOfSliderJoints += topo->sliderJoints().size();
353 sizeOfHingeJoints += topo->hingeJoints().size();
354 sizeOfFixedJoints += topo->fixedJoints().size();
355 sizeOfPointJoints += topo->pointJoints().size();
356 sizeOfDistanceJoints += topo->distanceJoints().size();
357 }
358
359 mBallAndSocketJoints.resize(sizeOfBallAndSocketJoints);
360 mSliderJoints.resize(sizeOfSliderJoints);
361 mHingeJoints.resize(sizeOfHingeJoints);
362 mFixedJoints.resize(sizeOfFixedJoints);
363 mPointJoints.resize(sizeOfPointJoints);
364 mDistanceJoints.resize(sizeOfDistanceJoints);
365
366 uint offsetOfBallAndSocketJoints = 0;
367 uint offsetOfSliderJoints = 0;
368 uint offsetOfHingeJoints = 0;
369 uint offsetOfFixedJoints = 0;
370 uint offsetOfPointJoints = 0;
371 uint offsetOfDistanceJoints = 0;
372
373 offsetOfRigidBodies = 0;
374 for (uint i = 0; i < topos.size(); i++)
375 {
376 auto topo = topos[i];
377
378 mBallAndSocketJoints.assign(topo->ballAndSocketJoints(), topo->ballAndSocketJoints().size(), offsetOfBallAndSocketJoints, 0);
379 mSliderJoints.assign(topo->sliderJoints(), topo->sliderJoints().size(), offsetOfSliderJoints, 0);
380 mHingeJoints.assign(topo->hingeJoints(), topo->hingeJoints().size(), offsetOfHingeJoints, 0);
381 mFixedJoints.assign(topo->fixedJoints(), topo->fixedJoints().size(), offsetOfFixedJoints, 0);
382 mPointJoints.assign(topo->pointJoints(), topo->pointJoints().size(), offsetOfPointJoints, 0);
383 mDistanceJoints.assign(topo->distanceJoints(), topo->distanceJoints().size(), offsetOfDistanceJoints, 0);
384
385 cuExecute(topo->ballAndSocketJoints().size(), DE_UpdateJointIds, mBallAndSocketJoints, topo->ballAndSocketJoints().size(), offsetOfBallAndSocketJoints, offsetOfRigidBodies);
386 cuExecute(topo->sliderJoints().size(), DE_UpdateJointIds, mSliderJoints, topo->sliderJoints().size(), offsetOfSliderJoints, offsetOfRigidBodies);
387 cuExecute(topo->hingeJoints().size(), DE_UpdateJointIds, mHingeJoints, topo->hingeJoints().size(), offsetOfHingeJoints, offsetOfRigidBodies);
388 cuExecute(topo->fixedJoints().size(), DE_UpdateJointIds, mFixedJoints, topo->fixedJoints().size(), offsetOfFixedJoints, offsetOfRigidBodies);
389 cuExecute(topo->pointJoints().size(), DE_UpdateJointIds, mPointJoints, topo->pointJoints().size(), offsetOfPointJoints, offsetOfRigidBodies);
390 cuExecute(topo->distanceJoints().size(), DE_UpdateJointIds, mDistanceJoints, topo->distanceJoints().size(), offsetOfDistanceJoints, offsetOfRigidBodies);
391
392 offsetOfBallAndSocketJoints += topo->ballAndSocketJoints().size();
393 offsetOfSliderJoints += topo->sliderJoints().size();
394 offsetOfHingeJoints += topo->hingeJoints().size();
395 offsetOfFixedJoints += topo->fixedJoints().size();
396 offsetOfPointJoints += topo->pointJoints().size();
397 offsetOfDistanceJoints += topo->distanceJoints().size();
398
399 offsetOfRigidBodies += topo->position().size();
400 }
401
402 this->update();
403 }
404
405 // Some useful tools to to do transformation for discrete element
406
407 template<typename Real>
408 DYN_FUNC TOrientedBox3D<Real> local2Global(const TOrientedBox3D<Real>& box, const Vector<Real, 3>& t, const SquareMatrix<Real, 3>& r)
409 {
410 TOrientedBox3D<Real> ret;
411 ret.center = t + r * box.center;
412 ret.u = r * box.u;
413 ret.v = r * box.v;
414 ret.w = r * box.w;
415 ret.extent = box.extent;
416
417 return ret;
418 }
419
420 template<typename Real>
421 DYN_FUNC TSphere3D<Real> local2Global(const TSphere3D<Real>& sphere, const Vector<Real, 3>& t, const SquareMatrix<Real, 3>& r)
422 {
423 TSphere3D<Real> ret;
424 ret.center = t + r * sphere.center;
425 ret.radius = sphere.radius;
426 ret.rotation = Quat<Real>(r * sphere.rotation.toMatrix3x3());
427
428 return ret;
429 }
430
431 template<typename Real>
432 DYN_FUNC TCapsule3D<Real> local2Global(const TCapsule3D<Real>& capsule, const Vector<Real, 3>& t, const SquareMatrix<Real, 3>& r)
433 {
434 TCapsule3D<Real> ret;
435 ret.center = t + r * capsule.center;
436 ret.radius = capsule.radius;
437 ret.halfLength = capsule.halfLength;
438 ret.rotation = Quat<Real>(r * capsule.rotation.toMatrix3x3());
439
440 return ret;
441 }
442
443 template<typename Real>
444 DYN_FUNC TTet3D<Real> local2Global(const TTet3D<Real>& tet, const Vector<Real, 3>& t, const SquareMatrix<Real, 3>& r)
445 {
446 TTet3D<Real> ret;
447 ret.v[0] = t + r * tet.v[0];
448 ret.v[1] = t + r * tet.v[1];
449 ret.v[2] = t + r * tet.v[2];
450 ret.v[3] = t + r * tet.v[3];
451
452 return ret;
453 }
454
455 template<typename Real>
456 DYN_FUNC TTriangle3D<Real> local2Global(const TTriangle3D<Real>& tri, const Vector<Real, 3>& t, const SquareMatrix<Real, 3>& r)
457 {
458 TTriangle3D<Real> ret;
459 ret.v[0] = t + r * tri.v[0];
460 ret.v[1] = t + r * tri.v[1];
461 ret.v[2] = t + r * tri.v[2];
462
463 return ret;
464 }
465
466 template<typename Coord, typename Matrix, typename Box3D>
467 __global__ void DE_Local2Global(
468 DArray<Box3D> boxInGlobal,
469 DArray<Sphere3D> sphereInGlobal,
470 DArray<Tet3D> tetInGlobal,
471 DArray<Capsule3D> capInGlobal,
472 DArray<Triangle3D> triInGlobal,
473 DArray<Box3D> boxInLocal,
474 DArray<Sphere3D> sphereInLocal,
475 DArray<Tet3D> tetInLocal,
476 DArray<Capsule3D> capInLocal,
477 DArray<Triangle3D> triInLocal,
478 DArray<Coord> positionGlobal,
479 DArray<Matrix> rotationGlobal,
480 DArray<Pair<uint, uint>> mapping,
481 ElementOffset elementOffset,
482 uint totalSize)
483 {
484 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
485 if (tId >= totalSize) return;
486
487 ElementType eleType = elementOffset.checkElementType(tId);
488
489 uint rigidbodyId = mapping[tId].second;
490
491 Coord t = positionGlobal[rigidbodyId];
492 Matrix r = rotationGlobal[rigidbodyId];
493
494 switch (eleType)
495 {
496 case ET_SPHERE:
497 {
498 sphereInGlobal[tId - elementOffset.sphereIndex()] = local2Global(sphereInLocal[tId - elementOffset.sphereIndex()], t, r);
499 break;
500 }
501 case ET_BOX:
502 {
503 boxInGlobal[tId - elementOffset.boxIndex()] = local2Global(boxInLocal[tId - elementOffset.boxIndex()], t, r);
504 break;
505 }
506 case ET_TET:
507 {
508 tetInGlobal[tId - elementOffset.tetIndex()] = local2Global(tetInLocal[tId - elementOffset.tetIndex()], t, r);
509 break;
510 }
511 case ET_CAPSULE:
512 {
513 capInGlobal[tId - elementOffset.capsuleIndex()] = local2Global(capInLocal[tId - elementOffset.capsuleIndex()], t, r);
514 break;
515 }
516 case ET_TRI:
517 {
518 triInGlobal[tId - elementOffset.triangleIndex()] = local2Global(triInLocal[tId - elementOffset.triangleIndex()], t, r);
519 break;
520 }
521 default:
522 break;
523 }
524 }
525
526 template<typename TDataType>
527 void DiscreteElements<TDataType>::requestDiscreteElementsInGlobal(
528 DArray<Box3D>& boxInGlobal,
529 DArray<Sphere3D>& sphereInGlobal,
530 DArray<Tet3D>& tetInGlobal,
531 DArray<Capsule3D>& capInGlobal,
532 DArray<Triangle3D>& triInGlobal)
533 {
534 auto elementOffset = this->calculateElementOffset();
535
536 boxInGlobal.assign(this->boxesInLocal());
537 sphereInGlobal.assign(this->spheresInLocal());
538 tetInGlobal.assign(this->tetsInLocal());
539 capInGlobal.assign(this->capsulesInLocal());
540 triInGlobal.assign(this->trianglesInLocal());
541
542 uint num = this->totalSize();
543
544 cuExecute(num,
545 DE_Local2Global,
546 boxInGlobal,
547 sphereInGlobal,
548 tetInGlobal,
549 capInGlobal,
550 triInGlobal,
551 this->boxesInLocal(),
552 this->spheresInLocal(),
553 this->tetsInLocal(),
554 this->capsulesInLocal(),
555 this->trianglesInLocal(),
556 mPosition,
557 mRotation,
558 mShape2RigidBody,
559 elementOffset,
560 num);
561 }
562
563 template<typename Coord, typename Matrix, typename Box3D>
564 __global__ void DE_Local2GlobalForBox(
565 DArray<Box3D> boxInGlobal,
566 DArray<Box3D> boxInLocal,
567 DArray<Coord> positionGlobal,
568 DArray<Matrix> rotationGlobal,
569 DArray<Pair<uint, uint>> mapping,
570 uint offset)
571 {
572 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
573 if (tId >= boxInLocal.size()) return;
574
575 uint rigidbodyId = mapping[tId + offset].second;
576
577 Coord t = positionGlobal[rigidbodyId];
578 Matrix r = rotationGlobal[rigidbodyId];
579
580 boxInGlobal[tId] = local2Global(boxInLocal[tId], t, r);
581 }
582
583 template<typename Coord, typename Matrix, typename Sphere3D>
584 __global__ void DE_Local2GlobalForSphere(
585 DArray<Sphere3D> sphereInGlobal,
586 DArray<Sphere3D> sphereInLocal,
587 DArray<Coord> positionGlobal,
588 DArray<Matrix> rotationGlobal,
589 DArray<Pair<uint, uint>> mapping,
590 uint offset)
591 {
592 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
593 if (tId >= sphereInLocal.size()) return;
594
595 uint rigidbodyId = mapping[tId + offset].second;
596
597 Coord t = positionGlobal[rigidbodyId];
598 Matrix r = rotationGlobal[rigidbodyId];
599
600 sphereInGlobal[tId] = local2Global(sphereInLocal[tId], t, r);
601 }
602
603 template<typename Coord, typename Matrix, typename Tet3D>
604 __global__ void DE_Local2GlobalForTet(
605 DArray<Tet3D> tetInGlobal,
606 DArray<Tet3D> tetInLocal,
607 DArray<Coord> positionGlobal,
608 DArray<Matrix> rotationGlobal,
609 DArray<Pair<uint, uint>> mapping,
610 uint offset)
611 {
612 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
613 if (tId >= tetInLocal.size()) return;
614
615 uint rigidbodyId = mapping[tId + offset].second;
616
617 Coord t = positionGlobal[rigidbodyId];
618 Matrix r = rotationGlobal[rigidbodyId];
619
620 tetInGlobal[tId] = local2Global(tetInLocal[tId], t, r);
621 }
622
623 template<typename Coord, typename Matrix, typename Capsule3D>
624 __global__ void DE_Local2GlobalForCapsule(
625 DArray<Capsule3D> capInGlobal,
626 DArray<Capsule3D> capInLocal,
627 DArray<Coord> positionGlobal,
628 DArray<Matrix> rotationGlobal,
629 DArray<Pair<uint, uint>> mapping,
630 uint offset)
631 {
632 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
633 if (tId >= capInLocal.size()) return;
634
635 uint rigidbodyId = mapping[tId + offset].second;
636
637 Coord t = positionGlobal[rigidbodyId];
638 Matrix r = rotationGlobal[rigidbodyId];
639
640 capInGlobal[tId] = local2Global(capInLocal[tId], t, r);
641 }
642
643 template<typename Coord, typename Matrix, typename Triangle3D>
644 __global__ void DE_Local2GlobalForTriangle(
645 DArray<Triangle3D> triInGlobal,
646 DArray<Triangle3D> triInLocal,
647 DArray<Coord> positionGlobal,
648 DArray<Matrix> rotationGlobal,
649 DArray<Pair<uint, uint>> mapping,
650 uint offset)
651 {
652 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
653 if (tId >= triInLocal.size()) return;
654
655 uint rigidbodyId = mapping[tId + offset].second;
656
657 Coord t = positionGlobal[rigidbodyId];
658 Matrix r = rotationGlobal[rigidbodyId];
659
660 triInGlobal[tId] = local2Global(triInLocal[tId], t, r);
661 }
662
663 template<typename TDataType>
664 void DiscreteElements<TDataType>::requestCapsuleInGlobal(DArray<Capsule3D>& capInGlobal)
665 {
666 auto elementOffset = this->calculateElementOffset();
667
668 capInGlobal.assign(this->capsulesInLocal());
669
670 cuExecute(capInGlobal.size(),
671 DE_Local2GlobalForCapsule,
672 capInGlobal,
673 this->capsulesInLocal(),
674 mPosition,
675 mRotation,
676 this->shape2RigidBodyMapping(),
677 elementOffset.capsuleIndex());
678 }
679
680 template<typename TDataType>
681 void DiscreteElements<TDataType>::requestTriangleInGlobal(DArray<Triangle3D>& triInGlobal)
682 {
683 auto elementOffset = this->calculateElementOffset();
684
685 triInGlobal.assign(this->trianglesInLocal());
686 }
687
688 template<typename TDataType>
689 void DiscreteElements<TDataType>::requestTetInGlobal(DArray<Tet3D>& tetInGlobal)
690 {
691 auto elementOffset = this->calculateElementOffset();
692
693 tetInGlobal.assign(this->tetsInLocal());
694
695 cuExecute(tetInGlobal.size(),
696 DE_Local2GlobalForCapsule,
697 tetInGlobal,
698 this->tetsInLocal(),
699 mPosition,
700 mRotation,
701 this->shape2RigidBodyMapping(),
702 elementOffset.tetIndex());
703 }
704
705 template<typename TDataType>
706 void DiscreteElements<TDataType>::requestSphereInGlobal(DArray<Sphere3D>& sphereInGlobal)
707 {
708 auto elementOffset = this->calculateElementOffset();
709
710 sphereInGlobal.assign(this->spheresInLocal());
711
712 cuExecute(sphereInGlobal.size(),
713 DE_Local2GlobalForSphere,
714 sphereInGlobal,
715 this->spheresInLocal(),
716 mPosition,
717 mRotation,
718 this->shape2RigidBodyMapping(),
719 elementOffset.sphereIndex());
720 }
721
722 template<typename TDataType>
723 void DiscreteElements<TDataType>::requestBoxInGlobal(DArray<Box3D>& boxInGlobal)
724 {
725 auto elementOffset = this->calculateElementOffset();
726
727 boxInGlobal.assign(this->boxesInLocal());
728
729 cuExecute(boxInGlobal.size(),
730 DE_Local2GlobalForBox,
731 boxInGlobal,
732 this->boxesInLocal(),
733 mPosition,
734 mRotation,
735 this->shape2RigidBodyMapping(),
736 elementOffset.boxIndex());
737 }
738
739 template<typename TDataType>
740 void DiscreteElements<TDataType>::updateTopology()
741 {
742 this->requestDiscreteElementsInGlobal(mBoxInGlobal, mSphereInGlobal, mTetInGlobal, mCapsuleInGlobal, mTriangleInGlobal);
743 }
744
745 DEFINE_CLASS(DiscreteElements);
746}