1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2014 Erwin Coumans http://bulletphysics.org
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16 #include "btCollisionWorldImporter.h"
17 #include "btBulletCollisionCommon.h"
18 #include "LinearMath/btSerializer.h" //for btBulletSerializedArrays definition
19
20 #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
21 #include "BulletCollision/Gimpact/btGImpactShape.h"
22 #endif //SUPPORT_GIMPACT_SHAPE_IMPORT
23
btCollisionWorldImporter(btCollisionWorld * world)24 btCollisionWorldImporter::btCollisionWorldImporter(btCollisionWorld* world)
25 : m_collisionWorld(world),
26 m_verboseMode(0)
27 {
28 }
29
~btCollisionWorldImporter()30 btCollisionWorldImporter::~btCollisionWorldImporter()
31 {
32 }
33
convertAllObjects(btBulletSerializedArrays * arrays)34 bool btCollisionWorldImporter::convertAllObjects(btBulletSerializedArrays* arrays)
35 {
36 m_shapeMap.clear();
37 m_bodyMap.clear();
38
39 int i;
40
41 for (i = 0; i < arrays->m_bvhsDouble.size(); i++)
42 {
43 btOptimizedBvh* bvh = createOptimizedBvh();
44 btQuantizedBvhDoubleData* bvhData = arrays->m_bvhsDouble[i];
45 bvh->deSerializeDouble(*bvhData);
46 m_bvhMap.insert(arrays->m_bvhsDouble[i], bvh);
47 }
48 for (i = 0; i < arrays->m_bvhsFloat.size(); i++)
49 {
50 btOptimizedBvh* bvh = createOptimizedBvh();
51 btQuantizedBvhFloatData* bvhData = arrays->m_bvhsFloat[i];
52 bvh->deSerializeFloat(*bvhData);
53 m_bvhMap.insert(arrays->m_bvhsFloat[i], bvh);
54 }
55
56 for (i = 0; i < arrays->m_colShapeData.size(); i++)
57 {
58 btCollisionShapeData* shapeData = arrays->m_colShapeData[i];
59 btCollisionShape* shape = convertCollisionShape(shapeData);
60 if (shape)
61 {
62 // printf("shapeMap.insert(%x,%x)\n",shapeData,shape);
63 m_shapeMap.insert(shapeData, shape);
64 }
65
66 if (shape && shapeData->m_name)
67 {
68 char* newname = duplicateName(shapeData->m_name);
69 m_objectNameMap.insert(shape, newname);
70 m_nameShapeMap.insert(newname, shape);
71 }
72 }
73
74 for (i = 0; i < arrays->m_collisionObjectDataDouble.size(); i++)
75 {
76 btCollisionObjectDoubleData* colObjData = arrays->m_collisionObjectDataDouble[i];
77 btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
78 if (shapePtr && *shapePtr)
79 {
80 btTransform startTransform;
81 colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
82 startTransform.deSerializeDouble(colObjData->m_worldTransform);
83
84 btCollisionShape* shape = (btCollisionShape*)*shapePtr;
85 btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name);
86 body->setFriction(btScalar(colObjData->m_friction));
87 body->setRestitution(btScalar(colObjData->m_restitution));
88
89 #ifdef USE_INTERNAL_EDGE_UTILITY
90 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
91 {
92 btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
93 if (trimesh->getTriangleInfoMap())
94 {
95 body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
96 }
97 }
98 #endif //USE_INTERNAL_EDGE_UTILITY
99 m_bodyMap.insert(colObjData, body);
100 }
101 else
102 {
103 printf("error: no shape found\n");
104 }
105 }
106 for (i = 0; i < arrays->m_collisionObjectDataFloat.size(); i++)
107 {
108 btCollisionObjectFloatData* colObjData = arrays->m_collisionObjectDataFloat[i];
109 btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape);
110 if (shapePtr && *shapePtr)
111 {
112 btTransform startTransform;
113 colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f;
114 startTransform.deSerializeFloat(colObjData->m_worldTransform);
115
116 btCollisionShape* shape = (btCollisionShape*)*shapePtr;
117 btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name);
118
119 #ifdef USE_INTERNAL_EDGE_UTILITY
120 if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
121 {
122 btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape;
123 if (trimesh->getTriangleInfoMap())
124 {
125 body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
126 }
127 }
128 #endif //USE_INTERNAL_EDGE_UTILITY
129 m_bodyMap.insert(colObjData, body);
130 }
131 else
132 {
133 printf("error: no shape found\n");
134 }
135 }
136
137 return true;
138 }
139
deleteAllData()140 void btCollisionWorldImporter::deleteAllData()
141 {
142 int i;
143
144 for (i = 0; i < m_allocatedCollisionObjects.size(); i++)
145 {
146 if (m_collisionWorld)
147 m_collisionWorld->removeCollisionObject(m_allocatedCollisionObjects[i]);
148 delete m_allocatedCollisionObjects[i];
149 }
150
151 m_allocatedCollisionObjects.clear();
152
153 for (i = 0; i < m_allocatedCollisionShapes.size(); i++)
154 {
155 delete m_allocatedCollisionShapes[i];
156 }
157 m_allocatedCollisionShapes.clear();
158
159 for (i = 0; i < m_allocatedBvhs.size(); i++)
160 {
161 delete m_allocatedBvhs[i];
162 }
163 m_allocatedBvhs.clear();
164
165 for (i = 0; i < m_allocatedTriangleInfoMaps.size(); i++)
166 {
167 delete m_allocatedTriangleInfoMaps[i];
168 }
169 m_allocatedTriangleInfoMaps.clear();
170 for (i = 0; i < m_allocatedTriangleIndexArrays.size(); i++)
171 {
172 delete m_allocatedTriangleIndexArrays[i];
173 }
174 m_allocatedTriangleIndexArrays.clear();
175 for (i = 0; i < m_allocatedNames.size(); i++)
176 {
177 delete[] m_allocatedNames[i];
178 }
179 m_allocatedNames.clear();
180
181 for (i = 0; i < m_allocatedbtStridingMeshInterfaceDatas.size(); i++)
182 {
183 btStridingMeshInterfaceData* curData = m_allocatedbtStridingMeshInterfaceDatas[i];
184
185 for (int a = 0; a < curData->m_numMeshParts; a++)
186 {
187 btMeshPartData* curPart = &curData->m_meshPartsPtr[a];
188 if (curPart->m_vertices3f)
189 delete[] curPart->m_vertices3f;
190
191 if (curPart->m_vertices3d)
192 delete[] curPart->m_vertices3d;
193
194 if (curPart->m_indices32)
195 delete[] curPart->m_indices32;
196
197 if (curPart->m_3indices16)
198 delete[] curPart->m_3indices16;
199
200 if (curPart->m_indices16)
201 delete[] curPart->m_indices16;
202
203 if (curPart->m_3indices8)
204 delete[] curPart->m_3indices8;
205 }
206 delete[] curData->m_meshPartsPtr;
207 delete curData;
208 }
209 m_allocatedbtStridingMeshInterfaceDatas.clear();
210
211 for (i = 0; i < m_indexArrays.size(); i++)
212 {
213 btAlignedFree(m_indexArrays[i]);
214 }
215 m_indexArrays.clear();
216
217 for (i = 0; i < m_shortIndexArrays.size(); i++)
218 {
219 btAlignedFree(m_shortIndexArrays[i]);
220 }
221 m_shortIndexArrays.clear();
222
223 for (i = 0; i < m_charIndexArrays.size(); i++)
224 {
225 btAlignedFree(m_charIndexArrays[i]);
226 }
227 m_charIndexArrays.clear();
228
229 for (i = 0; i < m_floatVertexArrays.size(); i++)
230 {
231 btAlignedFree(m_floatVertexArrays[i]);
232 }
233 m_floatVertexArrays.clear();
234
235 for (i = 0; i < m_doubleVertexArrays.size(); i++)
236 {
237 btAlignedFree(m_doubleVertexArrays[i]);
238 }
239 m_doubleVertexArrays.clear();
240 }
241
convertCollisionShape(btCollisionShapeData * shapeData)242 btCollisionShape* btCollisionWorldImporter::convertCollisionShape(btCollisionShapeData* shapeData)
243 {
244 btCollisionShape* shape = 0;
245
246 switch (shapeData->m_shapeType)
247 {
248 case STATIC_PLANE_PROXYTYPE:
249 {
250 btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData;
251 btVector3 planeNormal, localScaling;
252 planeNormal.deSerializeFloat(planeData->m_planeNormal);
253 localScaling.deSerializeFloat(planeData->m_localScaling);
254 shape = createPlaneShape(planeNormal, planeData->m_planeConstant);
255 shape->setLocalScaling(localScaling);
256
257 break;
258 }
259 case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE:
260 {
261 btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*)shapeData;
262 btCollisionShapeData* colShapeData = (btCollisionShapeData*)&scaledMesh->m_trimeshShapeData;
263 colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
264 btCollisionShape* childShape = convertCollisionShape(colShapeData);
265 btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape;
266 btVector3 localScaling;
267 localScaling.deSerializeFloat(scaledMesh->m_localScaling);
268
269 shape = createScaledTrangleMeshShape(meshShape, localScaling);
270 break;
271 }
272 #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
273 case GIMPACT_SHAPE_PROXYTYPE:
274 {
275 btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*)shapeData;
276 if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE)
277 {
278 btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface);
279 btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);
280
281 btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface);
282 btVector3 localScaling;
283 localScaling.deSerializeFloat(gimpactData->m_localScaling);
284 gimpactShape->setLocalScaling(localScaling);
285 gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin));
286 gimpactShape->updateBound();
287 shape = gimpactShape;
288 }
289 else
290 {
291 printf("unsupported gimpact sub type\n");
292 }
293 break;
294 }
295 #endif //SUPPORT_GIMPACT_SHAPE_IMPORT
296 //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API
297 //so deal with this
298 case CAPSULE_SHAPE_PROXYTYPE:
299 {
300 btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData;
301
302 switch (capData->m_upAxis)
303 {
304 case 0:
305 {
306 shape = createCapsuleShapeX(1, 1);
307 break;
308 }
309 case 1:
310 {
311 shape = createCapsuleShapeY(1, 1);
312 break;
313 }
314 case 2:
315 {
316 shape = createCapsuleShapeZ(1, 1);
317 break;
318 }
319 default:
320 {
321 printf("error: wrong up axis for btCapsuleShape\n");
322 }
323 };
324 if (shape)
325 {
326 btCapsuleShape* cap = (btCapsuleShape*)shape;
327 cap->deSerializeFloat(capData);
328 }
329 break;
330 }
331 case CYLINDER_SHAPE_PROXYTYPE:
332 case CONE_SHAPE_PROXYTYPE:
333 case BOX_SHAPE_PROXYTYPE:
334 case SPHERE_SHAPE_PROXYTYPE:
335 case MULTI_SPHERE_SHAPE_PROXYTYPE:
336 case CONVEX_HULL_SHAPE_PROXYTYPE:
337 {
338 btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData;
339 btVector3 implicitShapeDimensions;
340 implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions);
341 btVector3 localScaling;
342 localScaling.deSerializeFloat(bsd->m_localScaling);
343 btVector3 margin(bsd->m_collisionMargin, bsd->m_collisionMargin, bsd->m_collisionMargin);
344 switch (shapeData->m_shapeType)
345 {
346 case BOX_SHAPE_PROXYTYPE:
347 {
348 btBoxShape* box = (btBoxShape*)createBoxShape(implicitShapeDimensions / localScaling + margin);
349 //box->initializePolyhedralFeatures();
350 shape = box;
351
352 break;
353 }
354 case SPHERE_SHAPE_PROXYTYPE:
355 {
356 shape = createSphereShape(implicitShapeDimensions.getX());
357 break;
358 }
359
360 case CYLINDER_SHAPE_PROXYTYPE:
361 {
362 btCylinderShapeData* cylData = (btCylinderShapeData*)shapeData;
363 btVector3 halfExtents = implicitShapeDimensions + margin;
364 switch (cylData->m_upAxis)
365 {
366 case 0:
367 {
368 shape = createCylinderShapeX(halfExtents.getY(), halfExtents.getX());
369 break;
370 }
371 case 1:
372 {
373 shape = createCylinderShapeY(halfExtents.getX(), halfExtents.getY());
374 break;
375 }
376 case 2:
377 {
378 shape = createCylinderShapeZ(halfExtents.getX(), halfExtents.getZ());
379 break;
380 }
381 default:
382 {
383 printf("unknown Cylinder up axis\n");
384 }
385 };
386
387 break;
388 }
389 case CONE_SHAPE_PROXYTYPE:
390 {
391 btConeShapeData* conData = (btConeShapeData*)shapeData;
392 btVector3 halfExtents = implicitShapeDimensions; //+margin;
393 switch (conData->m_upIndex)
394 {
395 case 0:
396 {
397 shape = createConeShapeX(halfExtents.getY(), halfExtents.getX());
398 break;
399 }
400 case 1:
401 {
402 shape = createConeShapeY(halfExtents.getX(), halfExtents.getY());
403 break;
404 }
405 case 2:
406 {
407 shape = createConeShapeZ(halfExtents.getX(), halfExtents.getZ());
408 break;
409 }
410 default:
411 {
412 printf("unknown Cone up axis\n");
413 }
414 };
415
416 break;
417 }
418 case MULTI_SPHERE_SHAPE_PROXYTYPE:
419 {
420 btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd;
421 int numSpheres = mss->m_localPositionArraySize;
422
423 btAlignedObjectArray<btVector3> tmpPos;
424 btAlignedObjectArray<btScalar> radii;
425 radii.resize(numSpheres);
426 tmpPos.resize(numSpheres);
427 int i;
428 for (i = 0; i < numSpheres; i++)
429 {
430 tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos);
431 radii[i] = mss->m_localPositionArrayPtr[i].m_radius;
432 }
433 shape = createMultiSphereShape(&tmpPos[0], &radii[0], numSpheres);
434 break;
435 }
436 case CONVEX_HULL_SHAPE_PROXYTYPE:
437 {
438 // int sz = sizeof(btConvexHullShapeData);
439 // int sz2 = sizeof(btConvexInternalShapeData);
440 // int sz3 = sizeof(btCollisionShapeData);
441 btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd;
442 int numPoints = convexData->m_numUnscaledPoints;
443
444 btAlignedObjectArray<btVector3> tmpPoints;
445 tmpPoints.resize(numPoints);
446 int i;
447 for (i = 0; i < numPoints; i++)
448 {
449 #ifdef BT_USE_DOUBLE_PRECISION
450 if (convexData->m_unscaledPointsDoublePtr)
451 tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]);
452 if (convexData->m_unscaledPointsFloatPtr)
453 tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]);
454 #else
455 if (convexData->m_unscaledPointsFloatPtr)
456 tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]);
457 if (convexData->m_unscaledPointsDoublePtr)
458 tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]);
459 #endif //BT_USE_DOUBLE_PRECISION
460 }
461 btConvexHullShape* hullShape = createConvexHullShape();
462 for (i = 0; i < numPoints; i++)
463 {
464 hullShape->addPoint(tmpPoints[i]);
465 }
466 hullShape->setMargin(bsd->m_collisionMargin);
467 //hullShape->initializePolyhedralFeatures();
468 shape = hullShape;
469 break;
470 }
471 default:
472 {
473 printf("error: cannot create shape type (%d)\n", shapeData->m_shapeType);
474 }
475 }
476
477 if (shape)
478 {
479 shape->setMargin(bsd->m_collisionMargin);
480
481 btVector3 localScaling;
482 localScaling.deSerializeFloat(bsd->m_localScaling);
483 shape->setLocalScaling(localScaling);
484 }
485 break;
486 }
487 case TRIANGLE_MESH_SHAPE_PROXYTYPE:
488 {
489 btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData;
490 btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&trimesh->m_meshInterface);
491 btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData);
492 if (!meshInterface->getNumSubParts())
493 {
494 return 0;
495 }
496
497 btVector3 scaling;
498 scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling);
499 meshInterface->setScaling(scaling);
500
501 btOptimizedBvh* bvh = 0;
502 #if 1
503 if (trimesh->m_quantizedFloatBvh)
504 {
505 btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedFloatBvh);
506 if (bvhPtr && *bvhPtr)
507 {
508 bvh = *bvhPtr;
509 }
510 else
511 {
512 bvh = createOptimizedBvh();
513 bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh);
514 }
515 }
516 if (trimesh->m_quantizedDoubleBvh)
517 {
518 btOptimizedBvh** bvhPtr = m_bvhMap.find(trimesh->m_quantizedDoubleBvh);
519 if (bvhPtr && *bvhPtr)
520 {
521 bvh = *bvhPtr;
522 }
523 else
524 {
525 bvh = createOptimizedBvh();
526 bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh);
527 }
528 }
529 #endif
530
531 btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface, bvh);
532 trimeshShape->setMargin(trimesh->m_collisionMargin);
533 shape = trimeshShape;
534
535 if (trimesh->m_triangleInfoMap)
536 {
537 btTriangleInfoMap* map = createTriangleInfoMap();
538 map->deSerialize(*trimesh->m_triangleInfoMap);
539 trimeshShape->setTriangleInfoMap(map);
540
541 #ifdef USE_INTERNAL_EDGE_UTILITY
542 gContactAddedCallback = btAdjustInternalEdgeContactsCallback;
543 #endif //USE_INTERNAL_EDGE_UTILITY
544 }
545
546 //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin);
547 break;
548 }
549 case COMPOUND_SHAPE_PROXYTYPE:
550 {
551 btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData;
552 btCompoundShape* compoundShape = createCompoundShape();
553
554 //btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0];
555
556 btAlignedObjectArray<btCollisionShape*> childShapes;
557 for (int i = 0; i < compoundData->m_numChildShapes; i++)
558 {
559 //btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i];
560
561 btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape;
562
563 btCollisionShape* childShape = convertCollisionShape(cd);
564 if (childShape)
565 {
566 btTransform localTransform;
567 localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform);
568 compoundShape->addChildShape(localTransform, childShape);
569 }
570 else
571 {
572 #ifdef _DEBUG
573 printf("error: couldn't create childShape for compoundShape\n");
574 #endif
575 }
576 }
577 shape = compoundShape;
578
579 break;
580 }
581 case SOFTBODY_SHAPE_PROXYTYPE:
582 {
583 return 0;
584 }
585 default:
586 {
587 #ifdef _DEBUG
588 printf("unsupported shape type (%d)\n", shapeData->m_shapeType);
589 #endif
590 }
591 }
592
593 return shape;
594 }
595
duplicateName(const char * name)596 char* btCollisionWorldImporter::duplicateName(const char* name)
597 {
598 if (name)
599 {
600 int l = (int)strlen(name);
601 char* newName = new char[l + 1];
602 memcpy(newName, name, l);
603 newName[l] = 0;
604 m_allocatedNames.push_back(newName);
605 return newName;
606 }
607 return 0;
608 }
609
createMeshInterface(btStridingMeshInterfaceData & meshData)610 btTriangleIndexVertexArray* btCollisionWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData)
611 {
612 btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer();
613
614 for (int i = 0; i < meshData.m_numMeshParts; i++)
615 {
616 btIndexedMesh meshPart;
617 meshPart.m_numTriangles = meshData.m_meshPartsPtr[i].m_numTriangles;
618 meshPart.m_numVertices = meshData.m_meshPartsPtr[i].m_numVertices;
619
620 if (meshData.m_meshPartsPtr[i].m_indices32)
621 {
622 meshPart.m_indexType = PHY_INTEGER;
623 meshPart.m_triangleIndexStride = 3 * sizeof(int);
624 int* indexArray = (int*)btAlignedAlloc(sizeof(int) * 3 * meshPart.m_numTriangles, 16);
625 m_indexArrays.push_back(indexArray);
626 for (int j = 0; j < 3 * meshPart.m_numTriangles; j++)
627 {
628 indexArray[j] = meshData.m_meshPartsPtr[i].m_indices32[j].m_value;
629 }
630 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
631 }
632 else
633 {
634 if (meshData.m_meshPartsPtr[i].m_3indices16)
635 {
636 meshPart.m_indexType = PHY_SHORT;
637 meshPart.m_triangleIndexStride = sizeof(short int) * 3; //sizeof(btShortIntIndexTripletData);
638
639 short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int) * 3 * meshPart.m_numTriangles, 16);
640 m_shortIndexArrays.push_back(indexArray);
641
642 for (int j = 0; j < meshPart.m_numTriangles; j++)
643 {
644 indexArray[3 * j] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[0];
645 indexArray[3 * j + 1] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[1];
646 indexArray[3 * j + 2] = meshData.m_meshPartsPtr[i].m_3indices16[j].m_values[2];
647 }
648
649 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
650 }
651 if (meshData.m_meshPartsPtr[i].m_indices16)
652 {
653 meshPart.m_indexType = PHY_SHORT;
654 meshPart.m_triangleIndexStride = 3 * sizeof(short int);
655 short int* indexArray = (short int*)btAlignedAlloc(sizeof(short int) * 3 * meshPart.m_numTriangles, 16);
656 m_shortIndexArrays.push_back(indexArray);
657 for (int j = 0; j < 3 * meshPart.m_numTriangles; j++)
658 {
659 indexArray[j] = meshData.m_meshPartsPtr[i].m_indices16[j].m_value;
660 }
661
662 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
663 }
664
665 if (meshData.m_meshPartsPtr[i].m_3indices8)
666 {
667 meshPart.m_indexType = PHY_UCHAR;
668 meshPart.m_triangleIndexStride = sizeof(unsigned char) * 3;
669
670 unsigned char* indexArray = (unsigned char*)btAlignedAlloc(sizeof(unsigned char) * 3 * meshPart.m_numTriangles, 16);
671 m_charIndexArrays.push_back(indexArray);
672
673 for (int j = 0; j < meshPart.m_numTriangles; j++)
674 {
675 indexArray[3 * j] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[0];
676 indexArray[3 * j + 1] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[1];
677 indexArray[3 * j + 2] = meshData.m_meshPartsPtr[i].m_3indices8[j].m_values[2];
678 }
679
680 meshPart.m_triangleIndexBase = (const unsigned char*)indexArray;
681 }
682 }
683
684 if (meshData.m_meshPartsPtr[i].m_vertices3f)
685 {
686 meshPart.m_vertexType = PHY_FLOAT;
687 meshPart.m_vertexStride = sizeof(btVector3FloatData);
688 btVector3FloatData* vertices = (btVector3FloatData*)btAlignedAlloc(sizeof(btVector3FloatData) * meshPart.m_numVertices, 16);
689 m_floatVertexArrays.push_back(vertices);
690
691 for (int j = 0; j < meshPart.m_numVertices; j++)
692 {
693 vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[0];
694 vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[1];
695 vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[2];
696 vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3f[j].m_floats[3];
697 }
698 meshPart.m_vertexBase = (const unsigned char*)vertices;
699 }
700 else
701 {
702 meshPart.m_vertexType = PHY_DOUBLE;
703 meshPart.m_vertexStride = sizeof(btVector3DoubleData);
704
705 btVector3DoubleData* vertices = (btVector3DoubleData*)btAlignedAlloc(sizeof(btVector3DoubleData) * meshPart.m_numVertices, 16);
706 m_doubleVertexArrays.push_back(vertices);
707
708 for (int j = 0; j < meshPart.m_numVertices; j++)
709 {
710 vertices[j].m_floats[0] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[0];
711 vertices[j].m_floats[1] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[1];
712 vertices[j].m_floats[2] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[2];
713 vertices[j].m_floats[3] = meshData.m_meshPartsPtr[i].m_vertices3d[j].m_floats[3];
714 }
715 meshPart.m_vertexBase = (const unsigned char*)vertices;
716 }
717
718 if (meshPart.m_triangleIndexBase && meshPart.m_vertexBase)
719 {
720 meshInterface->addIndexedMesh(meshPart, meshPart.m_indexType);
721 }
722 }
723
724 return meshInterface;
725 }
726
createStridingMeshInterfaceData(btStridingMeshInterfaceData * interfaceData)727 btStridingMeshInterfaceData* btCollisionWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData)
728 {
729 //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter
730 btStridingMeshInterfaceData* newData = new btStridingMeshInterfaceData;
731
732 newData->m_scaling = interfaceData->m_scaling;
733 newData->m_numMeshParts = interfaceData->m_numMeshParts;
734 newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts];
735
736 for (int i = 0; i < newData->m_numMeshParts; i++)
737 {
738 btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i];
739 btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i];
740
741 curNewPart->m_numTriangles = curPart->m_numTriangles;
742 curNewPart->m_numVertices = curPart->m_numVertices;
743
744 if (curPart->m_vertices3f)
745 {
746 curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices];
747 memcpy(curNewPart->m_vertices3f, curPart->m_vertices3f, sizeof(btVector3FloatData) * curNewPart->m_numVertices);
748 }
749 else
750 curNewPart->m_vertices3f = NULL;
751
752 if (curPart->m_vertices3d)
753 {
754 curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices];
755 memcpy(curNewPart->m_vertices3d, curPart->m_vertices3d, sizeof(btVector3DoubleData) * curNewPart->m_numVertices);
756 }
757 else
758 curNewPart->m_vertices3d = NULL;
759
760 int numIndices = curNewPart->m_numTriangles * 3;
761 ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time
762 ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized
763 bool uninitialized3indices8Workaround = false;
764
765 if (curPart->m_indices32)
766 {
767 uninitialized3indices8Workaround = true;
768 curNewPart->m_indices32 = new btIntIndexData[numIndices];
769 memcpy(curNewPart->m_indices32, curPart->m_indices32, sizeof(btIntIndexData) * numIndices);
770 }
771 else
772 curNewPart->m_indices32 = NULL;
773
774 if (curPart->m_3indices16)
775 {
776 uninitialized3indices8Workaround = true;
777 curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles];
778 memcpy(curNewPart->m_3indices16, curPart->m_3indices16, sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles);
779 }
780 else
781 curNewPart->m_3indices16 = NULL;
782
783 if (curPart->m_indices16)
784 {
785 uninitialized3indices8Workaround = true;
786 curNewPart->m_indices16 = new btShortIntIndexData[numIndices];
787 memcpy(curNewPart->m_indices16, curPart->m_indices16, sizeof(btShortIntIndexData) * numIndices);
788 }
789 else
790 curNewPart->m_indices16 = NULL;
791
792 if (!uninitialized3indices8Workaround && curPart->m_3indices8)
793 {
794 curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles];
795 memcpy(curNewPart->m_3indices8, curPart->m_3indices8, sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles);
796 }
797 else
798 curNewPart->m_3indices8 = NULL;
799 }
800
801 m_allocatedbtStridingMeshInterfaceDatas.push_back(newData);
802
803 return (newData);
804 }
805
806 #ifdef USE_INTERNAL_EDGE_UTILITY
807 extern ContactAddedCallback gContactAddedCallback;
808
btAdjustInternalEdgeContactsCallback(btManifoldPoint & cp,const btCollisionObject * colObj0,int partId0,int index0,const btCollisionObject * colObj1,int partId1,int index1)809 static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1, int index1)
810 {
811 btAdjustInternalEdgeContacts(cp, colObj1, colObj0, partId1, index1);
812 //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE);
813 //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED);
814 return true;
815 }
816 #endif //USE_INTERNAL_EDGE_UTILITY
817
818 /*
819 btRigidBody* btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName)
820 {
821 btVector3 localInertia;
822 localInertia.setZero();
823
824 if (mass)
825 shape->calculateLocalInertia(mass,localInertia);
826
827 btRigidBody* body = new btRigidBody(mass,0,shape,localInertia);
828 body->setWorldTransform(startTransform);
829
830 if (m_dynamicsWorld)
831 m_dynamicsWorld->addRigidBody(body);
832
833 if (bodyName)
834 {
835 char* newname = duplicateName(bodyName);
836 m_objectNameMap.insert(body,newname);
837 m_nameBodyMap.insert(newname,body);
838 }
839 m_allocatedRigidBodies.push_back(body);
840 return body;
841
842 }
843 */
844
getCollisionObjectByName(const char * name)845 btCollisionObject* btCollisionWorldImporter::getCollisionObjectByName(const char* name)
846 {
847 btCollisionObject** bodyPtr = m_nameColObjMap.find(name);
848 if (bodyPtr && *bodyPtr)
849 {
850 return *bodyPtr;
851 }
852 return 0;
853 }
854
createCollisionObject(const btTransform & startTransform,btCollisionShape * shape,const char * bodyName)855 btCollisionObject* btCollisionWorldImporter::createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName)
856 {
857 btCollisionObject* colObj = new btCollisionObject();
858 colObj->setWorldTransform(startTransform);
859 colObj->setCollisionShape(shape);
860 m_collisionWorld->addCollisionObject(colObj); //todo: flags etc
861
862 if (bodyName)
863 {
864 char* newname = duplicateName(bodyName);
865 m_objectNameMap.insert(colObj, newname);
866 m_nameColObjMap.insert(newname, colObj);
867 }
868 m_allocatedCollisionObjects.push_back(colObj);
869
870 return colObj;
871 }
872
createPlaneShape(const btVector3 & planeNormal,btScalar planeConstant)873 btCollisionShape* btCollisionWorldImporter::createPlaneShape(const btVector3& planeNormal, btScalar planeConstant)
874 {
875 btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal, planeConstant);
876 m_allocatedCollisionShapes.push_back(shape);
877 return shape;
878 }
createBoxShape(const btVector3 & halfExtents)879 btCollisionShape* btCollisionWorldImporter::createBoxShape(const btVector3& halfExtents)
880 {
881 btBoxShape* shape = new btBoxShape(halfExtents);
882 m_allocatedCollisionShapes.push_back(shape);
883 return shape;
884 }
createSphereShape(btScalar radius)885 btCollisionShape* btCollisionWorldImporter::createSphereShape(btScalar radius)
886 {
887 btSphereShape* shape = new btSphereShape(radius);
888 m_allocatedCollisionShapes.push_back(shape);
889 return shape;
890 }
891
createCapsuleShapeX(btScalar radius,btScalar height)892 btCollisionShape* btCollisionWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height)
893 {
894 btCapsuleShapeX* shape = new btCapsuleShapeX(radius, height);
895 m_allocatedCollisionShapes.push_back(shape);
896 return shape;
897 }
898
createCapsuleShapeY(btScalar radius,btScalar height)899 btCollisionShape* btCollisionWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height)
900 {
901 btCapsuleShape* shape = new btCapsuleShape(radius, height);
902 m_allocatedCollisionShapes.push_back(shape);
903 return shape;
904 }
905
createCapsuleShapeZ(btScalar radius,btScalar height)906 btCollisionShape* btCollisionWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height)
907 {
908 btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius, height);
909 m_allocatedCollisionShapes.push_back(shape);
910 return shape;
911 }
912
createCylinderShapeX(btScalar radius,btScalar height)913 btCollisionShape* btCollisionWorldImporter::createCylinderShapeX(btScalar radius, btScalar height)
914 {
915 btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height, radius, radius));
916 m_allocatedCollisionShapes.push_back(shape);
917 return shape;
918 }
919
createCylinderShapeY(btScalar radius,btScalar height)920 btCollisionShape* btCollisionWorldImporter::createCylinderShapeY(btScalar radius, btScalar height)
921 {
922 btCylinderShape* shape = new btCylinderShape(btVector3(radius, height, radius));
923 m_allocatedCollisionShapes.push_back(shape);
924 return shape;
925 }
926
createCylinderShapeZ(btScalar radius,btScalar height)927 btCollisionShape* btCollisionWorldImporter::createCylinderShapeZ(btScalar radius, btScalar height)
928 {
929 btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius, radius, height));
930 m_allocatedCollisionShapes.push_back(shape);
931 return shape;
932 }
933
createConeShapeX(btScalar radius,btScalar height)934 btCollisionShape* btCollisionWorldImporter::createConeShapeX(btScalar radius, btScalar height)
935 {
936 btConeShapeX* shape = new btConeShapeX(radius, height);
937 m_allocatedCollisionShapes.push_back(shape);
938 return shape;
939 }
940
createConeShapeY(btScalar radius,btScalar height)941 btCollisionShape* btCollisionWorldImporter::createConeShapeY(btScalar radius, btScalar height)
942 {
943 btConeShape* shape = new btConeShape(radius, height);
944 m_allocatedCollisionShapes.push_back(shape);
945 return shape;
946 }
947
createConeShapeZ(btScalar radius,btScalar height)948 btCollisionShape* btCollisionWorldImporter::createConeShapeZ(btScalar radius, btScalar height)
949 {
950 btConeShapeZ* shape = new btConeShapeZ(radius, height);
951 m_allocatedCollisionShapes.push_back(shape);
952 return shape;
953 }
954
createTriangleMeshContainer()955 btTriangleIndexVertexArray* btCollisionWorldImporter::createTriangleMeshContainer()
956 {
957 btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray();
958 m_allocatedTriangleIndexArrays.push_back(in);
959 return in;
960 }
961
createOptimizedBvh()962 btOptimizedBvh* btCollisionWorldImporter::createOptimizedBvh()
963 {
964 btOptimizedBvh* bvh = new btOptimizedBvh();
965 m_allocatedBvhs.push_back(bvh);
966 return bvh;
967 }
968
createTriangleInfoMap()969 btTriangleInfoMap* btCollisionWorldImporter::createTriangleInfoMap()
970 {
971 btTriangleInfoMap* tim = new btTriangleInfoMap();
972 m_allocatedTriangleInfoMaps.push_back(tim);
973 return tim;
974 }
975
createBvhTriangleMeshShape(btStridingMeshInterface * trimesh,btOptimizedBvh * bvh)976 btBvhTriangleMeshShape* btCollisionWorldImporter::createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh)
977 {
978 if (bvh)
979 {
980 btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh, bvh->isQuantized(), false);
981 bvhTriMesh->setOptimizedBvh(bvh);
982 m_allocatedCollisionShapes.push_back(bvhTriMesh);
983 return bvhTriMesh;
984 }
985
986 btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh, true);
987 m_allocatedCollisionShapes.push_back(ts);
988 return ts;
989 }
createConvexTriangleMeshShape(btStridingMeshInterface * trimesh)990 btCollisionShape* btCollisionWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh)
991 {
992 return 0;
993 }
994 #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT
createGimpactShape(btStridingMeshInterface * trimesh)995 btGImpactMeshShape* btCollisionWorldImporter::createGimpactShape(btStridingMeshInterface* trimesh)
996 {
997 btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh);
998 m_allocatedCollisionShapes.push_back(shape);
999 return shape;
1000 }
1001 #endif //SUPPORT_GIMPACT_SHAPE_IMPORT
1002
createConvexHullShape()1003 btConvexHullShape* btCollisionWorldImporter::createConvexHullShape()
1004 {
1005 btConvexHullShape* shape = new btConvexHullShape();
1006 m_allocatedCollisionShapes.push_back(shape);
1007 return shape;
1008 }
1009
createCompoundShape()1010 btCompoundShape* btCollisionWorldImporter::createCompoundShape()
1011 {
1012 btCompoundShape* shape = new btCompoundShape();
1013 m_allocatedCollisionShapes.push_back(shape);
1014 return shape;
1015 }
1016
createScaledTrangleMeshShape(btBvhTriangleMeshShape * meshShape,const btVector3 & localScaling)1017 btScaledBvhTriangleMeshShape* btCollisionWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScaling)
1018 {
1019 btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape, localScaling);
1020 m_allocatedCollisionShapes.push_back(shape);
1021 return shape;
1022 }
1023
createMultiSphereShape(const btVector3 * positions,const btScalar * radi,int numSpheres)1024 btMultiSphereShape* btCollisionWorldImporter::createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres)
1025 {
1026 btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres);
1027 m_allocatedCollisionShapes.push_back(shape);
1028 return shape;
1029 }
1030
1031 // query for data
getNumCollisionShapes() const1032 int btCollisionWorldImporter::getNumCollisionShapes() const
1033 {
1034 return m_allocatedCollisionShapes.size();
1035 }
1036
getCollisionShapeByIndex(int index)1037 btCollisionShape* btCollisionWorldImporter::getCollisionShapeByIndex(int index)
1038 {
1039 return m_allocatedCollisionShapes[index];
1040 }
1041
getCollisionShapeByName(const char * name)1042 btCollisionShape* btCollisionWorldImporter::getCollisionShapeByName(const char* name)
1043 {
1044 btCollisionShape** shapePtr = m_nameShapeMap.find(name);
1045 if (shapePtr && *shapePtr)
1046 {
1047 return *shapePtr;
1048 }
1049 return 0;
1050 }
1051
getNameForPointer(const void * ptr) const1052 const char* btCollisionWorldImporter::getNameForPointer(const void* ptr) const
1053 {
1054 const char* const* namePtr = m_objectNameMap.find(ptr);
1055 if (namePtr && *namePtr)
1056 return *namePtr;
1057 return 0;
1058 }
1059
getNumRigidBodies() const1060 int btCollisionWorldImporter::getNumRigidBodies() const
1061 {
1062 return m_allocatedRigidBodies.size();
1063 }
1064
getRigidBodyByIndex(int index) const1065 btCollisionObject* btCollisionWorldImporter::getRigidBodyByIndex(int index) const
1066 {
1067 return m_allocatedRigidBodies[index];
1068 }
1069
getNumBvhs() const1070 int btCollisionWorldImporter::getNumBvhs() const
1071 {
1072 return m_allocatedBvhs.size();
1073 }
getBvhByIndex(int index) const1074 btOptimizedBvh* btCollisionWorldImporter::getBvhByIndex(int index) const
1075 {
1076 return m_allocatedBvhs[index];
1077 }
1078
getNumTriangleInfoMaps() const1079 int btCollisionWorldImporter::getNumTriangleInfoMaps() const
1080 {
1081 return m_allocatedTriangleInfoMaps.size();
1082 }
1083
getTriangleInfoMapByIndex(int index) const1084 btTriangleInfoMap* btCollisionWorldImporter::getTriangleInfoMapByIndex(int index) const
1085 {
1086 return m_allocatedTriangleInfoMaps[index];
1087 }
1088