1#include "CollistionDetectionTriangleSet.h"
3#include "Primitive/Primitive3D.h"
4#include "Topology/DiscreteElements.h"
8 template<typename TDataType>
9 CollistionDetectionTriangleSet<TDataType>::CollistionDetectionTriangleSet()
12 mBroadPhaseCD = std::make_shared<CollisionDetectionBroadPhase<TDataType>>();
15 template<typename TDataType>
16 CollistionDetectionTriangleSet<TDataType>::~CollistionDetectionTriangleSet()
21 template<typename Coord, typename AABB>
22 __global__ void CDTS_SetupAABBs(
24 DArray<Coord> vertices,
25 DArray<TopologyModule::Triangle> indices)
27 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
28 if (tId >= indices.size()) return;
30 TopologyModule::Triangle index = indices[tId];
32 Coord v0 = vertices[index[0]];
33 Coord v1 = vertices[index[1]];
34 Coord v2 = vertices[index[2]];
36 aabbs[tId] = TTriangle3D<Real>(v0, v1, v2).aabb();
39 template<typename AABB, typename Box3D>
40 __global__ void CDTS_SetupAABBForRigidBodies(
41 DArray<AABB> boundingBox,
43 DArray<Sphere3D> spheres,
45 DArray<Capsule3D> caps,
46 ElementOffset elementOffset)
48 uint tId = threadIdx.x + (blockIdx.x * blockDim.x);
49 if (tId >= boundingBox.size()) return;
51 ElementType eleType = elementOffset.checkElementType(tId);
58 box = spheres[tId].aabb();
63 box = boxes[tId - elementOffset.boxIndex()].aabb();
68 box = tets[tId - elementOffset.tetIndex()].aabb();
73 box = caps[tId - elementOffset.capsuleIndex()].aabb();
80 boundingBox[tId] = box;
83 template<typename Coord, typename Box3D, typename ContactPair>
84 __global__ void CDTS_CountContacts(
86 DArray<ContactPair> nbr_cons,
88 DArray<Sphere3D> spheres,
90 DArray<Capsule3D> capsules,
91 DArray<Coord> vertices, //triangle vertices
92 DArray<TopologyModule::Triangle> indices, //triangle indices
93 DArrayList<int> contactListBroadPhase,
94 DArray<Pair<uint, uint>> mapping,
95 ElementOffset elementOffset)
97 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
98 if (tId >= count.size()) return;
100 auto& list_i = contactListBroadPhase[tId];
102 ElementType eleType = elementOffset.checkElementType(tId);
108 if (eleType == ET_BOX)
111 Box3D box = boxes[tId - elementOffset.boxIndex()];
112 Coord center = box.center;
116 Coord extent = box.extent;
119 points[0] = center - u * extent[0] - v * extent[1] - w * extent[2];
120 points[1] = center - u * extent[0] - v * extent[1] + w * extent[2];
121 points[2] = center - u * extent[0] + v * extent[1] - w * extent[2];
122 points[3] = center - u * extent[0] + v * extent[1] + w * extent[2];
123 points[4] = center + u * extent[0] - v * extent[1] - w * extent[2];
124 points[5] = center + u * extent[0] - v * extent[1] + w * extent[2];
125 points[6] = center + u * extent[0] + v * extent[1] - w * extent[2];
126 points[7] = center + u * extent[0] + v * extent[1] + w * extent[2];
128 else if (eleType == ET_SPHERE)
131 Sphere3D sp = spheres[tId - elementOffset.sphereIndex()];
134 points[0] = sp.center;
136 else if (eleType == ET_CAPSULE)
140 Capsule3D cap = capsules[tId - elementOffset.capsuleIndex()];
143 points[0] = cap.startPoint();
144 points[1] = cap.endPoint();
146 else if (eleType == ET_TET)
149 Tet3D tet = tets[tId - elementOffset.tetIndex()];
152 points[0] = tet.v[0];
153 points[1] = tet.v[1];
154 points[2] = tet.v[2];
155 points[3] = tet.v[3];
158 auto PROJECT_INSIDE = [](const TPoint3D<Real> p, const TTriangle3D<Real> triangle) -> bool
160 Real epsilon = Real(0.00001);
161 TPlane3D<Real> plane(triangle.v[0], triangle.normal());
163 TPoint3D<Real> proj = p.project(plane);
165 typename TTriangle3D<Real>::Param tParam;
166 bool bValid = triangle.computeBarycentrics(proj.origin, tParam);
169 return tParam.u > Real(0) - epsilon && tParam.u < Real(1) + epsilon && tParam.v > Real(0) - epsilon && tParam.v < Real(1) + epsilon && tParam.w > Real(0) - epsilon && tParam.w < Real(1) + epsilon;
178 for (uint i = 0; i < num; i++)
180 bool intersected = false;
181 Real d_min = -REAL_MAX;
185 TPoint3D<Real> pi = TPoint3D<Real>(points[i]);
186 for (uint j = 0; j < list_i.size(); j++)
188 TopologyModule::Triangle index = indices[list_i[j]];
189 TTriangle3D<Real> tj(vertices[index[0]], vertices[index[1]], vertices[index[2]]);
191 Coord nj = tj.normal();
193 if (PROJECT_INSIDE(pi, tj))
195 TPoint3D<Real> proj = pi.project(tj);
196 Real d = nj.dot(pi.origin - proj.origin) - d_hat;
200 //Find the closest triangle
204 proj_min = proj.origin;
216 contact.bodyId1 = mapping[tId].second;
217 contact.bodyId2 = -1;
218 contact.normal1 = normal_min;
219 contact.pos1 = proj_min + normal_min * d_min;
220 contact.contactType = ContactType::CT_BOUDNARY;
221 contact.interpenetration = -d_min;
223 nbr_cons[8 * tId + cnt] = contact;
232 template<typename ContactPair>
233 __global__ void CDTS_Narrow_Set(
234 DArray<ContactPair> nbr_cons,
235 DArray<ContactPair> nbr_cons_all,
239 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
240 if (tId >= counter.size()) return;
242 int offset = prefix[tId];
243 int size = counter[tId];
244 for (int n = 0; n < size; n++)
246 nbr_cons[offset + n] = nbr_cons_all[8 * tId + n];
250 template<typename TDataType>
251 void CollistionDetectionTriangleSet<TDataType>::compute()
253 //Initialize AABBs of discrete elements
254 auto de = this->inDiscreteElements()->constDataPtr();
256 int num = de->totalSize();
258 if (mQueryAABB.size() != num)
259 mQueryAABB.resize(num);
261 DArray<Box3D>& boxInGlobal = de->boxesInGlobal();
262 DArray<Sphere3D>& sphereInGlobal = de->spheresInGlobal();
263 DArray<Tet3D>& tetInGlobal = de->tetsInGlobal();
264 DArray<Capsule3D>& capsuleInGlobal = de->capsulesInGlobal();
266 ElementOffset elementOffset = de->calculateElementOffset();
269 CDTS_SetupAABBForRigidBodies,
277 mBroadPhaseCD->inSource()->assign(mQueryAABB);
279 auto ts = this->inTriangleSet()->constDataPtr();
281 auto& vertices = ts->getPoints();
282 auto& indices = ts->getTriangles();
284 //Initialize AABBs of the triangle set
285 if (this->inTriangleSet()->isModified())
287 if (mTriangleAABB.size() != indices.size())
288 mTriangleAABB.resize(indices.size());
290 cuExecute(indices.size(),
296 mBroadPhaseCD->inTarget()->assign(mTriangleAABB);
298 mBroadPhaseCD->update();
300 auto& contactList = mBroadPhaseCD->outContactList()->constData();
302 mBoundaryContactCounter.resize(num);
303 mContactBuffer.resize(8 * num);
307 mBoundaryContactCounter,
316 de->shape2RigidBodyMapping(),
319 mBoundaryContactCpy.assign(mBoundaryContactCounter);
321 uint sum = mReduce.accumulate(mBoundaryContactCounter.begin(), mBoundaryContactCounter.size());
322 mScan.exclusive(mBoundaryContactCounter, true);
324 this->outContacts()->resize(sum);
328 this->outContacts()->getData(),
330 mBoundaryContactCounter,
331 mBoundaryContactCpy);
334 DEFINE_CLASS(CollistionDetectionTriangleSet);