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