1 #include "b3GpuNarrowPhase.h"
3 #include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h"
4 #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h"
5 #include "Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.h"
6 #include "Bullet3OpenCL/BroadphaseCollision/b3SapAabb.h"
8 #include "Bullet3Collision/NarrowPhaseCollision/b3Config.h"
9 #include "Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.h"
10 #include "Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.h"
11 #include "Bullet3Geometry/b3AabbUtil.h"
12 #include "Bullet3OpenCL/NarrowphaseCollision/b3BvhInfo.h"
14 #include "b3GpuNarrowPhaseInternalData.h"
15 #include "Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.h"
16 #include "Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.h"
18 b3GpuNarrowPhase::b3GpuNarrowPhase(cl_context ctx, cl_device_id device, cl_command_queue queue, const b3Config& config)
19 : m_data(0), m_planeBodyIndex(-1), m_static0Index(-1), m_context(ctx), m_device(device), m_queue(queue)
21 m_data = new b3GpuNarrowPhaseInternalData();
22 m_data->m_currentContactBuffer = 0;
24 memset(m_data, 0, sizeof(b3GpuNarrowPhaseInternalData));
26 m_data->m_config = config;
28 m_data->m_gpuSatCollision = new GpuSatCollision(ctx, device, queue);
30 m_data->m_triangleConvexPairs = new b3OpenCLArray<b3Int4>(m_context, m_queue, config.m_maxTriConvexPairCapacity);
32 //m_data->m_convexPairsOutGPU = new b3OpenCLArray<b3Int2>(ctx,queue,config.m_maxBroadphasePairs,false);
33 //m_data->m_planePairs = new b3OpenCLArray<b3Int2>(ctx,queue,config.m_maxBroadphasePairs,false);
35 m_data->m_pBufContactOutCPU = new b3AlignedObjectArray<b3Contact4>();
36 m_data->m_pBufContactOutCPU->resize(config.m_maxBroadphasePairs);
37 m_data->m_bodyBufferCPU = new b3AlignedObjectArray<b3RigidBodyData>();
38 m_data->m_bodyBufferCPU->resize(config.m_maxConvexBodies);
40 m_data->m_inertiaBufferCPU = new b3AlignedObjectArray<b3InertiaData>();
41 m_data->m_inertiaBufferCPU->resize(config.m_maxConvexBodies);
43 m_data->m_pBufContactBuffersGPU[0] = new b3OpenCLArray<b3Contact4>(ctx, queue, config.m_maxContactCapacity, true);
44 m_data->m_pBufContactBuffersGPU[1] = new b3OpenCLArray<b3Contact4>(ctx, queue, config.m_maxContactCapacity, true);
46 m_data->m_inertiaBufferGPU = new b3OpenCLArray<b3InertiaData>(ctx, queue, config.m_maxConvexBodies, false);
47 m_data->m_collidablesGPU = new b3OpenCLArray<b3Collidable>(ctx, queue, config.m_maxConvexShapes);
48 m_data->m_collidablesCPU.reserve(config.m_maxConvexShapes);
50 m_data->m_localShapeAABBCPU = new b3AlignedObjectArray<b3SapAabb>;
51 m_data->m_localShapeAABBGPU = new b3OpenCLArray<b3SapAabb>(ctx, queue, config.m_maxConvexShapes);
53 //m_data->m_solverDataGPU = adl::Solver<adl::TYPE_CL>::allocate(ctx,queue, config.m_maxBroadphasePairs,false);
54 m_data->m_bodyBufferGPU = new b3OpenCLArray<b3RigidBodyData>(ctx, queue, config.m_maxConvexBodies, false);
56 m_data->m_convexFacesGPU = new b3OpenCLArray<b3GpuFace>(ctx, queue, config.m_maxConvexShapes * config.m_maxFacesPerShape, false);
57 m_data->m_convexFaces.reserve(config.m_maxConvexShapes * config.m_maxFacesPerShape);
59 m_data->m_gpuChildShapes = new b3OpenCLArray<b3GpuChildShape>(ctx, queue, config.m_maxCompoundChildShapes, false);
61 m_data->m_convexPolyhedraGPU = new b3OpenCLArray<b3ConvexPolyhedronData>(ctx, queue, config.m_maxConvexShapes, false);
62 m_data->m_convexPolyhedra.reserve(config.m_maxConvexShapes);
64 m_data->m_uniqueEdgesGPU = new b3OpenCLArray<b3Vector3>(ctx, queue, config.m_maxConvexUniqueEdges, true);
65 m_data->m_uniqueEdges.reserve(config.m_maxConvexUniqueEdges);
67 m_data->m_convexVerticesGPU = new b3OpenCLArray<b3Vector3>(ctx, queue, config.m_maxConvexVertices, true);
68 m_data->m_convexVertices.reserve(config.m_maxConvexVertices);
70 m_data->m_convexIndicesGPU = new b3OpenCLArray<int>(ctx, queue, config.m_maxConvexIndices, true);
71 m_data->m_convexIndices.reserve(config.m_maxConvexIndices);
73 m_data->m_worldVertsB1GPU = new b3OpenCLArray<b3Vector3>(ctx, queue, config.m_maxConvexBodies * config.m_maxVerticesPerFace);
74 m_data->m_clippingFacesOutGPU = new b3OpenCLArray<b3Int4>(ctx, queue, config.m_maxConvexBodies);
75 m_data->m_worldNormalsAGPU = new b3OpenCLArray<b3Vector3>(ctx, queue, config.m_maxConvexBodies);
76 m_data->m_worldVertsA1GPU = new b3OpenCLArray<b3Vector3>(ctx, queue, config.m_maxConvexBodies * config.m_maxVerticesPerFace);
77 m_data->m_worldVertsB2GPU = new b3OpenCLArray<b3Vector3>(ctx, queue, config.m_maxConvexBodies * config.m_maxVerticesPerFace);
79 m_data->m_convexData = new b3AlignedObjectArray<b3ConvexUtility*>();
81 m_data->m_convexData->resize(config.m_maxConvexShapes);
82 m_data->m_convexPolyhedra.resize(config.m_maxConvexShapes);
84 m_data->m_numAcceleratedShapes = 0;
85 m_data->m_numAcceleratedRigidBodies = 0;
87 m_data->m_subTreesGPU = new b3OpenCLArray<b3BvhSubtreeInfo>(this->m_context, this->m_queue);
88 m_data->m_treeNodesGPU = new b3OpenCLArray<b3QuantizedBvhNode>(this->m_context, this->m_queue);
89 m_data->m_bvhInfoGPU = new b3OpenCLArray<b3BvhInfo>(this->m_context, this->m_queue);
91 //m_data->m_contactCGPU = new b3OpenCLArray<Constraint4>(ctx,queue,config.m_maxBroadphasePairs,false);
92 //m_data->m_frictionCGPU = new b3OpenCLArray<adl::Solver<adl::TYPE_CL>::allocateFrictionConstraint( m_data->m_deviceCL, config.m_maxBroadphasePairs);
95 b3GpuNarrowPhase::~b3GpuNarrowPhase()
97 delete m_data->m_gpuSatCollision;
99 delete m_data->m_triangleConvexPairs;
100 //delete m_data->m_convexPairsOutGPU;
101 //delete m_data->m_planePairs;
102 delete m_data->m_pBufContactOutCPU;
103 delete m_data->m_bodyBufferCPU;
104 delete m_data->m_inertiaBufferCPU;
105 delete m_data->m_pBufContactBuffersGPU[0];
106 delete m_data->m_pBufContactBuffersGPU[1];
108 delete m_data->m_inertiaBufferGPU;
109 delete m_data->m_collidablesGPU;
110 delete m_data->m_localShapeAABBCPU;
111 delete m_data->m_localShapeAABBGPU;
112 delete m_data->m_bodyBufferGPU;
113 delete m_data->m_convexFacesGPU;
114 delete m_data->m_gpuChildShapes;
115 delete m_data->m_convexPolyhedraGPU;
116 delete m_data->m_uniqueEdgesGPU;
117 delete m_data->m_convexVerticesGPU;
118 delete m_data->m_convexIndicesGPU;
119 delete m_data->m_worldVertsB1GPU;
120 delete m_data->m_clippingFacesOutGPU;
121 delete m_data->m_worldNormalsAGPU;
122 delete m_data->m_worldVertsA1GPU;
123 delete m_data->m_worldVertsB2GPU;
125 delete m_data->m_bvhInfoGPU;
127 for (int i = 0; i < m_data->m_bvhData.size(); i++)
129 delete m_data->m_bvhData[i];
131 for (int i = 0; i < m_data->m_meshInterfaces.size(); i++)
133 delete m_data->m_meshInterfaces[i];
135 m_data->m_meshInterfaces.clear();
136 m_data->m_bvhData.clear();
137 delete m_data->m_treeNodesGPU;
138 delete m_data->m_subTreesGPU;
140 delete m_data->m_convexData;
144 int b3GpuNarrowPhase::allocateCollidable()
146 int curSize = m_data->m_collidablesCPU.size();
147 if (curSize < m_data->m_config.m_maxConvexShapes)
149 m_data->m_collidablesCPU.expand();
154 b3Error("allocateCollidable out-of-range %d\n", m_data->m_config.m_maxConvexShapes);
159 int b3GpuNarrowPhase::registerSphereShape(float radius)
161 int collidableIndex = allocateCollidable();
162 if (collidableIndex < 0)
163 return collidableIndex;
165 b3Collidable& col = getCollidableCpu(collidableIndex);
166 col.m_shapeType = SHAPE_SPHERE;
167 col.m_shapeIndex = 0;
168 col.m_radius = radius;
170 if (col.m_shapeIndex >= 0)
173 b3Vector3 myAabbMin = b3MakeVector3(-radius, -radius, -radius);
174 b3Vector3 myAabbMax = b3MakeVector3(radius, radius, radius);
176 aabb.m_min[0] = myAabbMin[0]; //s_convexHeightField->m_aabb.m_min.x;
177 aabb.m_min[1] = myAabbMin[1]; //s_convexHeightField->m_aabb.m_min.y;
178 aabb.m_min[2] = myAabbMin[2]; //s_convexHeightField->m_aabb.m_min.z;
179 aabb.m_minIndices[3] = 0;
181 aabb.m_max[0] = myAabbMax[0]; //s_convexHeightField->m_aabb.m_max.x;
182 aabb.m_max[1] = myAabbMax[1]; //s_convexHeightField->m_aabb.m_max.y;
183 aabb.m_max[2] = myAabbMax[2]; //s_convexHeightField->m_aabb.m_max.z;
184 aabb.m_signedMaxIndices[3] = 0;
186 m_data->m_localShapeAABBCPU->push_back(aabb);
187 // m_data->m_localShapeAABBGPU->push_back(aabb);
191 return collidableIndex;
194 int b3GpuNarrowPhase::registerFace(const b3Vector3& faceNormal, float faceConstant)
196 int faceOffset = m_data->m_convexFaces.size();
197 b3GpuFace& face = m_data->m_convexFaces.expand();
198 face.m_plane = b3MakeVector3(faceNormal.x, faceNormal.y, faceNormal.z, faceConstant);
202 int b3GpuNarrowPhase::registerPlaneShape(const b3Vector3& planeNormal, float planeConstant)
204 int collidableIndex = allocateCollidable();
205 if (collidableIndex < 0)
206 return collidableIndex;
208 b3Collidable& col = getCollidableCpu(collidableIndex);
209 col.m_shapeType = SHAPE_PLANE;
210 col.m_shapeIndex = registerFace(planeNormal, planeConstant);
211 col.m_radius = planeConstant;
213 if (col.m_shapeIndex >= 0)
216 aabb.m_min[0] = -1e30f;
217 aabb.m_min[1] = -1e30f;
218 aabb.m_min[2] = -1e30f;
219 aabb.m_minIndices[3] = 0;
221 aabb.m_max[0] = 1e30f;
222 aabb.m_max[1] = 1e30f;
223 aabb.m_max[2] = 1e30f;
224 aabb.m_signedMaxIndices[3] = 0;
226 m_data->m_localShapeAABBCPU->push_back(aabb);
227 // m_data->m_localShapeAABBGPU->push_back(aabb);
231 return collidableIndex;
234 int b3GpuNarrowPhase::registerConvexHullShapeInternal(b3ConvexUtility* convexPtr, b3Collidable& col)
236 m_data->m_convexData->resize(m_data->m_numAcceleratedShapes + 1);
237 m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes + 1);
239 b3ConvexPolyhedronData& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size() - 1);
240 convex.mC = convexPtr->mC;
241 convex.mE = convexPtr->mE;
242 convex.m_extents = convexPtr->m_extents;
243 convex.m_localCenter = convexPtr->m_localCenter;
244 convex.m_radius = convexPtr->m_radius;
246 convex.m_numUniqueEdges = convexPtr->m_uniqueEdges.size();
247 int edgeOffset = m_data->m_uniqueEdges.size();
248 convex.m_uniqueEdgesOffset = edgeOffset;
250 m_data->m_uniqueEdges.resize(edgeOffset + convex.m_numUniqueEdges);
254 for (i = 0; i < convexPtr->m_uniqueEdges.size(); i++)
256 m_data->m_uniqueEdges[edgeOffset + i] = convexPtr->m_uniqueEdges[i];
259 int faceOffset = m_data->m_convexFaces.size();
260 convex.m_faceOffset = faceOffset;
261 convex.m_numFaces = convexPtr->m_faces.size();
263 m_data->m_convexFaces.resize(faceOffset + convex.m_numFaces);
265 for (i = 0; i < convexPtr->m_faces.size(); i++)
267 m_data->m_convexFaces[convex.m_faceOffset + i].m_plane = b3MakeVector3(convexPtr->m_faces[i].m_plane[0],
268 convexPtr->m_faces[i].m_plane[1],
269 convexPtr->m_faces[i].m_plane[2],
270 convexPtr->m_faces[i].m_plane[3]);
272 int indexOffset = m_data->m_convexIndices.size();
273 int numIndices = convexPtr->m_faces[i].m_indices.size();
274 m_data->m_convexFaces[convex.m_faceOffset + i].m_numIndices = numIndices;
275 m_data->m_convexFaces[convex.m_faceOffset + i].m_indexOffset = indexOffset;
276 m_data->m_convexIndices.resize(indexOffset + numIndices);
277 for (int p = 0; p < numIndices; p++)
279 m_data->m_convexIndices[indexOffset + p] = convexPtr->m_faces[i].m_indices[p];
283 convex.m_numVertices = convexPtr->m_vertices.size();
284 int vertexOffset = m_data->m_convexVertices.size();
285 convex.m_vertexOffset = vertexOffset;
287 m_data->m_convexVertices.resize(vertexOffset + convex.m_numVertices);
288 for (int i = 0; i < convexPtr->m_vertices.size(); i++)
290 m_data->m_convexVertices[vertexOffset + i] = convexPtr->m_vertices[i];
293 (*m_data->m_convexData)[m_data->m_numAcceleratedShapes] = convexPtr;
295 return m_data->m_numAcceleratedShapes++;
298 int b3GpuNarrowPhase::registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling)
300 b3AlignedObjectArray<b3Vector3> verts;
302 unsigned char* vts = (unsigned char*)vertices;
303 for (int i = 0; i < numVertices; i++)
305 float* vertex = (float*)&vts[i * strideInBytes];
306 verts.push_back(b3MakeVector3(vertex[0] * scaling[0], vertex[1] * scaling[1], vertex[2] * scaling[2]));
309 b3ConvexUtility* utilPtr = new b3ConvexUtility();
313 utilPtr->initializePolyhedralFeatures(&verts[0], verts.size(), merge);
316 int collidableIndex = registerConvexHullShape(utilPtr);
318 return collidableIndex;
321 int b3GpuNarrowPhase::registerConvexHullShape(b3ConvexUtility* utilPtr)
323 int collidableIndex = allocateCollidable();
324 if (collidableIndex < 0)
325 return collidableIndex;
327 b3Collidable& col = getCollidableCpu(collidableIndex);
328 col.m_shapeType = SHAPE_CONVEX_HULL;
329 col.m_shapeIndex = -1;
332 b3Vector3 localCenter = b3MakeVector3(0, 0, 0);
333 for (int i = 0; i < utilPtr->m_vertices.size(); i++)
334 localCenter += utilPtr->m_vertices[i];
335 localCenter *= (1.f / utilPtr->m_vertices.size());
336 utilPtr->m_localCenter = localCenter;
338 col.m_shapeIndex = registerConvexHullShapeInternal(utilPtr, col);
341 if (col.m_shapeIndex >= 0)
345 b3Vector3 myAabbMin = b3MakeVector3(1e30f, 1e30f, 1e30f);
346 b3Vector3 myAabbMax = b3MakeVector3(-1e30f, -1e30f, -1e30f);
348 for (int i = 0; i < utilPtr->m_vertices.size(); i++)
350 myAabbMin.setMin(utilPtr->m_vertices[i]);
351 myAabbMax.setMax(utilPtr->m_vertices[i]);
353 aabb.m_min[0] = myAabbMin[0];
354 aabb.m_min[1] = myAabbMin[1];
355 aabb.m_min[2] = myAabbMin[2];
356 aabb.m_minIndices[3] = 0;
358 aabb.m_max[0] = myAabbMax[0];
359 aabb.m_max[1] = myAabbMax[1];
360 aabb.m_max[2] = myAabbMax[2];
361 aabb.m_signedMaxIndices[3] = 0;
363 m_data->m_localShapeAABBCPU->push_back(aabb);
364 // m_data->m_localShapeAABBGPU->push_back(aabb);
367 return collidableIndex;
370 int b3GpuNarrowPhase::registerCompoundShape(b3AlignedObjectArray<b3GpuChildShape>* childShapes)
372 int collidableIndex = allocateCollidable();
373 if (collidableIndex < 0)
374 return collidableIndex;
376 b3Collidable& col = getCollidableCpu(collidableIndex);
377 col.m_shapeType = SHAPE_COMPOUND_OF_CONVEX_HULLS;
378 col.m_shapeIndex = m_data->m_cpuChildShapes.size();
379 col.m_compoundBvhIndex = m_data->m_bvhInfoCPU.size();
382 b3Assert(col.m_shapeIndex + childShapes->size() < m_data->m_config.m_maxCompoundChildShapes);
383 for (int i = 0; i < childShapes->size(); i++)
385 m_data->m_cpuChildShapes.push_back(childShapes->at(i));
389 col.m_numChildShapes = childShapes->size();
391 b3SapAabb aabbLocalSpace;
392 b3Vector3 myAabbMin = b3MakeVector3(1e30f, 1e30f, 1e30f);
393 b3Vector3 myAabbMax = b3MakeVector3(-1e30f, -1e30f, -1e30f);
395 b3AlignedObjectArray<b3Aabb> childLocalAabbs;
396 childLocalAabbs.resize(childShapes->size());
398 //compute local AABB of the compound of all children
399 for (int i = 0; i < childShapes->size(); i++)
401 int childColIndex = childShapes->at(i).m_shapeIndex;
402 //b3Collidable& childCol = getCollidableCpu(childColIndex);
403 b3SapAabb aabbLoc = m_data->m_localShapeAABBCPU->at(childColIndex);
405 b3Vector3 childLocalAabbMin = b3MakeVector3(aabbLoc.m_min[0], aabbLoc.m_min[1], aabbLoc.m_min[2]);
406 b3Vector3 childLocalAabbMax = b3MakeVector3(aabbLoc.m_max[0], aabbLoc.m_max[1], aabbLoc.m_max[2]);
407 b3Vector3 aMin, aMax;
408 b3Scalar margin(0.f);
410 childTr.setIdentity();
412 childTr.setOrigin(childShapes->at(i).m_childPosition);
413 childTr.setRotation(b3Quaternion(childShapes->at(i).m_childOrientation));
414 b3TransformAabb(childLocalAabbMin, childLocalAabbMax, margin, childTr, aMin, aMax);
415 myAabbMin.setMin(aMin);
416 myAabbMax.setMax(aMax);
417 childLocalAabbs[i].m_min[0] = aMin[0];
418 childLocalAabbs[i].m_min[1] = aMin[1];
419 childLocalAabbs[i].m_min[2] = aMin[2];
420 childLocalAabbs[i].m_min[3] = 0;
421 childLocalAabbs[i].m_max[0] = aMax[0];
422 childLocalAabbs[i].m_max[1] = aMax[1];
423 childLocalAabbs[i].m_max[2] = aMax[2];
424 childLocalAabbs[i].m_max[3] = 0;
427 aabbLocalSpace.m_min[0] = myAabbMin[0]; //s_convexHeightField->m_aabb.m_min.x;
428 aabbLocalSpace.m_min[1] = myAabbMin[1]; //s_convexHeightField->m_aabb.m_min.y;
429 aabbLocalSpace.m_min[2] = myAabbMin[2]; //s_convexHeightField->m_aabb.m_min.z;
430 aabbLocalSpace.m_minIndices[3] = 0;
432 aabbLocalSpace.m_max[0] = myAabbMax[0]; //s_convexHeightField->m_aabb.m_max.x;
433 aabbLocalSpace.m_max[1] = myAabbMax[1]; //s_convexHeightField->m_aabb.m_max.y;
434 aabbLocalSpace.m_max[2] = myAabbMax[2]; //s_convexHeightField->m_aabb.m_max.z;
435 aabbLocalSpace.m_signedMaxIndices[3] = 0;
437 m_data->m_localShapeAABBCPU->push_back(aabbLocalSpace);
439 b3QuantizedBvh* bvh = new b3QuantizedBvh;
440 bvh->setQuantizationValues(myAabbMin, myAabbMax);
441 QuantizedNodeArray& nodes = bvh->getLeafNodeArray();
442 int numNodes = childShapes->size();
444 for (int i = 0; i < numNodes; i++)
446 b3QuantizedBvhNode node;
447 b3Vector3 aabbMin, aabbMax;
448 aabbMin = (b3Vector3&)childLocalAabbs[i].m_min;
449 aabbMax = (b3Vector3&)childLocalAabbs[i].m_max;
451 bvh->quantize(&node.m_quantizedAabbMin[0], aabbMin, 0);
452 bvh->quantize(&node.m_quantizedAabbMax[0], aabbMax, 1);
454 node.m_escapeIndexOrTriangleIndex = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | i;
455 nodes.push_back(node);
457 bvh->buildInternal();
459 int numSubTrees = bvh->getSubtreeInfoArray().size();
461 //void setQuantizationValues(const b3Vector3& bvhAabbMin,const b3Vector3& bvhAabbMax,b3Scalar quantizationMargin=b3Scalar(1.0));
462 //QuantizedNodeArray& getLeafNodeArray() { return m_quantizedLeafNodes; }
463 ///buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialized
464 //void buildInternal();
468 bvhInfo.m_aabbMin = bvh->m_bvhAabbMin;
469 bvhInfo.m_aabbMax = bvh->m_bvhAabbMax;
470 bvhInfo.m_quantization = bvh->m_bvhQuantization;
471 bvhInfo.m_numNodes = numNodes;
472 bvhInfo.m_numSubTrees = numSubTrees;
473 bvhInfo.m_nodeOffset = m_data->m_treeNodesCPU.size();
474 bvhInfo.m_subTreeOffset = m_data->m_subTreesCPU.size();
476 int numNewNodes = bvh->getQuantizedNodeArray().size();
478 for (int i = 0; i < numNewNodes - 1; i++)
480 if (bvh->getQuantizedNodeArray()[i].isLeafNode())
482 int orgIndex = bvh->getQuantizedNodeArray()[i].getTriangleIndex();
484 b3Vector3 nodeMinVec = bvh->unQuantize(bvh->getQuantizedNodeArray()[i].m_quantizedAabbMin);
485 b3Vector3 nodeMaxVec = bvh->unQuantize(bvh->getQuantizedNodeArray()[i].m_quantizedAabbMax);
487 for (int c = 0; c < 3; c++)
489 if (childLocalAabbs[orgIndex].m_min[c] < nodeMinVec[c])
491 printf("min org (%f) and new (%f) ? at i:%d,c:%d\n", childLocalAabbs[i].m_min[c], nodeMinVec[c], i, c);
493 if (childLocalAabbs[orgIndex].m_max[c] > nodeMaxVec[c])
495 printf("max org (%f) and new (%f) ? at i:%d,c:%d\n", childLocalAabbs[i].m_max[c], nodeMaxVec[c], i, c);
501 m_data->m_bvhInfoCPU.push_back(bvhInfo);
503 int numNewSubtrees = bvh->getSubtreeInfoArray().size();
504 m_data->m_subTreesCPU.reserve(m_data->m_subTreesCPU.size() + numNewSubtrees);
505 for (int i = 0; i < numNewSubtrees; i++)
507 m_data->m_subTreesCPU.push_back(bvh->getSubtreeInfoArray()[i]);
509 int numNewTreeNodes = bvh->getQuantizedNodeArray().size();
511 for (int i = 0; i < numNewTreeNodes; i++)
513 m_data->m_treeNodesCPU.push_back(bvh->getQuantizedNodeArray()[i]);
516 // m_data->m_localShapeAABBGPU->push_back(aabbWS);
518 return collidableIndex;
521 int b3GpuNarrowPhase::registerConcaveMesh(b3AlignedObjectArray<b3Vector3>* vertices, b3AlignedObjectArray<int>* indices, const float* scaling1)
523 b3Vector3 scaling = b3MakeVector3(scaling1[0], scaling1[1], scaling1[2]);
525 int collidableIndex = allocateCollidable();
526 if (collidableIndex < 0)
527 return collidableIndex;
529 b3Collidable& col = getCollidableCpu(collidableIndex);
531 col.m_shapeType = SHAPE_CONCAVE_TRIMESH;
532 col.m_shapeIndex = registerConcaveMeshShape(vertices, indices, col, scaling);
533 col.m_bvhIndex = m_data->m_bvhInfoCPU.size();
536 b3Vector3 myAabbMin = b3MakeVector3(1e30f, 1e30f, 1e30f);
537 b3Vector3 myAabbMax = b3MakeVector3(-1e30f, -1e30f, -1e30f);
539 for (int i = 0; i < vertices->size(); i++)
541 b3Vector3 vtx(vertices->at(i) * scaling);
542 myAabbMin.setMin(vtx);
543 myAabbMax.setMax(vtx);
545 aabb.m_min[0] = myAabbMin[0];
546 aabb.m_min[1] = myAabbMin[1];
547 aabb.m_min[2] = myAabbMin[2];
548 aabb.m_minIndices[3] = 0;
550 aabb.m_max[0] = myAabbMax[0];
551 aabb.m_max[1] = myAabbMax[1];
552 aabb.m_max[2] = myAabbMax[2];
553 aabb.m_signedMaxIndices[3] = 0;
555 m_data->m_localShapeAABBCPU->push_back(aabb);
556 // m_data->m_localShapeAABBGPU->push_back(aabb);
558 b3OptimizedBvh* bvh = new b3OptimizedBvh();
559 //void b3OptimizedBvh::build(b3StridingMeshInterface* triangles, bool useQuantizedAabbCompression, const b3Vector3& bvhAabbMin, const b3Vector3& bvhAabbMax)
561 bool useQuantizedAabbCompression = true;
562 b3TriangleIndexVertexArray* meshInterface = new b3TriangleIndexVertexArray();
563 m_data->m_meshInterfaces.push_back(meshInterface);
565 mesh.m_numTriangles = indices->size() / 3;
566 mesh.m_numVertices = vertices->size();
567 mesh.m_vertexBase = (const unsigned char*)&vertices->at(0).x;
568 mesh.m_vertexStride = sizeof(b3Vector3);
569 mesh.m_triangleIndexStride = 3 * sizeof(int); // or sizeof(int)
570 mesh.m_triangleIndexBase = (const unsigned char*)&indices->at(0);
572 meshInterface->addIndexedMesh(mesh);
573 bvh->build(meshInterface, useQuantizedAabbCompression, (b3Vector3&)aabb.m_min, (b3Vector3&)aabb.m_max);
574 m_data->m_bvhData.push_back(bvh);
575 int numNodes = bvh->getQuantizedNodeArray().size();
576 //b3OpenCLArray<b3QuantizedBvhNode>* treeNodesGPU = new b3OpenCLArray<b3QuantizedBvhNode>(this->m_context,this->m_queue,numNodes);
577 int numSubTrees = bvh->getSubtreeInfoArray().size();
581 bvhInfo.m_aabbMin = bvh->m_bvhAabbMin;
582 bvhInfo.m_aabbMax = bvh->m_bvhAabbMax;
583 bvhInfo.m_quantization = bvh->m_bvhQuantization;
584 bvhInfo.m_numNodes = numNodes;
585 bvhInfo.m_numSubTrees = numSubTrees;
586 bvhInfo.m_nodeOffset = m_data->m_treeNodesCPU.size();
587 bvhInfo.m_subTreeOffset = m_data->m_subTreesCPU.size();
589 m_data->m_bvhInfoCPU.push_back(bvhInfo);
591 int numNewSubtrees = bvh->getSubtreeInfoArray().size();
592 m_data->m_subTreesCPU.reserve(m_data->m_subTreesCPU.size() + numNewSubtrees);
593 for (int i = 0; i < numNewSubtrees; i++)
595 m_data->m_subTreesCPU.push_back(bvh->getSubtreeInfoArray()[i]);
597 int numNewTreeNodes = bvh->getQuantizedNodeArray().size();
599 for (int i = 0; i < numNewTreeNodes; i++)
601 m_data->m_treeNodesCPU.push_back(bvh->getQuantizedNodeArray()[i]);
604 return collidableIndex;
607 int b3GpuNarrowPhase::registerConcaveMeshShape(b3AlignedObjectArray<b3Vector3>* vertices, b3AlignedObjectArray<int>* indices, b3Collidable& col, const float* scaling1)
609 b3Vector3 scaling = b3MakeVector3(scaling1[0], scaling1[1], scaling1[2]);
611 m_data->m_convexData->resize(m_data->m_numAcceleratedShapes + 1);
612 m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes + 1);
614 b3ConvexPolyhedronData& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size() - 1);
615 convex.mC = b3MakeVector3(0, 0, 0);
616 convex.mE = b3MakeVector3(0, 0, 0);
617 convex.m_extents = b3MakeVector3(0, 0, 0);
618 convex.m_localCenter = b3MakeVector3(0, 0, 0);
619 convex.m_radius = 0.f;
621 convex.m_numUniqueEdges = 0;
622 int edgeOffset = m_data->m_uniqueEdges.size();
623 convex.m_uniqueEdgesOffset = edgeOffset;
625 int faceOffset = m_data->m_convexFaces.size();
626 convex.m_faceOffset = faceOffset;
628 convex.m_numFaces = indices->size() / 3;
629 m_data->m_convexFaces.resize(faceOffset + convex.m_numFaces);
630 m_data->m_convexIndices.reserve(convex.m_numFaces * 3);
631 for (int i = 0; i < convex.m_numFaces; i++)
635 //printf("i=%d out of %d", i,convex.m_numFaces);
637 b3Vector3 vert0(vertices->at(indices->at(i * 3)) * scaling);
638 b3Vector3 vert1(vertices->at(indices->at(i * 3 + 1)) * scaling);
639 b3Vector3 vert2(vertices->at(indices->at(i * 3 + 2)) * scaling);
641 b3Vector3 normal = ((vert1 - vert0).cross(vert2 - vert0)).normalize();
642 b3Scalar c = -(normal.dot(vert0));
644 m_data->m_convexFaces[convex.m_faceOffset + i].m_plane = b3MakeVector4(normal.x, normal.y, normal.z, c);
645 int indexOffset = m_data->m_convexIndices.size();
647 m_data->m_convexFaces[convex.m_faceOffset + i].m_numIndices = numIndices;
648 m_data->m_convexFaces[convex.m_faceOffset + i].m_indexOffset = indexOffset;
649 m_data->m_convexIndices.resize(indexOffset + numIndices);
650 for (int p = 0; p < numIndices; p++)
652 int vi = indices->at(i * 3 + p);
653 m_data->m_convexIndices[indexOffset + p] = vi; //convexPtr->m_faces[i].m_indices[p];
657 convex.m_numVertices = vertices->size();
658 int vertexOffset = m_data->m_convexVertices.size();
659 convex.m_vertexOffset = vertexOffset;
660 m_data->m_convexVertices.resize(vertexOffset + convex.m_numVertices);
661 for (int i = 0; i < vertices->size(); i++)
663 m_data->m_convexVertices[vertexOffset + i] = vertices->at(i) * scaling;
666 (*m_data->m_convexData)[m_data->m_numAcceleratedShapes] = 0;
668 return m_data->m_numAcceleratedShapes++;
671 cl_mem b3GpuNarrowPhase::getBodiesGpu()
673 return (cl_mem)m_data->m_bodyBufferGPU->getBufferCL();
676 const struct b3RigidBodyData* b3GpuNarrowPhase::getBodiesCpu() const
678 return &m_data->m_bodyBufferCPU->at(0);
681 int b3GpuNarrowPhase::getNumBodiesGpu() const
683 return m_data->m_bodyBufferGPU->size();
686 cl_mem b3GpuNarrowPhase::getBodyInertiasGpu()
688 return (cl_mem)m_data->m_inertiaBufferGPU->getBufferCL();
691 int b3GpuNarrowPhase::getNumBodyInertiasGpu() const
693 return m_data->m_inertiaBufferGPU->size();
696 b3Collidable& b3GpuNarrowPhase::getCollidableCpu(int collidableIndex)
698 return m_data->m_collidablesCPU[collidableIndex];
701 const b3Collidable& b3GpuNarrowPhase::getCollidableCpu(int collidableIndex) const
703 return m_data->m_collidablesCPU[collidableIndex];
706 cl_mem b3GpuNarrowPhase::getCollidablesGpu()
708 return m_data->m_collidablesGPU->getBufferCL();
711 const struct b3Collidable* b3GpuNarrowPhase::getCollidablesCpu() const
713 if (m_data->m_collidablesCPU.size())
714 return &m_data->m_collidablesCPU[0];
718 const struct b3SapAabb* b3GpuNarrowPhase::getLocalSpaceAabbsCpu() const
720 if (m_data->m_localShapeAABBCPU->size())
722 return &m_data->m_localShapeAABBCPU->at(0);
727 cl_mem b3GpuNarrowPhase::getAabbLocalSpaceBufferGpu()
729 return m_data->m_localShapeAABBGPU->getBufferCL();
731 int b3GpuNarrowPhase::getNumCollidablesGpu() const
733 return m_data->m_collidablesGPU->size();
736 int b3GpuNarrowPhase::getNumContactsGpu() const
738 return m_data->m_pBufContactBuffersGPU[m_data->m_currentContactBuffer]->size();
740 cl_mem b3GpuNarrowPhase::getContactsGpu()
742 return m_data->m_pBufContactBuffersGPU[m_data->m_currentContactBuffer]->getBufferCL();
745 const b3Contact4* b3GpuNarrowPhase::getContactsCPU() const
747 m_data->m_pBufContactBuffersGPU[m_data->m_currentContactBuffer]->copyToHost(*m_data->m_pBufContactOutCPU);
748 return &m_data->m_pBufContactOutCPU->at(0);
751 void b3GpuNarrowPhase::computeContacts(cl_mem broadphasePairs, int numBroadphasePairs, cl_mem aabbsWorldSpace, int numObjects)
753 cl_mem aabbsLocalSpace = m_data->m_localShapeAABBGPU->getBufferCL();
758 m_data->m_currentContactBuffer = 1 - m_data->m_currentContactBuffer;
760 //int curSize = m_data->m_pBufContactBuffersGPU[m_data->m_currentContactBuffer]->size();
762 int maxTriConvexPairCapacity = m_data->m_config.m_maxTriConvexPairCapacity;
763 int numTriConvexPairsOut = 0;
765 b3OpenCLArray<b3Int4> broadphasePairsGPU(m_context, m_queue);
766 broadphasePairsGPU.setFromOpenCLBuffer(broadphasePairs, numBroadphasePairs);
768 b3OpenCLArray<b3Aabb> clAabbArrayWorldSpace(this->m_context, this->m_queue);
769 clAabbArrayWorldSpace.setFromOpenCLBuffer(aabbsWorldSpace, numObjects);
771 b3OpenCLArray<b3Aabb> clAabbArrayLocalSpace(this->m_context, this->m_queue);
772 clAabbArrayLocalSpace.setFromOpenCLBuffer(aabbsLocalSpace, numObjects);
774 m_data->m_gpuSatCollision->computeConvexConvexContactsGPUSAT(
775 &broadphasePairsGPU, numBroadphasePairs,
776 m_data->m_bodyBufferGPU,
777 m_data->m_pBufContactBuffersGPU[m_data->m_currentContactBuffer],
779 m_data->m_pBufContactBuffersGPU[1 - m_data->m_currentContactBuffer],
780 m_data->m_config.m_maxContactCapacity,
781 m_data->m_config.m_compoundPairCapacity,
782 *m_data->m_convexPolyhedraGPU,
783 *m_data->m_convexVerticesGPU,
784 *m_data->m_uniqueEdgesGPU,
785 *m_data->m_convexFacesGPU,
786 *m_data->m_convexIndicesGPU,
787 *m_data->m_collidablesGPU,
788 *m_data->m_gpuChildShapes,
789 clAabbArrayWorldSpace,
790 clAabbArrayLocalSpace,
791 *m_data->m_worldVertsB1GPU,
792 *m_data->m_clippingFacesOutGPU,
793 *m_data->m_worldNormalsAGPU,
794 *m_data->m_worldVertsA1GPU,
795 *m_data->m_worldVertsB2GPU,
797 m_data->m_treeNodesGPU,
798 m_data->m_subTreesGPU,
799 m_data->m_bvhInfoGPU,
801 maxTriConvexPairCapacity,
802 *m_data->m_triangleConvexPairs,
803 numTriConvexPairsOut);
805 /*b3AlignedObjectArray<b3Int4> broadphasePairsCPU;
806 broadphasePairsGPU.copyToHost(broadphasePairsCPU);
807 printf("checking pairs\n");
811 const b3SapAabb& b3GpuNarrowPhase::getLocalSpaceAabb(int collidableIndex) const
813 return m_data->m_localShapeAABBCPU->at(collidableIndex);
816 int b3GpuNarrowPhase::registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation, const float* aabbMinPtr, const float* aabbMaxPtr, bool writeToGpu)
818 b3Vector3 aabbMin = b3MakeVector3(aabbMinPtr[0], aabbMinPtr[1], aabbMinPtr[2]);
819 b3Vector3 aabbMax = b3MakeVector3(aabbMaxPtr[0], aabbMaxPtr[1], aabbMaxPtr[2]);
821 if (m_data->m_numAcceleratedRigidBodies >= (m_data->m_config.m_maxConvexBodies))
823 b3Error("registerRigidBody: exceeding the number of rigid bodies, %d > %d \n", m_data->m_numAcceleratedRigidBodies, m_data->m_config.m_maxConvexBodies);
827 m_data->m_bodyBufferCPU->resize(m_data->m_numAcceleratedRigidBodies + 1);
829 b3RigidBodyData& body = m_data->m_bodyBufferCPU->at(m_data->m_numAcceleratedRigidBodies);
831 float friction = 1.f;
832 float restitution = 0.f;
834 body.m_frictionCoeff = friction;
835 body.m_restituitionCoeff = restitution;
836 body.m_angVel = b3MakeVector3(0, 0, 0);
837 body.m_linVel = b3MakeVector3(0, 0, 0); //.setZero();
838 body.m_pos = b3MakeVector3(position[0], position[1], position[2]);
839 body.m_quat.setValue(orientation[0], orientation[1], orientation[2], orientation[3]);
840 body.m_collidableIdx = collidableIndex;
841 if (collidableIndex >= 0)
843 // body.m_shapeType = m_data->m_collidablesCPU.at(collidableIndex).m_shapeType;
847 // body.m_shapeType = CollisionShape::SHAPE_PLANE;
848 m_planeBodyIndex = m_data->m_numAcceleratedRigidBodies;
850 //body.m_shapeType = shapeType;
852 body.m_invMass = mass ? 1.f / mass : 0.f;
856 m_data->m_bodyBufferGPU->copyFromHostPointer(&body, 1, m_data->m_numAcceleratedRigidBodies);
859 b3InertiaData& shapeInfo = m_data->m_inertiaBufferCPU->at(m_data->m_numAcceleratedRigidBodies);
863 if (m_data->m_numAcceleratedRigidBodies == 0)
866 shapeInfo.m_initInvInertia.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0);
867 shapeInfo.m_invInertiaWorld.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0);
871 b3Assert(body.m_collidableIdx >= 0);
873 //approximate using the aabb of the shape
875 //Aabb aabb = (*m_data->m_shapePointers)[shapeIndex]->m_aabb;
876 b3Vector3 halfExtents = (aabbMax - aabbMin); //*0.5f;//fake larger inertia makes demos more stable ;-)
878 b3Vector3 localInertia;
880 float lx = 2.f * halfExtents[0];
881 float ly = 2.f * halfExtents[1];
882 float lz = 2.f * halfExtents[2];
884 localInertia.setValue((mass / 12.0f) * (ly * ly + lz * lz),
885 (mass / 12.0f) * (lx * lx + lz * lz),
886 (mass / 12.0f) * (lx * lx + ly * ly));
888 b3Vector3 invLocalInertia;
889 invLocalInertia[0] = 1.f / localInertia[0];
890 invLocalInertia[1] = 1.f / localInertia[1];
891 invLocalInertia[2] = 1.f / localInertia[2];
892 invLocalInertia[3] = 0.f;
894 shapeInfo.m_initInvInertia.setValue(
895 invLocalInertia[0], 0, 0,
896 0, invLocalInertia[1], 0,
897 0, 0, invLocalInertia[2]);
899 b3Matrix3x3 m(body.m_quat);
901 shapeInfo.m_invInertiaWorld = m.scaled(invLocalInertia) * m.transpose();
905 m_data->m_inertiaBufferGPU->copyFromHostPointer(&shapeInfo, 1, m_data->m_numAcceleratedRigidBodies);
907 return m_data->m_numAcceleratedRigidBodies++;
910 int b3GpuNarrowPhase::getNumRigidBodies() const
912 return m_data->m_numAcceleratedRigidBodies;
915 void b3GpuNarrowPhase::writeAllBodiesToGpu()
917 if (m_data->m_localShapeAABBCPU->size())
919 m_data->m_localShapeAABBGPU->copyFromHost(*m_data->m_localShapeAABBCPU);
922 m_data->m_gpuChildShapes->copyFromHost(m_data->m_cpuChildShapes);
923 m_data->m_convexFacesGPU->copyFromHost(m_data->m_convexFaces);
924 m_data->m_convexPolyhedraGPU->copyFromHost(m_data->m_convexPolyhedra);
925 m_data->m_uniqueEdgesGPU->copyFromHost(m_data->m_uniqueEdges);
926 m_data->m_convexVerticesGPU->copyFromHost(m_data->m_convexVertices);
927 m_data->m_convexIndicesGPU->copyFromHost(m_data->m_convexIndices);
928 m_data->m_bvhInfoGPU->copyFromHost(m_data->m_bvhInfoCPU);
929 m_data->m_treeNodesGPU->copyFromHost(m_data->m_treeNodesCPU);
930 m_data->m_subTreesGPU->copyFromHost(m_data->m_subTreesCPU);
932 m_data->m_bodyBufferGPU->resize(m_data->m_numAcceleratedRigidBodies);
933 m_data->m_inertiaBufferGPU->resize(m_data->m_numAcceleratedRigidBodies);
935 if (m_data->m_numAcceleratedRigidBodies)
937 m_data->m_bodyBufferGPU->copyFromHostPointer(&m_data->m_bodyBufferCPU->at(0), m_data->m_numAcceleratedRigidBodies);
938 m_data->m_inertiaBufferGPU->copyFromHostPointer(&m_data->m_inertiaBufferCPU->at(0), m_data->m_numAcceleratedRigidBodies);
940 if (m_data->m_collidablesCPU.size())
942 m_data->m_collidablesGPU->copyFromHost(m_data->m_collidablesCPU);
946 void b3GpuNarrowPhase::reset()
948 m_data->m_numAcceleratedShapes = 0;
949 m_data->m_numAcceleratedRigidBodies = 0;
950 this->m_static0Index = -1;
951 m_data->m_uniqueEdges.resize(0);
952 m_data->m_convexVertices.resize(0);
953 m_data->m_convexPolyhedra.resize(0);
954 m_data->m_convexIndices.resize(0);
955 m_data->m_cpuChildShapes.resize(0);
956 m_data->m_convexFaces.resize(0);
957 m_data->m_collidablesCPU.resize(0);
958 m_data->m_localShapeAABBCPU->resize(0);
959 m_data->m_bvhData.resize(0);
960 m_data->m_treeNodesCPU.resize(0);
961 m_data->m_subTreesCPU.resize(0);
962 m_data->m_bvhInfoCPU.resize(0);
965 void b3GpuNarrowPhase::readbackAllBodiesToCpu()
967 m_data->m_bodyBufferGPU->copyToHostPointer(&m_data->m_bodyBufferCPU->at(0), m_data->m_numAcceleratedRigidBodies);
970 void b3GpuNarrowPhase::setObjectTransformCpu(float* position, float* orientation, int bodyIndex)
972 if (bodyIndex >= 0 && bodyIndex < m_data->m_bodyBufferCPU->size())
974 m_data->m_bodyBufferCPU->at(bodyIndex).m_pos = b3MakeVector3(position[0], position[1], position[2]);
975 m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.setValue(orientation[0], orientation[1], orientation[2], orientation[3]);
979 b3Warning("setObjectVelocityCpu out of range.\n");
982 void b3GpuNarrowPhase::setObjectVelocityCpu(float* linVel, float* angVel, int bodyIndex)
984 if (bodyIndex >= 0 && bodyIndex < m_data->m_bodyBufferCPU->size())
986 m_data->m_bodyBufferCPU->at(bodyIndex).m_linVel = b3MakeVector3(linVel[0], linVel[1], linVel[2]);
987 m_data->m_bodyBufferCPU->at(bodyIndex).m_angVel = b3MakeVector3(angVel[0], angVel[1], angVel[2]);
991 b3Warning("setObjectVelocityCpu out of range.\n");
995 bool b3GpuNarrowPhase::getObjectTransformFromCpu(float* position, float* orientation, int bodyIndex) const
997 if (bodyIndex >= 0 && bodyIndex < m_data->m_bodyBufferCPU->size())
999 position[0] = m_data->m_bodyBufferCPU->at(bodyIndex).m_pos.x;
1000 position[1] = m_data->m_bodyBufferCPU->at(bodyIndex).m_pos.y;
1001 position[2] = m_data->m_bodyBufferCPU->at(bodyIndex).m_pos.z;
1002 position[3] = 1.f; //or 1
1004 orientation[0] = m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.x;
1005 orientation[1] = m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.y;
1006 orientation[2] = m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.z;
1007 orientation[3] = m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.w;
1011 b3Warning("getObjectTransformFromCpu out of range.\n");