Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / Serialize / BulletXmlWorldImporter / btBulletXmlWorldImporter.cpp
1 /*\r
2 Bullet Continuous Collision Detection and Physics Library\r
3 Copyright (c) 2003-2012 Erwin Coumans  http://bulletphysics.org\r
4 \r
5 This software is provided 'as-is', without any express or implied warranty.\r
6 In no event will the authors be held liable for any damages arising from the use of this software.\r
7 Permission is granted to anyone to use this software for any purpose, \r
8 including commercial applications, and to alter it and redistribute it freely, \r
9 subject to the following restrictions:\r
10 \r
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.\r
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\r
13 3. This notice may not be removed or altered from any source distribution.\r
14 */\r
15 \r
16 #include "btBulletXmlWorldImporter.h"\r
17 #include "tinyxml.h"\r
18 #include "btBulletDynamicsCommon.h"\r
19 #include "string_split.h"\r
20 \r
21 \r
22 btBulletXmlWorldImporter::btBulletXmlWorldImporter(btDynamicsWorld* world)\r
23         :btWorldImporter(world),\r
24         m_fileVersion(-1),\r
25         m_fileOk(false)\r
26 {\r
27 \r
28 }\r
29 \r
30 btBulletXmlWorldImporter::~btBulletXmlWorldImporter()\r
31 {\r
32 \r
33 }\r
34 \r
35 \r
36 static int get_double_attribute_by_name(const TiXmlElement* pElement, const char* attribName,double* value)\r
37 {\r
38         if ( !pElement ) \r
39                 return 0;\r
40 \r
41         const TiXmlAttribute* pAttrib=pElement->FirstAttribute();\r
42         while (pAttrib)\r
43         {\r
44                 if (pAttrib->Name()==attribName)\r
45                         if (pAttrib->QueryDoubleValue(value)==TIXML_SUCCESS)\r
46                                 return 1;\r
47                 pAttrib=pAttrib->Next();\r
48         }\r
49         return 0;\r
50 }\r
51 \r
52 \r
53 static int get_int_attribute_by_name(const TiXmlElement* pElement, const char* attribName,int* value)\r
54 {\r
55         if ( !pElement ) \r
56                 return 0;\r
57 \r
58         const TiXmlAttribute* pAttrib=pElement->FirstAttribute();\r
59         while (pAttrib)\r
60         {\r
61                 if (!strcmp(pAttrib->Name(),attribName))\r
62                         if (pAttrib->QueryIntValue(value)==TIXML_SUCCESS)\r
63                                 return 1;\r
64 //              if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval);\r
65                 pAttrib=pAttrib->Next();\r
66         }\r
67         return 0;\r
68 }\r
69 \r
70 void stringToFloatArray(const std::string& string, btAlignedObjectArray<float>& floats)\r
71 {\r
72         btAlignedObjectArray<std::string> pieces;\r
73 \r
74     bullet_utils::split( pieces, string, " ");\r
75     for (unsigned int i = 0; i < pieces.size(); ++i)\r
76         {\r
77                 assert(pieces[i]!="");\r
78         floats.push_back((float)atof(pieces[i].c_str()));\r
79     }\r
80           \r
81 }\r
82 \r
83 static btVector3FloatData TextToVector3Data(const char* txt)\r
84 {\r
85         btAssert(txt);\r
86         btAlignedObjectArray<float> floats;\r
87         stringToFloatArray(txt, floats);\r
88         assert(floats.size()==4);\r
89 \r
90         btVector3FloatData vec4;\r
91         vec4.m_floats[0] = floats[0];\r
92         vec4.m_floats[1] = floats[1];\r
93         vec4.m_floats[2] = floats[2];\r
94         vec4.m_floats[3] = floats[3];\r
95         return vec4;\r
96 }\r
97 \r
98 void btBulletXmlWorldImporter::deSerializeVector3FloatData(TiXmlNode* pParent,btAlignedObjectArray<btVector3FloatData>& vectors)\r
99 {\r
100         TiXmlNode* flNode = pParent->FirstChild("m_floats");\r
101         btAssert(flNode);\r
102         while (flNode && flNode->FirstChild())\r
103         {\r
104                 TiXmlText* pText = flNode->FirstChild()->ToText();\r
105 //              printf("value = %s\n",pText->Value());\r
106                 btVector3FloatData vec4 = TextToVector3Data(pText->Value());\r
107                 vectors.push_back(vec4);\r
108                 flNode = flNode->NextSibling();\r
109         }\r
110         \r
111 }\r
112 \r
113 \r
114 #define SET_INT_VALUE(xmlnode, targetdata, argname) \\r
115         btAssert((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement());\\r
116         if ((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement())\\r
117                 (targetdata)->argname= (int)atof(xmlnode->FirstChild(#argname)->ToElement()->GetText());\r
118 \r
119 \r
120 #define SET_FLOAT_VALUE(xmlnode, targetdata, argname) \\r
121         btAssert((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement());\\r
122         if ((xmlnode)->FirstChild(#argname) && (xmlnode)->FirstChild(#argname)->ToElement())\\r
123                 (targetdata)->argname= (float)atof(xmlnode->FirstChild(#argname)->ToElement()->GetText());\r
124 \r
125 \r
126 #define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype) \\r
127         {\\r
128                 TiXmlNode* node = xmlnode->FirstChild(#argname);\\r
129                 btAssert(node);\\r
130                 if (node)\\r
131                 {\\r
132                         const char* txt = (node)->ToElement()->GetText();\\r
133                         (targetdata).argname= (pointertype) (int) atof(txt);\\r
134                 }\\r
135         }\r
136 \r
137 #define SET_VECTOR4_VALUE(xmlnode, targetdata, argname) \\r
138         {\\r
139                 TiXmlNode* flNode = xmlnode->FirstChild(#argname);\\r
140                 btAssert(flNode);\\r
141                 if (flNode && flNode->FirstChild())\\r
142                 {\\r
143                         const char* txt= flNode->FirstChild()->ToElement()->GetText();\\r
144                         btVector3FloatData vec4 = TextToVector3Data(txt);\\r
145                         (targetdata)->argname.m_floats[0] = vec4.m_floats[0];\\r
146                         (targetdata)->argname.m_floats[1] = vec4.m_floats[1];\\r
147                         (targetdata)->argname.m_floats[2] = vec4.m_floats[2];\\r
148                         (targetdata)->argname.m_floats[3] = vec4.m_floats[3];\\r
149                 }\\r
150         }\r
151 \r
152 \r
153 #define SET_MATRIX33_VALUE(n, targetdata, argname) \\r
154 {\\r
155         TiXmlNode* xmlnode = n->FirstChild(#argname);\\r
156         btAssert(xmlnode);\\r
157         if (xmlnode)\\r
158         {\\r
159                 TiXmlNode* eleNode = xmlnode->FirstChild("m_el");\\r
160                 btAssert(eleNode);\\r
161                 if (eleNode&& eleNode->FirstChild())\\r
162                 {\\r
163                         const char* txt= eleNode->FirstChild()->ToElement()->GetText();\\r
164                         btVector3FloatData vec4 = TextToVector3Data(txt);\\r
165                         (targetdata)->argname.m_el[0].m_floats[0] = vec4.m_floats[0];\\r
166                         (targetdata)->argname.m_el[0].m_floats[1] = vec4.m_floats[1];\\r
167                         (targetdata)->argname.m_el[0].m_floats[2] = vec4.m_floats[2];\\r
168                         (targetdata)->argname.m_el[0].m_floats[3] = vec4.m_floats[3];\\r
169                         \\r
170                         TiXmlNode* n1 = eleNode->FirstChild()->NextSibling();\\r
171                         btAssert(n1);\\r
172                         if (n1)\\r
173                         {\\r
174                                 const char* txt= n1->ToElement()->GetText();\\r
175                                 btVector3FloatData vec4 = TextToVector3Data(txt);\\r
176                                 (targetdata)->argname.m_el[1].m_floats[0] = vec4.m_floats[0];\\r
177                                 (targetdata)->argname.m_el[1].m_floats[1] = vec4.m_floats[1];\\r
178                                 (targetdata)->argname.m_el[1].m_floats[2] = vec4.m_floats[2];\\r
179                                 (targetdata)->argname.m_el[1].m_floats[3] = vec4.m_floats[3];\\r
180                         \\r
181                                 TiXmlNode* n2 = n1->NextSibling();\\r
182                                 btAssert(n2);\\r
183                                 if (n2)\\r
184                                 {\\r
185                                         const char* txt= n2->ToElement()->GetText();\\r
186                                         btVector3FloatData vec4 = TextToVector3Data(txt);\\r
187                                         (targetdata)->argname.m_el[2].m_floats[0] = vec4.m_floats[0];\\r
188                                         (targetdata)->argname.m_el[2].m_floats[1] = vec4.m_floats[1];\\r
189                                         (targetdata)->argname.m_el[2].m_floats[2] = vec4.m_floats[2];\\r
190                                         (targetdata)->argname.m_el[2].m_floats[3] = vec4.m_floats[3];\\r
191                                 }\\r
192                         }\\r
193                 }\\r
194         }\\r
195 }\\r
196 \r
197 #define SET_TRANSFORM_VALUE(n, targetdata, argname) \\r
198 {\\r
199         TiXmlNode* trNode = n->FirstChild(#argname);\\r
200         btAssert(trNode);\\r
201         if (trNode)\\r
202         {\\r
203                 SET_VECTOR4_VALUE(trNode,&(targetdata)->argname,m_origin)\\r
204                 SET_MATRIX33_VALUE(trNode, &(targetdata)->argname,m_basis)\\r
205         }\\r
206 }\\r
207 \r
208 \r
209 void btBulletXmlWorldImporter::deSerializeCollisionShapeData(TiXmlNode* pParent, btCollisionShapeData* colShapeData)\r
210 {\r
211                 SET_INT_VALUE(pParent,colShapeData,m_shapeType)\r
212                 colShapeData->m_name = 0;\r
213 }\r
214 \r
215 \r
216 \r
217 void btBulletXmlWorldImporter::deSerializeConvexHullShapeData(TiXmlNode* pParent)\r
218 {\r
219         int ptr;\r
220         get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr);\r
221         \r
222         btConvexHullShapeData* convexHullData = (btConvexHullShapeData*)btAlignedAlloc(sizeof(btConvexHullShapeData), 16);\r
223 \r
224         TiXmlNode* xmlConvexInt = pParent->FirstChild("m_convexInternalShapeData");\r
225         btAssert(xmlConvexInt);\r
226 \r
227         TiXmlNode* xmlColShape = xmlConvexInt ->FirstChild("m_collisionShapeData");\r
228         btAssert(xmlColShape);\r
229 \r
230         deSerializeCollisionShapeData(xmlColShape,&convexHullData->m_convexInternalShapeData.m_collisionShapeData);\r
231         \r
232         SET_FLOAT_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_collisionMargin)\r
233         SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_localScaling)\r
234         SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_implicitShapeDimensions)\r
235 \r
236         SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsFloatPtr,btVector3FloatData*);\r
237         SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsDoublePtr,btVector3DoubleData*);\r
238         SET_INT_VALUE(pParent,convexHullData,m_numUnscaledPoints);\r
239 \r
240         m_collisionShapeData.push_back((btCollisionShapeData*)convexHullData);\r
241         m_pointerLookup.insert((void*)ptr,convexHullData);\r
242 }\r
243 \r
244 void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(TiXmlNode* pParent)\r
245 {\r
246         int ptr;\r
247         get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr);\r
248 \r
249         int numChildren = 0;\r
250         btAlignedObjectArray<btCompoundShapeChildData>* compoundChildArrayPtr = new btAlignedObjectArray<btCompoundShapeChildData>;\r
251         {\r
252                 TiXmlNode* transNode = pParent->FirstChild("m_transform");\r
253                 TiXmlNode* colShapeNode = pParent->FirstChild("m_childShape");\r
254                 TiXmlNode* marginNode = pParent->FirstChild("m_childMargin");\r
255                 TiXmlNode* childTypeNode = pParent->FirstChild("m_childShapeType");\r
256 \r
257                 int i=0;\r
258                 while (transNode && colShapeNode && marginNode && childTypeNode)\r
259                 {\r
260                         compoundChildArrayPtr->expandNonInitializing();\r
261                         SET_VECTOR4_VALUE (transNode,&compoundChildArrayPtr->at(i).m_transform,m_origin)\r
262                         SET_MATRIX33_VALUE(transNode,&compoundChildArrayPtr->at(i).m_transform,m_basis)\r
263 \r
264                         const char* txt = (colShapeNode)->ToElement()->GetText();\r
265                         compoundChildArrayPtr->at(i).m_childShape = (btCollisionShapeData*) (int) atof(txt);\r
266                         \r
267                         btAssert(childTypeNode->ToElement());\r
268                         if (childTypeNode->ToElement())\r
269                         {\r
270                                 compoundChildArrayPtr->at(i).m_childShapeType =  (int)atof(childTypeNode->ToElement()->GetText());\r
271                         }\r
272 \r
273                         btAssert(marginNode->ToElement());\r
274                         if (marginNode->ToElement())\r
275                         {\r
276                                 compoundChildArrayPtr->at(i).m_childMargin = (float)atof(marginNode->ToElement()->GetText());\r
277                         }\r
278 \r
279                         transNode = transNode->NextSibling("m_transform");\r
280                         colShapeNode = colShapeNode->NextSibling("m_childShape");\r
281                         marginNode = marginNode->NextSibling("m_childMargin");\r
282                         childTypeNode = childTypeNode->NextSibling("m_childShapeType");\r
283                         i++;\r
284                 }\r
285                 \r
286                 numChildren = i;\r
287                 \r
288         }\r
289 \r
290         btAssert(numChildren);\r
291         if (numChildren)\r
292         {\r
293                 m_compoundShapeChildDataArrays.push_back(compoundChildArrayPtr);\r
294                 btCompoundShapeChildData* cd = &compoundChildArrayPtr->at(0);\r
295                 m_pointerLookup.insert((void*)ptr,cd);\r
296         }\r
297         \r
298 }\r
299 \r
300 void btBulletXmlWorldImporter::deSerializeCompoundShapeData(TiXmlNode* pParent)\r
301 {\r
302         int ptr;\r
303         get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr);\r
304 \r
305         btCompoundShapeData* compoundData = (btCompoundShapeData*) btAlignedAlloc(sizeof(btCompoundShapeData),16); \r
306 \r
307         TiXmlNode* xmlColShape = pParent ->FirstChild("m_collisionShapeData");\r
308         btAssert(xmlColShape);\r
309         deSerializeCollisionShapeData(xmlColShape,&compoundData->m_collisionShapeData);\r
310         \r
311         SET_INT_VALUE(pParent, compoundData,m_numChildShapes);\r
312 \r
313         TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData");\r
314         btAssert(xmlShapeData );\r
315 \r
316         {\r
317                 TiXmlNode* node = pParent->FirstChild("m_childShapePtr");\\r
318                 btAssert(node);\r
319                 while (node)\r
320                 {\r
321                         const char* txt = (node)->ToElement()->GetText();\r
322                         compoundData->m_childShapePtr = (btCompoundShapeChildData*) (int) atof(txt);\r
323                         node = node->NextSibling("m_childShapePtr");\r
324                 }\r
325                 //SET_POINTER_VALUE(xmlColShape, *compoundData,m_childShapePtr,btCompoundShapeChildData*);\r
326                 \r
327         }\r
328         SET_FLOAT_VALUE(pParent, compoundData,m_collisionMargin);\r
329 \r
330         m_collisionShapeData.push_back((btCollisionShapeData*)compoundData);\r
331         m_pointerLookup.insert((void*)ptr,compoundData);\r
332 \r
333 }\r
334 \r
335 void btBulletXmlWorldImporter::deSerializeStaticPlaneShapeData(TiXmlNode* pParent)\r
336 {\r
337         int ptr;\r
338         get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr);\r
339 \r
340         btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) btAlignedAlloc(sizeof(btStaticPlaneShapeData),16);\r
341 \r
342         TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData");\r
343         btAssert(xmlShapeData );\r
344         deSerializeCollisionShapeData(xmlShapeData,&planeData->m_collisionShapeData);\r
345 \r
346         SET_VECTOR4_VALUE(pParent, planeData,m_localScaling);\r
347         SET_VECTOR4_VALUE(pParent, planeData,m_planeNormal);\r
348         SET_FLOAT_VALUE(pParent, planeData,m_planeConstant);\r
349 \r
350         m_collisionShapeData.push_back((btCollisionShapeData*)planeData);\r
351         m_pointerLookup.insert((void*)ptr,planeData);\r
352 \r
353 }\r
354 \r
355 void btBulletXmlWorldImporter::deSerializeDynamicsWorldData(TiXmlNode* pParent)\r
356 {\r
357         btContactSolverInfo solverInfo;\r
358         //btVector3 gravity(0,0,0);\r
359 \r
360         //setDynamicsWorldInfo(gravity,solverInfo);\r
361 \r
362         //gravity and world info\r
363 }\r
364 \r
365 void btBulletXmlWorldImporter::deSerializeConvexInternalShapeData(TiXmlNode* pParent)\r
366 {\r
367         int ptr=0;\r
368         get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr);\r
369         \r
370 \r
371         btConvexInternalShapeData* convexShape = (btConvexInternalShapeData*) btAlignedAlloc(sizeof(btConvexInternalShapeData),16);\r
372         memset(convexShape,0,sizeof(btConvexInternalShapeData));\r
373 \r
374         TiXmlNode* xmlShapeData = pParent->FirstChild("m_collisionShapeData");\r
375         btAssert(xmlShapeData );\r
376 \r
377         deSerializeCollisionShapeData(xmlShapeData,&convexShape->m_collisionShapeData);\r
378 \r
379         \r
380         SET_FLOAT_VALUE(pParent,convexShape,m_collisionMargin)\r
381         SET_VECTOR4_VALUE(pParent,convexShape,m_localScaling)\r
382         SET_VECTOR4_VALUE(pParent,convexShape,m_implicitShapeDimensions)\r
383 \r
384         m_collisionShapeData.push_back((btCollisionShapeData*)convexShape);\r
385         m_pointerLookup.insert((void*)ptr,convexShape);\r
386 \r
387 }\r
388 \r
389 /*\r
390 enum btTypedConstraintType\r
391 {\r
392         POINT2POINT_CONSTRAINT_TYPE=3,\r
393         HINGE_CONSTRAINT_TYPE,\r
394         CONETWIST_CONSTRAINT_TYPE,\r
395 //      D6_CONSTRAINT_TYPE,\r
396         SLIDER_CONSTRAINT_TYPE,\r
397         CONTACT_CONSTRAINT_TYPE,\r
398         D6_SPRING_CONSTRAINT_TYPE,\r
399         GEAR_CONSTRAINT_TYPE,\r
400         MAX_CONSTRAINT_TYPE\r
401 };\r
402 */\r
403 \r
404 \r
405 void btBulletXmlWorldImporter::deSerializeGeneric6DofConstraintData(TiXmlNode* pParent)\r
406 {\r
407         int ptr=0;\r
408         get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr);\r
409         \r
410         btGeneric6DofConstraintData* dof6Data = (btGeneric6DofConstraintData*)btAlignedAlloc(sizeof(btGeneric6DofConstraintData),16);\r
411 \r
412         \r
413         TiXmlNode* n = pParent->FirstChild("m_typeConstraintData");\r
414         if (n)\r
415         {\r
416                 SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbA,btRigidBodyData*);\r
417                 SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbB,btRigidBodyData*);\r
418                 dof6Data->m_typeConstraintData.m_name = 0;//tbd\r
419                 SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_objectType);\r
420                 SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintType);\r
421                 SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintId);\r
422                 SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_needsFeedback);\r
423                 SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_appliedImpulse);\r
424                 SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_dbgDrawSize);\r
425                 SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_disableCollisionsBetweenLinkedBodies);\r
426                 SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_overrideNumSolverIterations);\r
427                 SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_breakingImpulseThreshold);\r
428                 SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_isEnabled);\r
429 \r
430         }       \r
431 \r
432         SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbAFrame);\r
433         SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbBFrame);\r
434         SET_VECTOR4_VALUE(pParent, dof6Data, m_linearUpperLimit);\r
435         SET_VECTOR4_VALUE(pParent, dof6Data, m_linearLowerLimit);\r
436         SET_VECTOR4_VALUE(pParent, dof6Data, m_angularUpperLimit);\r
437         SET_VECTOR4_VALUE(pParent, dof6Data, m_angularLowerLimit);\r
438         SET_INT_VALUE(pParent, dof6Data,m_useLinearReferenceFrameA);\r
439         SET_INT_VALUE(pParent, dof6Data,m_useOffsetForConstraintFrame);\r
440         \r
441         m_constraintData.push_back((btTypedConstraintData*)dof6Data);\r
442         m_pointerLookup.insert((void*)ptr,dof6Data);\r
443 }\r
444 \r
445 void btBulletXmlWorldImporter::deSerializeRigidBodyFloatData(TiXmlNode* pParent)\r
446 {\r
447         int ptr=0;\r
448         if (!get_int_attribute_by_name(pParent->ToElement(),"pointer",&ptr))\r
449         {\r
450                 m_fileOk = false;\r
451                 return;\r
452         }\r
453         \r
454         btRigidBodyData* rbData = (btRigidBodyData*)btAlignedAlloc(sizeof(btRigidBodyData),16);\r
455         \r
456         TiXmlNode* n = pParent->FirstChild("m_collisionObjectData");\r
457 \r
458         if (n)\r
459         {\r
460                 SET_POINTER_VALUE(n,rbData->m_collisionObjectData,m_collisionShape, void*);\r
461                 SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_worldTransform);\r
462                 SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_interpolationWorldTransform);\r
463                 SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationLinearVelocity)\r
464                 SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationAngularVelocity)\r
465                 SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_anisotropicFriction)\r
466                 SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_contactProcessingThreshold);\r
467                 SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_deactivationTime);\r
468                 SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_friction);\r
469                 SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_restitution);\r
470                 SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_hitFraction);\r
471                 SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdSweptSphereRadius);\r
472                 SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdMotionThreshold);\r
473                 SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_hasAnisotropicFriction);\r
474                 SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_collisionFlags);\r
475                 SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_islandTag1);\r
476                 SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_companionId);\r
477                 SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_activationState1);\r
478                 SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_internalType);\r
479                 SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_checkCollideWith);\r
480         }\r
481 \r
482 //      SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity);\r
483 \r
484         SET_MATRIX33_VALUE(pParent,rbData,m_invInertiaTensorWorld);\r
485 \r
486 \r
487         SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity)\r
488         SET_VECTOR4_VALUE(pParent,rbData,m_angularVelocity)\r
489         SET_VECTOR4_VALUE(pParent,rbData,m_angularFactor)\r
490         SET_VECTOR4_VALUE(pParent,rbData,m_linearFactor)\r
491         SET_VECTOR4_VALUE(pParent,rbData,m_gravity)\r
492         SET_VECTOR4_VALUE(pParent,rbData,m_gravity_acceleration )\r
493         SET_VECTOR4_VALUE(pParent,rbData,m_invInertiaLocal)\r
494         SET_VECTOR4_VALUE(pParent,rbData,m_totalTorque)\r
495         SET_VECTOR4_VALUE(pParent,rbData,m_totalForce)\r
496         SET_FLOAT_VALUE(pParent,rbData,m_inverseMass);\r
497         SET_FLOAT_VALUE(pParent,rbData,m_linearDamping);\r
498         SET_FLOAT_VALUE(pParent,rbData,m_angularDamping);\r
499         SET_FLOAT_VALUE(pParent,rbData,m_additionalDampingFactor);\r
500         SET_FLOAT_VALUE(pParent,rbData,m_additionalLinearDampingThresholdSqr);\r
501         SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingThresholdSqr);\r
502         SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingFactor);\r
503         SET_FLOAT_VALUE(pParent,rbData,m_angularSleepingThreshold);\r
504         SET_FLOAT_VALUE(pParent,rbData,m_linearSleepingThreshold);\r
505         SET_INT_VALUE(pParent,rbData,m_additionalDamping);\r
506 \r
507 \r
508         m_rigidBodyData.push_back(rbData);\r
509         m_pointerLookup.insert((void*)ptr,rbData);\r
510         \r
511 //      rbData->m_collisionObjectData.m_collisionShape = (void*) (int)atof(txt);\r
512 }\r
513 \r
514 /*\r
515         TETRAHEDRAL_SHAPE_PROXYTYPE,\r
516         CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,\r
517         ,\r
518         CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,\r
519         CUSTOM_POLYHEDRAL_SHAPE_TYPE,\r
520 //implicit convex shapes\r
521 IMPLICIT_CONVEX_SHAPES_START_HERE,\r
522         SPHERE_SHAPE_PROXYTYPE,\r
523         MULTI_SPHERE_SHAPE_PROXYTYPE,\r
524         CAPSULE_SHAPE_PROXYTYPE,\r
525         CONE_SHAPE_PROXYTYPE,\r
526         CONVEX_SHAPE_PROXYTYPE,\r
527         CYLINDER_SHAPE_PROXYTYPE,\r
528         UNIFORM_SCALING_SHAPE_PROXYTYPE,\r
529         MINKOWSKI_SUM_SHAPE_PROXYTYPE,\r
530         MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,\r
531         BOX_2D_SHAPE_PROXYTYPE,\r
532         CONVEX_2D_SHAPE_PROXYTYPE,\r
533         CUSTOM_CONVEX_SHAPE_TYPE,\r
534 //concave shapes\r
535 CONCAVE_SHAPES_START_HERE,\r
536         //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!\r
537         TRIANGLE_MESH_SHAPE_PROXYTYPE,\r
538         SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,\r
539         ///used for demo integration FAST/Swift collision library and Bullet\r
540         FAST_CONCAVE_MESH_PROXYTYPE,\r
541         //terrain\r
542         TERRAIN_SHAPE_PROXYTYPE,\r
543 ///Used for GIMPACT Trimesh integration\r
544         GIMPACT_SHAPE_PROXYTYPE,\r
545 ///Multimaterial mesh\r
546     MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,\r
547         \r
548         ,\r
549         ,\r
550         CUSTOM_CONCAVE_SHAPE_TYPE,\r
551 CONCAVE_SHAPES_END_HERE,\r
552 \r
553         ,\r
554 \r
555         SOFTBODY_SHAPE_PROXYTYPE,\r
556         HFFLUID_SHAPE_PROXYTYPE,\r
557         HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,\r
558         INVALID_SHAPE_PROXYTYPE,\r
559 \r
560         MAX_BROADPHASE_COLLISION_TYPES\r
561 */\r
562 \r
563 void    btBulletXmlWorldImporter::fixupConstraintData(btTypedConstraintData* tcd)\r
564 {\r
565         if (tcd->m_rbA)\r
566         {\r
567                 btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbA);\r
568                 btAssert(ptrptr);\r
569                 tcd->m_rbA = ptrptr? *ptrptr : 0;\r
570         }\r
571         if (tcd->m_rbB)\r
572         {\r
573                 btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbB);\r
574                 btAssert(ptrptr);\r
575                 tcd->m_rbB = ptrptr? *ptrptr : 0;\r
576         }\r
577                 \r
578 }\r
579 \r
580 void    btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData* shapeData)\r
581 {\r
582 \r
583                 switch (shapeData->m_shapeType)\r
584                 {\r
585 \r
586                 case COMPOUND_SHAPE_PROXYTYPE:\r
587                         {\r
588                                 btCompoundShapeData* compound = (btCompoundShapeData*) shapeData;\r
589                                 \r
590                                 void** cdptr = m_pointerLookup.find((void*)compound->m_childShapePtr);\r
591                                 btCompoundShapeChildData** c = (btCompoundShapeChildData**)cdptr;\r
592                                 btAssert(c);\r
593                                 if (c)\r
594                                 {\r
595                                         compound->m_childShapePtr = *c;\r
596                                 } else\r
597                                 {\r
598                                         compound->m_childShapePtr = 0;\r
599                                 }\r
600                                 break;\r
601                         }\r
602 \r
603                 case CONVEX_HULL_SHAPE_PROXYTYPE:\r
604                         {\r
605                                 btConvexHullShapeData* convexData = (btConvexHullShapeData*)shapeData;\r
606                                 btVector3FloatData** ptrptr = (btVector3FloatData**)m_pointerLookup.find((void*)convexData->m_unscaledPointsFloatPtr);\r
607                                 btAssert(ptrptr);\r
608                                 if (ptrptr)\r
609                                 {\r
610                                         convexData->m_unscaledPointsFloatPtr = *ptrptr;\r
611                                 } else\r
612                                 {\r
613                                         convexData->m_unscaledPointsFloatPtr = 0;\r
614                                 }\r
615                                 break;\r
616                         }\r
617 \r
618                 case BOX_SHAPE_PROXYTYPE:\r
619                 case TRIANGLE_SHAPE_PROXYTYPE:\r
620                 case STATIC_PLANE_PROXYTYPE:\r
621                 case EMPTY_SHAPE_PROXYTYPE:\r
622                         break;\r
623 \r
624                 default:\r
625                         {\r
626                                 btAssert(0);\r
627                         }\r
628                 }\r
629 }\r
630 \r
631 \r
632 void btBulletXmlWorldImporter::auto_serialize_root_level_children(TiXmlNode* pParent)\r
633 {\r
634         int numChildren = 0;\r
635         btAssert(pParent);\r
636         if (pParent)\r
637         {\r
638                 TiXmlNode*pChild; \r
639                 for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling(), numChildren++) \r
640                 {\r
641 //                      printf("child Name=%s\n", pChild->Value());\r
642                         if (!strcmp(pChild->Value(),"btVector3FloatData"))\r
643                         {\r
644                                 int ptr;\r
645                                 get_int_attribute_by_name(pChild->ToElement(),"pointer",&ptr);\r
646                                 \r
647                                 btAlignedObjectArray<btVector3FloatData> v;\r
648                                 deSerializeVector3FloatData(pChild,v);\r
649                                 int numVectors = v.size();\r
650                                 btVector3FloatData* vectors= (btVector3FloatData*) btAlignedAlloc(sizeof(btVector3FloatData)*numVectors,16);\r
651                                 for (int i=0;i<numVectors;i++)\r
652                                         vectors[i] = v[i];\r
653                                 m_floatVertexArrays.push_back(vectors);\r
654                                 m_pointerLookup.insert((void*)ptr,vectors);\r
655                                 continue;\r
656                         }\r
657 \r
658                         if (!strcmp(pChild->Value(),"btGeneric6DofConstraintData"))\r
659                         {\r
660                                 deSerializeGeneric6DofConstraintData(pChild);\r
661                                 continue;\r
662                         }\r
663 \r
664                         if (!strcmp(pChild->Value(),"btStaticPlaneShapeData"))\r
665                         {\r
666                                 deSerializeStaticPlaneShapeData(pChild);\r
667                                 continue;\r
668                         }\r
669 \r
670                         if (!strcmp(pChild->Value(),"btCompoundShapeData"))\r
671                         {\r
672                                 deSerializeCompoundShapeData(pChild);\r
673                                 continue;\r
674                         }\r
675 \r
676                         if (!strcmp(pChild->Value(),"btCompoundShapeChildData"))\r
677                         {\r
678                                 deSerializeCompoundShapeChildData(pChild);\r
679                                 continue;\r
680                         }\r
681 \r
682                         if (!strcmp(pChild->Value(),"btConvexHullShapeData"))\r
683                         {\r
684                                 deSerializeConvexHullShapeData(pChild);\r
685                                 continue;\r
686                         }\r
687 \r
688                         if (!strcmp(pChild->Value(),"btDynamicsWorldFloatData"))\r
689                         {\r
690                                 deSerializeDynamicsWorldData(pChild);\r
691                                 continue;\r
692                         }\r
693                         \r
694 \r
695                         if (!strcmp(pChild->Value(),"btConvexInternalShapeData"))\r
696                         {\r
697                                 deSerializeConvexInternalShapeData(pChild);\r
698                                 continue;\r
699                         }\r
700                         if (!strcmp(pChild->Value(),"btRigidBodyFloatData"))\r
701                         {\r
702                                 deSerializeRigidBodyFloatData(pChild);\r
703                                 continue;\r
704                         }\r
705 \r
706                         //printf("Error: btBulletXmlWorldImporter doesn't support %s yet\n", pChild->Value());\r
707                 //      btAssert(0);\r
708                 }\r
709         } \r
710 \r
711         ///=================================================================\r
712         ///fixup pointers in various places, in the right order\r
713 \r
714         //fixup compoundshape child data\r
715         for (int i=0;i<m_compoundShapeChildDataArrays.size();i++)\r
716         {\r
717                 btAlignedObjectArray<btCompoundShapeChildData>* childDataArray = m_compoundShapeChildDataArrays[i];\r
718                 for (int c=0;c<childDataArray->size();c++)\r
719                 {\r
720                         btCompoundShapeChildData* childData = &childDataArray->at(c);\r
721                         btCollisionShapeData** ptrptr = (btCollisionShapeData**)m_pointerLookup[childData->m_childShape];\r
722                         btAssert(ptrptr);\r
723                         if (ptrptr)\r
724                         {\r
725                                 childData->m_childShape = *ptrptr;\r
726                         }\r
727                 }\r
728         }\r
729 \r
730         for (int i=0;i<this->m_collisionShapeData.size();i++)\r
731         {\r
732                 btCollisionShapeData* shapeData = m_collisionShapeData[i];\r
733                 fixupCollisionDataPointers(shapeData);\r
734                 \r
735         }\r
736         \r
737         ///now fixup pointers\r
738         for (int i=0;i<m_rigidBodyData.size();i++)\r
739         {\r
740                 btRigidBodyData* rbData = m_rigidBodyData[i];\r
741                 \r
742                 void** ptrptr = m_pointerLookup.find(rbData->m_collisionObjectData.m_collisionShape);\r
743                 //btAssert(ptrptr);\r
744                 rbData->m_collisionObjectData.m_broadphaseHandle = 0;\r
745                 rbData->m_collisionObjectData.m_rootCollisionShape = 0;\r
746                 rbData->m_collisionObjectData.m_name = 0;//tbd\r
747                 if (ptrptr)\r
748                 {\r
749                         rbData->m_collisionObjectData.m_collisionShape = *ptrptr;\r
750                 }\r
751         }\r
752 \r
753         \r
754 \r
755         for (int i=0;i<m_constraintData.size();i++)\r
756         {\r
757                 btTypedConstraintData* tcd = m_constraintData[i];\r
758                 fixupConstraintData(tcd);\r
759                 \r
760         }\r
761         ///=================================================================\r
762         ///convert data into Bullet data in the right order\r
763 \r
764         ///convert collision shapes\r
765         for (int i=0;i<this->m_collisionShapeData.size();i++)\r
766         {\r
767                 btCollisionShapeData* shapeData = m_collisionShapeData[i];\r
768                 btCollisionShape* shape = convertCollisionShape(shapeData);\r
769                 if (shape)\r
770                 {\r
771                         m_shapeMap.insert(shapeData,shape);\r
772                 }\r
773                 if (shape&& shapeData->m_name)\r
774                 {\r
775                         char* newname = duplicateName(shapeData->m_name);\r
776                         m_objectNameMap.insert(shape,newname);\r
777                         m_nameShapeMap.insert(newname,shape);\r
778                 }\r
779         }\r
780 \r
781         for (int i=0;i<m_rigidBodyData.size();i++)\r
782         {\r
783 #ifdef BT_USE_DOUBLE_PRECISION\r
784                 convertRigidBodyDouble(m_rigidBodyData[i]);\r
785 #else\r
786                 convertRigidBodyFloat(m_rigidBodyData[i]);\r
787 #endif\r
788         }\r
789 \r
790         for (int i=0;i<m_constraintData.size();i++)\r
791         {\r
792                 btTypedConstraintData* tcd = m_constraintData[i];\r
793                 bool isDoublePrecision = false;\r
794                 btRigidBody* rbA = 0;\r
795                 btRigidBody* rbB = 0;\r
796                 {\r
797                         btCollisionObject** ptrptr = m_bodyMap.find(tcd->m_rbA);\r
798                         if (ptrptr)\r
799                         {\r
800                                 rbA = btRigidBody::upcast(*ptrptr);\r
801                         }\r
802                 }\r
803                 {\r
804                         btCollisionObject** ptrptr = m_bodyMap.find(tcd->m_rbB);\r
805                         if (ptrptr)\r
806                         {\r
807                                 rbB = btRigidBody::upcast(*ptrptr);\r
808                         }\r
809                 }\r
810                 if (rbA || rbB)\r
811                 {\r
812                         convertConstraint(tcd,rbA,rbB,isDoublePrecision, m_fileVersion);\r
813                 }\r
814 \r
815         }\r
816 }\r
817 \r
818 void btBulletXmlWorldImporter::auto_serialize(TiXmlNode* pParent)\r
819 {\r
820 //      TiXmlElement* root = pParent->FirstChildElement("bullet_physics");\r
821         if (pParent)\r
822         {\r
823                 TiXmlNode*pChild; \r
824                 for ( pChild = pParent->FirstChild(); pChild != 0; pChild = pChild->NextSibling()) \r
825                 {\r
826                         if (pChild->Type()==TiXmlNode::TINYXML_ELEMENT)\r
827                         {\r
828 //                              printf("root Name=%s\n", pChild->Value());\r
829                                 auto_serialize_root_level_children(pChild);\r
830                         }\r
831                 }\r
832         } else\r
833         {\r
834                 printf("ERROR: no bullet_physics element\n");\r
835         }\r
836 }\r
837 \r
838 \r
839 \r
840 \r
841 bool btBulletXmlWorldImporter::loadFile(const char* fileName)\r
842 {\r
843         TiXmlDocument doc(fileName);\r
844 \r
845         bool loadOkay = doc.LoadFile();\r
846         //dump_to_stdout(&doc,0);\r
847         \r
848 \r
849         if (loadOkay)\r
850         {\r
851                 if (get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"version", &m_fileVersion))\r
852                 {\r
853                         if (m_fileVersion==281)\r
854                         {\r
855                                 m_fileOk = true;\r
856                                 int itemcount;\r
857                                 get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"itemcount", &itemcount);\r
858 \r
859                                 auto_serialize(&doc);\r
860                                 return m_fileOk;\r
861 \r
862                         }\r
863                 }\r
864         }\r
865         return false;\r
866 }\r
867 \r
868 \r
869 \r
870 \r