1#include "DiscreteElementsToTriangleSet.h"
5 typedef typename ::dyno::TOrientedBox3D<Real> Box3D;
7 template<typename TDataType>
8 DiscreteElementsToTriangleSet<TDataType>::DiscreteElementsToTriangleSet()
11 mStandardSphere.loadObjFile(getAssetPath() + "standard/standard_icosahedron.obj");
12 mStandardCapsule.loadObjFile(getAssetPath() + "standard/standard_capsule.obj");
15 template<typename Triangle>
16 __global__ void SetupCubeInstances(
17 DArray<Vec3f> vertices,
18 DArray<Triangle> indices,
24 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
25 if (tId >= boxes.size()) return;
28 Box3D box = boxes[idx];
30 Vec3f hx = box.u * box.extent[0];
31 Vec3f hy = box.v * box.extent[1];
32 Vec3f hz = box.w * box.extent[2];
40 Vec3f v0 = c - hx - hyz;
41 Vec3f v1 = c + hx - hyz;
42 Vec3f v2 = c + hxz - hy;
43 Vec3f v3 = c - hxy + hz;
45 Vec3f v4 = c - hxz + hy;
46 Vec3f v5 = c + hxy - hz;
47 Vec3f v6 = c + hx + hyz;
48 Vec3f v7 = c - hx + hyz;
50 vertices[pointOffset + idx * 8] = v0;
51 vertices[pointOffset + idx * 8 + 1] = v1;
52 vertices[pointOffset + idx * 8 + 2] = v2;
53 vertices[pointOffset + idx * 8 + 3] = v3;
54 vertices[pointOffset + idx * 8 + 4] = v4;
55 vertices[pointOffset + idx * 8 + 5] = v5;
56 vertices[pointOffset + idx * 8 + 6] = v6;
57 vertices[pointOffset + idx * 8 + 7] = v7;
59 uint offset = idx * 8 + pointOffset;
61 indices[indexOffset + idx * 12] = Triangle(offset + 0, offset + 1, offset + 2);
62 indices[indexOffset + idx * 12 + 1] = Triangle(offset + 0, offset + 2, offset + 3);
64 indices[indexOffset + idx * 12 + 2] = Triangle(offset + 0, offset + 4, offset + 5);
65 indices[indexOffset + idx * 12 + 3] = Triangle(offset + 0, offset + 5, offset + 1);
67 indices[indexOffset + idx * 12 + 4] = Triangle(offset + 4, offset + 7, offset + 6);
68 indices[indexOffset + idx * 12 + 5] = Triangle(offset + 4, offset + 6, offset + 5);
70 indices[indexOffset + idx * 12 + 6] = Triangle(offset + 1, offset + 5, offset + 6);
71 indices[indexOffset + idx * 12 + 7] = Triangle(offset + 1, offset + 6, offset + 2);
73 indices[indexOffset + idx * 12 + 8] = Triangle(offset + 2, offset + 6, offset + 7);
74 indices[indexOffset + idx * 12 + 9] = Triangle(offset + 2, offset + 7, offset + 3);
76 indices[indexOffset + idx * 12 + 10] = Triangle(offset + 0, offset + 3, offset + 7);
77 indices[indexOffset + idx * 12 + 11] = Triangle(offset + 0, offset + 7, offset + 4);
80 template<typename Triangle>
81 __global__ void SetupTetInstances(
82 DArray<Vec3f> vertices,
83 DArray<Triangle> indices,
89 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
90 if (tId >= tets.size()) return;
93 Tet3D tet = tets[idx];
100 vertices[pointOffset + idx * 4] = v0;
101 vertices[pointOffset + idx * 4 + 1] = v1;
102 vertices[pointOffset + idx * 4 + 2] = v2;
103 vertices[pointOffset + idx * 4 + 3] = v3;
105 uint offset = idx * 4 + pointOffset;
107 indices[indexOffset + idx * 4] = Triangle(offset + 0, offset + 1, offset + 2);
108 indices[indexOffset + idx * 4 + 1] = Triangle(offset + 0, offset + 1, offset + 3);
109 indices[indexOffset + idx * 4 + 2] = Triangle(offset + 1, offset + 2, offset + 3);
110 indices[indexOffset + idx * 4 + 3] = Triangle(offset + 0, offset + 2, offset + 3);
113 __global__ void SetupVerticesForSphereInstances(
114 DArray<Vec3f> vertices,
115 DArray<Vec3f> sphereVertices,
116 DArray<Sphere3D> sphereInstances,
120 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
121 if (tId >= sphereInstances.size() * sphereVertices.size()) return;
123 uint instanceId = tId / sphereVertices.size();
124 uint vertexId = tId % sphereVertices.size();
126 Sphere3D sphere = sphereInstances[instanceId];
128 Vec3f v = sphereVertices[vertexId];
129 vertices[pointOffset + tId] = sphere.center + sphere.radius * sphere.rotation.rotate(v);
132 template<typename Triangle>
133 __global__ void SetupIndicesForSphereInstances(
134 DArray<Triangle> indices,
135 DArray<Triangle> sphereIndices,
136 DArray<Sphere3D> sphereInstances,
137 uint vertexSize, //vertex size of the instance sphere
140 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
141 if (tId >= sphereInstances.size() * sphereIndices.size()) return;
143 uint instanceId = tId / sphereIndices.size();
144 uint indexId = tId % sphereIndices.size();
146 int vertexOffset = indexOffset + instanceId * vertexSize;
148 Triangle tIndex = sphereIndices[indexId];
149 indices[indexOffset + tId] = Triangle(tIndex[0] + vertexOffset, tIndex[1] + vertexOffset, tIndex[2] + vertexOffset);
152 __global__ void SetupVerticesForCapsuleInstances(
153 DArray<Vec3f> vertices,
154 DArray<Vec3f> capsuleVertices,
155 DArray<Capsule3D> capsuleInstances,
159 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
160 if (tId >= capsuleInstances.size() * capsuleVertices.size()) return;
162 uint instanceId = tId / capsuleVertices.size();
163 uint vertexId = tId % capsuleVertices.size();
165 Capsule3D capsule = capsuleInstances[instanceId];
166 float r = capsule.radius;
167 float h = capsule.halfLength;
168 auto rot = capsule.rotation.toMatrix3x3();
169 Vec3f center = capsule.center;
171 Vec3f v = capsuleVertices[vertexId];
172 Vec3f orignZ = Vec3f(0, 1, 0);
173 Vec3f newZ = Vec3f(0, h, 0);
177 vertices[pointOffset + tId] = rot * ((v - orignZ) * r + newZ) + center;
181 vertices[pointOffset + tId] = rot * ((v + orignZ) * r - newZ) + center;
185 vertices[pointOffset + tId] = rot * (v * Vec3f(r, h, r)) + center;
189 template<typename Triangle>
190 __global__ void SetupIndicesForCapsuleInstances(
191 DArray<Triangle> indices,
192 DArray<Triangle> capsuleIndices,
193 DArray<Capsule3D> capsuleInstances,
194 uint vertexSize, //vertex size of the instance sphere
198 int tId = threadIdx.x + (blockIdx.x * blockDim.x);
199 if (tId >= capsuleInstances.size() * capsuleIndices.size()) return;
201 uint instanceId = tId / capsuleIndices.size();
202 uint indexId = tId % capsuleIndices.size();
204 vertexOffset += instanceId * vertexSize;
206 Triangle tIndex = capsuleIndices[indexId];
207 indices[indexOffset + tId] = Triangle(tIndex[0] + vertexOffset, tIndex[1] + vertexOffset, tIndex[2] + vertexOffset);
210 template<typename TDataType>
211 bool DiscreteElementsToTriangleSet<TDataType>::apply()
213 if (this->outTriangleSet()->isEmpty())
215 this->outTriangleSet()->allocate();
218 auto inTopo = this->inDiscreteElements()->constDataPtr();
220 DArray<Box3D>& boxInGlobal = inTopo->boxesInGlobal();
221 DArray<Sphere3D>& sphereInGlobal = inTopo->spheresInGlobal();
222 DArray<Tet3D>& tetInGlobal = inTopo->tetsInGlobal();
223 DArray<Capsule3D>& capsuleInGlobal = inTopo->capsulesInGlobal();
225 ElementOffset elementOffset = inTopo->calculateElementOffset();
227 int numOfSpheres = sphereInGlobal.size();
228 int numofCaps = capsuleInGlobal.size();
229 int numOfBoxes = boxInGlobal.size();
230 int numOfTets = tetInGlobal.size();
232 auto triSet = this->outTriangleSet()->getDataPtr();
234 auto& vertices = triSet->getPoints();
235 auto& indices = triSet->getTriangles();
237 auto& sphereVertices = mStandardSphere.getPoints();
238 auto& sphereIndices = mStandardSphere.getTriangles();
240 auto& capsuleVertices = mStandardCapsule.getPoints();
241 auto& capsuleIndices = mStandardCapsule.getTriangles();
243 int numOfVertices = 8 * numOfBoxes + 4 * numOfTets + sphereVertices.size() * numOfSpheres + capsuleVertices.size() * numofCaps;
244 int numOfTriangles = 12 * numOfBoxes + 4 * numOfTets + sphereIndices.size() * numOfSpheres + capsuleIndices.size() * numofCaps;
246 vertices.resize(numOfVertices);
247 indices.resize(numOfTriangles);
249 uint vertexOffset = 0;
250 uint indexOffset = 0;
253 cuExecute(numOfSpheres * sphereVertices.size(),
254 SetupVerticesForSphereInstances,
259 elementOffset.sphereIndex());
261 cuExecute(numOfSpheres * sphereIndices.size(),
262 SetupIndicesForSphereInstances,
266 sphereVertices.size(),
269 vertexOffset += numOfSpheres * sphereVertices.size();
270 indexOffset += numOfSpheres * sphereIndices.size();
273 cuExecute(numOfBoxes,
280 elementOffset.boxIndex());
282 vertexOffset += numOfBoxes * 8;
283 indexOffset += numOfBoxes * 12;
293 elementOffset.tetIndex());
295 vertexOffset += numOfTets * 4;
296 indexOffset += numOfTets * 4;
298 cuExecute(numofCaps * capsuleVertices.size(),
299 SetupVerticesForCapsuleInstances,
304 elementOffset.capsuleIndex());
306 cuExecute(numofCaps * capsuleIndices.size(),
307 SetupIndicesForCapsuleInstances,
311 capsuleVertices.size(),
315 vertexOffset += numofCaps * capsuleVertices.size();
316 indexOffset += numofCaps * capsuleIndices.size();
318 this->outTriangleSet()->getDataPtr()->update();
323 DEFINE_CLASS(DiscreteElementsToTriangleSet);