resetting manifest requested domain to floor
[platform/upstream/libbullet.git] / Demos / SerializeDemo / SerializeDemo.cpp
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2010 Erwin Coumans  http://continuousphysics.com/Bullet/
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 #define TEST_SERIALIZATION 1
17 //#undef DESERIALIZE_SOFT_BODIES
18
19 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
20 #define CREATE_NEW_BULLETFILE 1
21 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
22
23 ///create 125 (5x5x5) dynamic object
24 #define ARRAY_SIZE_X 5
25 #define ARRAY_SIZE_Y 5
26 #define ARRAY_SIZE_Z 5
27
28 //maximum number of objects (and allow user to shoot additional boxes)
29 #define MAX_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z + 1024)
30
31 ///scaling of the objects (0.1 = 20 centimeter boxes )
32 #define SCALING 1.
33 #define START_POS_X -5
34 #define START_POS_Y -5
35 #define START_POS_Z -3
36
37 #include "SerializeDemo.h"
38 #include "GlutStuff.h"
39 ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
40 #include "btBulletDynamicsCommon.h"
41 #ifdef TEST_SERIALIZATION
42 #include "LinearMath/btSerializer.h"
43 #include "btBulletFile.h"
44 #include "btBulletWorldImporter.h"
45 #endif //TEST_SERIALIZATION
46
47 #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
48 #include <stdio.h> //printf debugging
49
50
51
52 #ifdef DESERIALIZE_SOFT_BODIES
53 #include "BulletSoftBody/btSoftBodySolvers.h"
54
55
56 #ifdef USE_AMD_OPENCL
57     #include <BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h>
58     #include <BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h>
59         #include "../SharedOpenCL/btOpenCLUtils.h"
60
61     extern cl_context           g_cxMainContext;
62     extern cl_device_id     g_cdDevice;
63     extern cl_command_queue g_cqCommandQue;
64 #endif
65
66 btSoftBodySolver*       fSoftBodySolver=0;
67
68 #include "BulletSoftBody/btSoftBodyHelpers.h"
69 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
70 #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
71 #endif
72
73 void SerializeDemo::keyboardCallback(unsigned char key, int x, int y)
74 {
75         btAlignedObjectArray<btRigidBody*> bodies;
76         if (key == 'g')
77         {
78                 int numManifolds = getDynamicsWorld()->getDispatcher()->getNumManifolds();
79
80                 for (int i=0;i<numManifolds;i++)
81                 {
82                         btPersistentManifold* manifold = getDynamicsWorld()->getDispatcher()->getManifoldByIndexInternal(i);
83                         if (!manifold->getNumContacts())
84                                 continue;
85
86                         btScalar minDist = 1e30f;
87                         int minIndex = -1;
88                         for (int v=0;v<manifold->getNumContacts();v++)
89                         {
90                                 if (minDist >manifold->getContactPoint(v).getDistance())
91                                 {
92                                         minDist = manifold->getContactPoint(v).getDistance();
93                                         minIndex = v;
94                                 }
95                         }
96                         if (minDist>0.)
97                                 continue;
98                 
99                         btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0();
100                         btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1();
101                 //      int tag0 = (colObj0)->getIslandTag();
102                 //      int tag1 = (colObj1)->getIslandTag();
103                         btRigidBody* body0 = btRigidBody::upcast(colObj0);
104                         btRigidBody* body1 = btRigidBody::upcast(colObj1);
105                         if (bodies.findLinearSearch(body0)==bodies.size())
106                                 bodies.push_back(body0);
107                         if (bodies.findLinearSearch(body1)==bodies.size())
108                                 bodies.push_back(body1);
109
110                         if (body0 && body1)
111                         {
112                                 if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject())
113                                 {
114                                         if (body0->checkCollideWithOverride(body1))
115                                         {
116                                                 {
117                                                         btTransform trA,trB;
118                                                         trA.setIdentity();
119                                                         trB.setIdentity();
120                                                         btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA;
121                                                         btTransform globalFrame;
122                                                         globalFrame.setIdentity();
123                                                         globalFrame.setOrigin(contactPosWorld);
124
125                                                         trA = body0->getWorldTransform().inverse()*globalFrame;
126                                                         trB = body1->getWorldTransform().inverse()*globalFrame;
127
128                                                         btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true);
129                                                         dof6->setOverrideNumSolverIterations(100);
130
131                                                         dof6->setBreakingImpulseThreshold(35);
132
133                                                         for (int i=0;i<6;i++)
134                                                                 dof6->setLimit(i,0,0);
135                                                         getDynamicsWorld()->addConstraint(dof6,true);
136                                                         
137                                                 }
138                                         }
139                                 }
140                         }
141                         
142                 } 
143
144                 for (int i=0;i<bodies.size();i++)
145                 {
146                         getDynamicsWorld()->removeRigidBody(bodies[i]);
147                         getDynamicsWorld()->addRigidBody(bodies[i]);
148                 }
149         }else
150         {
151                 PlatformDemoApplication::keyboardCallback(key,x,y);
152         }
153 }
154
155
156 void SerializeDemo::clientMoveAndDisplay()
157 {
158         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
159
160         //simple dynamics world doesn't handle fixed-time-stepping
161         float ms = getDeltaTimeMicroseconds();
162         
163         ///step the simulation
164         if (m_dynamicsWorld)
165         {
166                 m_dynamicsWorld->stepSimulation(ms / 1000000.f);
167
168                 
169 #ifdef DESERIALIZE_SOFT_BODIES
170                 if (fSoftBodySolver)
171             fSoftBodySolver->copyBackToSoftBodies();
172 #endif
173
174                 m_dynamicsWorld->debugDrawWorld();
175
176 #ifdef DESERIALIZE_SOFT_BODIES
177                 if (m_dynamicsWorld->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD)
178                 {
179                         //optional but useful: debug drawing
180                         btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
181
182                         for (  int i=0;i<softWorld->getSoftBodyArray().size();i++)
183                         {
184                                 btSoftBody*     psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
185                                 if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
186                                 {
187                                         btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
188                                         btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
189                                 }
190                         }
191                 }
192 #endif //DESERIALIZE_SOFT_BODIES
193
194         }
195                 
196         renderme(); 
197
198         glFlush();
199
200         swapBuffers();
201
202 }
203 #ifdef USE_AMD_OPENCL
204
205 ///the CachingCLFuncs class will try to create/load precompiled binary programs, instead of the slow on-line compilation of programs
206 class CachingCLFuncs : public CLFunctions
207 {
208         cl_device_id m_device;
209
210         public:
211
212         CachingCLFuncs (cl_command_queue cqCommandQue, cl_context cxMainContext, cl_device_id device) 
213         :CLFunctions(cqCommandQue,cxMainContext),
214         m_device(device)
215         {
216         }
217
218         virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros, const char* srcFileNameForCaching)
219         {
220
221                 cl_int pErrNum;
222                 cl_program prog;
223                 
224                 prog = btOpenCLUtils::compileCLProgramFromFile( m_cxMainContext,m_device, &pErrNum,additionalMacros ,srcFileNameForCaching);
225                 if (!prog)
226                 {
227                         printf("Using embedded kernel source instead:\n");
228                         prog = btOpenCLUtils::compileCLProgramFromString( m_cxMainContext,m_device, kernelSource, &pErrNum,additionalMacros);
229                 }
230                 
231                 return btOpenCLUtils::compileCLKernelFromString( m_cxMainContext,m_device, kernelSource, kernelName, &pErrNum, prog,additionalMacros);
232         }
233
234 };
235 #endif
236
237
238 void SerializeDemo::displayCallback(void) {
239
240         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
241         
242         if (m_dynamicsWorld->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD)
243         {
244 #ifdef DESERIALIZE_SOFT_BODIES
245
246                 //optional but useful: debug drawing
247                 btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
248
249                 for (  int i=0;i<softWorld->getSoftBodyArray().size();i++)
250                 {
251                         btSoftBody*     psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
252                         if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
253                         {
254                                 btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
255                                 btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
256                         }
257                 }
258 #endif //DESERIALIZE_SOFT_BODIES
259         }
260
261         renderme();
262
263         //optional but useful: debug drawing to detect problems
264         if (m_dynamicsWorld)
265                 m_dynamicsWorld->debugDrawWorld();
266
267         glFlush();
268         swapBuffers();
269 }
270
271 enum SolverType
272 {
273         kSolverAccelerationOpenCL_CPU = 1,
274         kSolverAccelerationOpenCL_GPU = 2,
275         kSolverAccelerationNone = 3
276 };
277
278
279 void    SerializeDemo::setupEmptyDynamicsWorld()
280 {
281         ///collision configuration contains default setup for memory, collision setup
282         //m_collisionConfiguration = new btDefaultCollisionConfiguration();
283 #ifdef DESERIALIZE_SOFT_BODIES
284         m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
285 #else
286         m_collisionConfiguration = new btDefaultCollisionConfiguration();
287 #endif //DESERIALIZE_SOFT_BODIES
288
289         //m_collisionConfiguration->setConvexConvexMultipointIterations();
290
291         ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
292         m_dispatcher = new      btCollisionDispatcher(m_collisionConfiguration);
293         btGImpactCollisionAlgorithm::registerAlgorithm(m_dispatcher);
294
295         m_broadphase = new btDbvtBroadphase();
296         
297
298         ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
299         btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
300         m_solver = sol;
301
302 #ifdef DESERIALIZE_SOFT_BODIES
303
304         
305
306         #ifdef USE_AMD_OPENCL
307
308         int solverAccel = kSolverAccelerationOpenCL_GPU;
309
310     if ( 1 ) {
311         switch (solverAccel)
312         {        
313             case kSolverAccelerationOpenCL_GPU:
314             {
315                 btOpenCLSoftBodySolverSIMDAware* softSolv= new btOpenCLSoftBodySolverSIMDAware( g_cqCommandQue, g_cxMainContext );
316                                 //btOpenCLSoftBodySolver* softSolv= new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext);
317                                 fSoftBodySolver = softSolv;
318                                 
319                                 CLFunctions* funcs = new CachingCLFuncs(g_cqCommandQue, g_cxMainContext,g_cdDevice);
320                                 softSolv->setCLFunctions(funcs);
321                                 
322
323                 break;
324             }
325             case kSolverAccelerationOpenCL_CPU:
326                 {
327                     //fSoftBodySolver = new btCPUSoftBodySolver();
328                     break;
329                 };
330             case kSolverAccelerationNone:
331             default:
332             {
333                 fSoftBodySolver = NULL;
334             }
335         };
336     }
337     else 
338         {
339         if ( solverAccel != kSolverAccelerationNone ) 
340                 {
341         }
342         else 
343                 {
344                 }
345         fSoftBodySolver = NULL;
346     }
347 #else
348    
349     fSoftBodySolver = NULL;
350 #endif
351     
352     btSoftRigidDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver,
353                                           m_collisionConfiguration, fSoftBodySolver);
354         m_dynamicsWorld = world;
355
356
357         //world->setDrawFlags(world->getDrawFlags()^fDrawFlags::Clusters);
358 #else
359         m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
360         //m_dynamicsWorld ->getSolverInfo().m_solverMode|=SOLVER_RANDMIZE_ORDER;
361         //m_dynamicsWorld->getDispatchInfo().m_enableSatConvex = true;
362         //m_dynamicsWorld->getSolverInfo().m_splitImpulse=true;
363 #endif //DESERIALIZE_SOFT_BODIES
364
365         //btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher*)m_dynamicsWorld->getDispatcher());
366
367         m_dynamicsWorld->setGravity(btVector3(0,-10,0));
368
369 }
370
371
372 #ifdef DESERIALIZE_SOFT_BODIES
373 #include "BulletSoftBody/btSoftBodyData.h"
374 class MySoftBulletWorldImporter : public btBulletWorldImporter
375 {
376
377         btSoftRigidDynamicsWorld* m_softRigidWorld;
378
379         btHashMap<btHashPtr,btSoftBody::Material*>      m_materialMap;
380
381         btHashMap<btHashPtr,btSoftBody*>        m_clusterBodyMap;
382         btHashMap<btHashPtr,btSoftBody*>        m_softBodyMap;
383         
384
385
386 public:
387
388         MySoftBulletWorldImporter(btSoftRigidDynamicsWorld* world)
389                 :btBulletWorldImporter(world),
390                 m_softRigidWorld(world)
391         {
392
393         }
394
395         virtual ~MySoftBulletWorldImporter()
396         {
397                 
398         }
399
400         virtual bool convertAllObjects(  bParse::btBulletFile* bulletFile2)
401         {
402                 bool result = btBulletWorldImporter::convertAllObjects(bulletFile2);
403                 int i;
404                 //now the soft bodies
405                 for (i=0;i<bulletFile2->m_softBodies.size();i++)
406                 {
407                         if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
408                         {
409                                 btAssert(0); //not yet
410                                 //btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
411                         } else
412                         {
413                                 btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
414                                 int i;
415                                 int numNodes = softBodyData->m_numNodes;
416                                 
417                 
418                                 btSoftBody*             psb=new btSoftBody(&m_softRigidWorld->getWorldInfo());
419                                 m_softBodyMap.insert(softBodyData,psb);
420
421                                 //materials
422                                 for (i=0;i<softBodyData->m_numMaterials;i++)
423                                 {
424                                         SoftBodyMaterialData* matData = softBodyData->m_materials[i];
425                                         btSoftBody::Material** matPtr = m_materialMap.find(matData);
426                                         btSoftBody::Material* mat = 0;
427                                         if (matPtr&& *matPtr)
428                                         {
429                                                 mat = *matPtr;
430                                         } else
431                                         {
432                                                 mat = psb->appendMaterial();
433                                                 mat->m_flags = matData->m_flags;
434                                                 mat->m_kAST = matData->m_angularStiffness;
435                                                 mat->m_kLST = matData->m_linearStiffness;
436                                                 mat->m_kVST = matData->m_volumeStiffness;
437                                                 m_materialMap.insert(matData,mat);
438                                         }
439                                 }
440
441
442
443
444                                 for (i=0;i<numNodes;i++)
445                                 {
446                                         SoftBodyNodeData& nodeData = softBodyData->m_nodes[i];
447                                         btVector3 position;
448                                         position.deSerializeFloat(nodeData.m_position);
449                                         btScalar mass = nodeData.m_inverseMass? 1./nodeData.m_inverseMass : 0.f;
450                                         psb->appendNode(position,mass);
451                                         btSoftBody::Node* node = &psb->m_nodes[psb->m_nodes.size()-1];
452                                         node->m_area = nodeData.m_area;
453                                         node->m_battach = nodeData.m_attach;
454                                         node->m_f.deSerializeFloat(nodeData.m_accumulatedForce);
455                                         node->m_im = nodeData.m_inverseMass;
456
457                                         btSoftBody::Material** matPtr = m_materialMap.find(nodeData.m_material);
458                                         if (matPtr && *matPtr)
459                                         {
460                                                 node->m_material = *matPtr;
461                                         } else
462                                         {
463                                                 printf("no mat?\n");
464                                         }
465                                         
466                                         node->m_n.deSerializeFloat(nodeData.m_normal);
467                                         node->m_q = node->m_x;
468                                         node->m_v.deSerializeFloat(nodeData.m_velocity);
469                                         
470                                 }
471
472                                 for (i=0;i<softBodyData->m_numLinks;i++)
473                                 {
474                                         SoftBodyLinkData& linkData = softBodyData->m_links[i];
475                                         btSoftBody::Material** matPtr = m_materialMap.find(linkData.m_material);
476                                         if (matPtr && *matPtr)
477                                         {
478                                                 psb->appendLink(linkData.m_nodeIndices[0],linkData.m_nodeIndices[1],*matPtr);
479                                         } else
480                                         {
481                                                 psb->appendLink(linkData.m_nodeIndices[0],linkData.m_nodeIndices[1]);
482                                         }
483                                         btSoftBody::Link* link = &psb->m_links[psb->m_links.size()-1];
484                                         link->m_bbending = linkData.m_bbending;
485                                         link->m_rl = linkData.m_restLength;
486                                 }
487
488                                 for (i=0;i<softBodyData->m_numFaces;i++)
489                                 {
490                                         SoftBodyFaceData& faceData = softBodyData->m_faces[i];
491                                         btSoftBody::Material** matPtr = m_materialMap.find(faceData.m_material);
492                                         if (matPtr && *matPtr)
493                                         {
494                                                 psb->appendFace(faceData.m_nodeIndices[0],faceData.m_nodeIndices[1],faceData.m_nodeIndices[2],*matPtr);
495                                         } else
496                                         {
497                                                 psb->appendFace(faceData.m_nodeIndices[0],faceData.m_nodeIndices[1],faceData.m_nodeIndices[2]);
498                                         }
499                                         btSoftBody::Face* face = &psb->m_faces[psb->m_faces.size()-1];
500                                         face->m_normal.deSerializeFloat(faceData.m_normal);
501                                         face->m_ra = faceData.m_restArea;
502                                 }
503
504                         
505
506                                 //anchors
507                                 for (i=0;i<softBodyData->m_numAnchors;i++)
508                                 {
509                                         btCollisionObject** colAptr = m_bodyMap.find(softBodyData->m_anchors[i].m_rigidBody);
510                                         if (colAptr && *colAptr)
511                                         {
512                                                 btRigidBody* body = btRigidBody::upcast(*colAptr);
513                                                 if (body)
514                                                 {
515                                                         bool disableCollision = false;
516                                                         btVector3 localPivot;
517                                                         localPivot.deSerializeFloat(softBodyData->m_anchors[i].m_localFrame);
518                                                         psb->appendAnchor(softBodyData->m_anchors[i].m_nodeIndex,body,localPivot, disableCollision);
519                                                 }
520                                         }
521                                 }
522
523                                 if (softBodyData->m_pose)
524                                 {
525                                         psb->m_pose.m_aqq.deSerializeFloat(  softBodyData->m_pose->m_aqq);
526                                         psb->m_pose.m_bframe = (softBodyData->m_pose->m_bframe!=0);
527                                         psb->m_pose.m_bvolume = (softBodyData->m_pose->m_bvolume!=0);
528                                         psb->m_pose.m_com.deSerializeFloat(softBodyData->m_pose->m_com);
529                                         
530                                         psb->m_pose.m_pos.resize(softBodyData->m_pose->m_numPositions);
531                                         for (i=0;i<softBodyData->m_pose->m_numPositions;i++)
532                                         {
533                                                 psb->m_pose.m_pos[i].deSerializeFloat(softBodyData->m_pose->m_positions[i]);
534                                         }
535                                         psb->m_pose.m_rot.deSerializeFloat(softBodyData->m_pose->m_rot);
536                                         psb->m_pose.m_scl.deSerializeFloat(softBodyData->m_pose->m_scale);
537                                         psb->m_pose.m_wgh.resize(softBodyData->m_pose->m_numWeigts);
538                                         for (i=0;i<softBodyData->m_pose->m_numWeigts;i++)
539                                         {
540                                                 psb->m_pose.m_wgh[i] = softBodyData->m_pose->m_weights[i];
541                                         }
542                                         psb->m_pose.m_volume = softBodyData->m_pose->m_restVolume;
543                                 }
544
545 #if 1
546                                 psb->m_cfg.piterations=softBodyData->m_config.m_positionIterations;
547                                 psb->m_cfg.diterations=softBodyData->m_config.m_driftIterations;
548                                 psb->m_cfg.citerations=softBodyData->m_config.m_clusterIterations;
549                                 psb->m_cfg.viterations=softBodyData->m_config.m_velocityIterations;
550                                 
551                                 //psb->setTotalMass(0.1);
552                                 psb->m_cfg.aeromodel = (btSoftBody::eAeroModel::_)softBodyData->m_config.m_aeroModel;
553                                 psb->m_cfg.kLF = softBodyData->m_config.m_lift;
554                                 psb->m_cfg.kDG = softBodyData->m_config.m_drag;
555                                 psb->m_cfg.kMT = softBodyData->m_config.m_poseMatch;
556                                 psb->m_cfg.collisions = softBodyData->m_config.m_collisionFlags;
557                                 psb->m_cfg.kDF = 1.f;//softBodyData->m_config.m_dynamicFriction;
558                                 psb->m_cfg.kDP = softBodyData->m_config.m_damping;
559                                 psb->m_cfg.kPR = softBodyData->m_config.m_pressure;
560                                 psb->m_cfg.kVC = softBodyData->m_config.m_volume;
561                                 psb->m_cfg.kAHR = softBodyData->m_config.m_anchorHardness;
562                                 psb->m_cfg.kKHR = softBodyData->m_config.m_kineticContactHardness;
563                                 psb->m_cfg.kSHR = softBodyData->m_config.m_softContactHardness;
564                                 psb->m_cfg.kSRHR_CL = softBodyData->m_config.m_softRigidClusterHardness;
565                                 psb->m_cfg.kSKHR_CL = softBodyData->m_config.m_softKineticClusterHardness;
566                                 psb->m_cfg.kSSHR_CL = softBodyData->m_config.m_softSoftClusterHardness;
567 #endif
568
569 //                              pm->m_kLST                              =       1;
570
571 #if 1
572                                 //clusters
573                                 if (softBodyData->m_numClusters)
574                                 {
575                                         m_clusterBodyMap.insert(softBodyData->m_clusters,psb);
576                                         int j;
577                                         psb->m_clusters.resize(softBodyData->m_numClusters);
578                                         for (i=0;i<softBodyData->m_numClusters;i++)
579                                         {
580                                                 psb->m_clusters[i] = new(btAlignedAlloc(sizeof(btSoftBody::Cluster),16)) btSoftBody::Cluster();
581                                                 psb->m_clusters[i]->m_adamping = softBodyData->m_clusters[i].m_adamping;
582                                                 psb->m_clusters[i]->m_av.deSerializeFloat(softBodyData->m_clusters[i].m_av);
583                                                 psb->m_clusters[i]->m_clusterIndex = softBodyData->m_clusters[i].m_clusterIndex;
584                                                 psb->m_clusters[i]->m_collide = (softBodyData->m_clusters[i].m_collide!=0);
585                                                 psb->m_clusters[i]->m_com.deSerializeFloat(softBodyData->m_clusters[i].m_com);
586                                                 psb->m_clusters[i]->m_containsAnchor = (softBodyData->m_clusters[i].m_containsAnchor!=0);
587                                                 psb->m_clusters[i]->m_dimpulses[0].deSerializeFloat(softBodyData->m_clusters[i].m_dimpulses[0]);
588                                                 psb->m_clusters[i]->m_dimpulses[1].deSerializeFloat(softBodyData->m_clusters[i].m_dimpulses[1]);
589
590                                                 psb->m_clusters[i]->m_framerefs.resize(softBodyData->m_clusters[i].m_numFrameRefs);
591                                                 for (j=0;j<softBodyData->m_clusters[i].m_numFrameRefs;j++)
592                                                 {
593                                                         psb->m_clusters[i]->m_framerefs[j].deSerializeFloat(softBodyData->m_clusters[i].m_framerefs[j]);
594                                                 }
595                                                 psb->m_clusters[i]->m_nodes.resize(softBodyData->m_clusters[i].m_numNodes);
596                                                 for (j=0;j<softBodyData->m_clusters[i].m_numNodes;j++)
597                                                 {
598                                                         int nodeIndex = softBodyData->m_clusters[i].m_nodeIndices[j];
599                                                         psb->m_clusters[i]->m_nodes[j] = &psb->m_nodes[nodeIndex];
600                                                 }
601
602                                                 psb->m_clusters[i]->m_masses.resize(softBodyData->m_clusters[i].m_numMasses);
603                                                 for (j=0;j<softBodyData->m_clusters[i].m_numMasses;j++)
604                                                 {
605                                                         psb->m_clusters[i]->m_masses[j] = softBodyData->m_clusters[i].m_masses[j];
606                                                 }
607                                                 psb->m_clusters[i]->m_framexform.deSerializeFloat(softBodyData->m_clusters[i].m_framexform);
608                                                 psb->m_clusters[i]->m_idmass = softBodyData->m_clusters[i].m_idmass;
609                                                 psb->m_clusters[i]->m_imass = softBodyData->m_clusters[i].m_imass;
610                                                 psb->m_clusters[i]->m_invwi.deSerializeFloat(softBodyData->m_clusters[i].m_invwi);
611                                                 psb->m_clusters[i]->m_ldamping = softBodyData->m_clusters[i].m_ldamping;
612                                                 psb->m_clusters[i]->m_locii.deSerializeFloat(softBodyData->m_clusters[i].m_locii);
613                                                 psb->m_clusters[i]->m_lv.deSerializeFloat(softBodyData->m_clusters[i].m_lv);
614                                                 psb->m_clusters[i]->m_matching = softBodyData->m_clusters[i].m_matching;
615                                                 psb->m_clusters[i]->m_maxSelfCollisionImpulse = 0;//softBodyData->m_clusters[i].m_maxSelfCollisionImpulse;
616                                                 psb->m_clusters[i]->m_ndamping = softBodyData->m_clusters[i].m_ndamping;
617                                                 psb->m_clusters[i]->m_ndimpulses = softBodyData->m_clusters[i].m_ndimpulses;
618                                                 psb->m_clusters[i]->m_nvimpulses = softBodyData->m_clusters[i].m_nvimpulses;
619                                                 psb->m_clusters[i]->m_selfCollisionImpulseFactor = softBodyData->m_clusters[i].m_selfCollisionImpulseFactor;
620                                                 psb->m_clusters[i]->m_vimpulses[0].deSerializeFloat(softBodyData->m_clusters[i].m_vimpulses[0]);
621                                                 psb->m_clusters[i]->m_vimpulses[1].deSerializeFloat(softBodyData->m_clusters[i].m_vimpulses[1]);
622                                                 
623                                         }
624                                         //psb->initializeClusters();
625                                         //psb->updateClusters();
626
627                                 }
628 #else
629
630                                 psb->m_cfg.piterations  =       2;
631                                 psb->m_cfg.collisions   =       btSoftBody::fCollision::CL_SS+  btSoftBody::fCollision::CL_RS;
632                                 //psb->setTotalMass(50,true);
633                                 //psb->generateClusters(64);
634                                 //psb->m_cfg.kDF=1;
635                                 psb->generateClusters(8);
636
637
638 #endif //
639
640
641
642                                 psb->updateConstants();
643                                 m_softRigidWorld->getWorldInfo().m_dispatcher = m_softRigidWorld->getDispatcher();
644                                 
645                                 m_softRigidWorld->addSoftBody(psb);
646
647
648                         }
649                 }
650
651
652                 //now the soft body joints
653                 for (i=0;i<bulletFile2->m_softBodies.size();i++)
654                 {
655                         if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
656                         {
657                                 btAssert(0); //not yet
658                                 //btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
659                         } else
660                         {
661                                 btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
662                                 btSoftBody** sbp = m_softBodyMap.find(softBodyData);
663                                 if (sbp && *sbp)
664                                 {
665                                         btSoftBody* sb = *sbp;
666                                         for (int i=0;i<softBodyData->m_numJoints;i++)
667                                         {
668                                                 btSoftBodyJointData* sbjoint = &softBodyData->m_joints[i];
669
670
671                                                 btSoftBody::Body bdyB;
672
673                                                 btSoftBody* sbB = 0;
674                                                 btTransform transA;
675                                                 transA.setIdentity();
676                                                 transA = sb->m_clusters[0]->m_framexform;
677
678                                                 btCollisionObject** colBptr = m_bodyMap.find(sbjoint->m_bodyB);
679                                                 if (colBptr && *colBptr)
680                                                 {
681                                                         btRigidBody* rbB = btRigidBody::upcast(*colBptr);
682                                                         if (rbB)
683                                                         {
684                                                                 bdyB = rbB;
685                                                         } else
686                                                         {
687                                                                 bdyB = *colBptr;
688                                                         }
689                                                 }
690
691
692                                                 btSoftBody** bodyBptr = m_clusterBodyMap.find(sbjoint->m_bodyB);
693                                                 if (bodyBptr && *bodyBptr )
694                                                 {
695                                                         sbB = *bodyBptr;
696                                                         bdyB = sbB->m_clusters[0];
697                                                 }
698
699
700                                                 if (sbjoint->m_jointType==btSoftBody::Joint::eType::Linear)
701                                                 {
702                                                         btSoftBody::LJoint::Specs specs;
703                                                         specs.cfm = sbjoint->m_cfm;
704                                                         specs.erp = sbjoint->m_erp;
705                                                         specs.split = sbjoint->m_split;
706                                                         btVector3 relA;
707                                                         relA.deSerializeFloat(sbjoint->m_refs[0]);
708                                                         specs.position = transA*relA;
709                                                         sb->appendLinearJoint(specs,sb->m_clusters[0],bdyB);
710                                                 }
711
712                                                 if (sbjoint->m_jointType==btSoftBody::Joint::eType::Angular)
713                                                 {
714                                                         btSoftBody::AJoint::Specs specs;
715                                                         specs.cfm = sbjoint->m_cfm;
716                                                         specs.erp = sbjoint->m_erp;
717                                                         specs.split = sbjoint->m_split;
718                                                         btVector3 relA;
719                                                         relA.deSerializeFloat(sbjoint->m_refs[0]);
720                                                         specs.axis = transA.getBasis()*relA;
721                                                         sb->appendAngularJoint(specs,sb->m_clusters[0],bdyB);
722                                                 }
723                                         }
724                                 }
725
726                         }
727                 }
728
729                 return result;
730
731         }
732 };
733 #endif //DESERIALIZE_SOFT_BODIES
734
735 SerializeDemo::SerializeDemo()
736 :m_verboseMode(0),
737 m_fileName("testFile.bullet")
738 {
739         m_idle=true;
740
741 }
742 SerializeDemo::~SerializeDemo()
743 {
744         m_fileLoader->deleteAllData();
745         delete m_fileLoader;    
746         exitPhysics();
747 }
748
749 void    SerializeDemo::initPhysics()
750 {
751         setTexturing(true);
752         setShadows(false);//true);
753
754         setCameraDistance(btScalar(SCALING*30.));
755
756         setupEmptyDynamicsWorld();
757         
758 #ifdef DESERIALIZE_SOFT_BODIES
759         m_fileLoader = new MySoftBulletWorldImporter((btSoftRigidDynamicsWorld*)m_dynamicsWorld);
760 #else
761         m_fileLoader = new btBulletWorldImporter(m_dynamicsWorld);
762 #endif //DESERIALIZE_SOFT_BODIES
763         
764         m_fileLoader->setVerboseMode(m_verboseMode);
765         
766
767
768         if (!m_fileLoader->loadFile("testFile.bullet"))
769 //      if (!m_fileLoader->loadFile("../SoftDemo/testFile.bullet"))
770         {
771                 ///create a few basic rigid bodies and save them to testFile.bullet
772                 btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));
773         //      btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50);
774                 btCollisionObject* groundObject = 0;
775
776                 
777                 m_collisionShapes.push_back(groundShape);
778
779                 btTransform groundTransform;
780                 groundTransform.setIdentity();
781                 groundTransform.setOrigin(btVector3(0,-50,0));
782
783                 //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
784                 {
785                         btScalar mass(0.);
786
787                         //rigidbody is dynamic if and only if mass is non zero, otherwise static
788                         bool isDynamic = (mass != 0.f);
789
790                         btVector3 localInertia(0,0,0);
791                         if (isDynamic)
792                                 groundShape->calculateLocalInertia(mass,localInertia);
793
794                         //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
795                         btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
796                         btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);
797                         btRigidBody* body = new btRigidBody(rbInfo);
798
799                         //add the body to the dynamics world
800                         m_dynamicsWorld->addRigidBody(body);
801                         groundObject = body;
802                 }
803
804
805                 {
806                         //create a few dynamic rigidbodies
807                         // Re-using the same collision is better for memory usage and performance
808
809                         int numSpheres = 2;
810                         btVector3 positions[2] = {btVector3(0.1f,0.2f,0.3f),btVector3(0.4f,0.5f,0.6f)};
811                         btScalar        radii[2] = {0.3f,0.4f};
812
813                         btMultiSphereShape* colShape = new btMultiSphereShape(positions,radii,numSpheres);
814
815                         //btCollisionShape* colShape = new btCapsuleShapeZ(SCALING*1,SCALING*1);
816                         //btCollisionShape* colShape = new btCylinderShapeZ(btVector3(SCALING*1,SCALING*1,SCALING*1));
817                         //btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1));
818                         //btCollisionShape* colShape = new btSphereShape(btScalar(1.));
819                         m_collisionShapes.push_back(colShape);
820
821                         /// Create Dynamic Objects
822                         btTransform startTransform;
823                         startTransform.setIdentity();
824
825                         btScalar        mass(1.f);
826
827                         //rigidbody is dynamic if and only if mass is non zero, otherwise static
828                         bool isDynamic = (mass != 0.f);
829
830                         btVector3 localInertia(0,0,0);
831                         if (isDynamic)
832                                 colShape->calculateLocalInertia(mass,localInertia);
833
834                         float start_x = START_POS_X - ARRAY_SIZE_X/2;
835                         float start_y = START_POS_Y;
836                         float start_z = START_POS_Z - ARRAY_SIZE_Z/2;
837
838                         for (int k=0;k<ARRAY_SIZE_Y;k++)
839                         {
840                                 for (int i=0;i<ARRAY_SIZE_X;i++)
841                                 {
842                                         for(int j = 0;j<ARRAY_SIZE_Z;j++)
843                                         {
844                                                 startTransform.setOrigin(SCALING*btVector3(
845                                                                                         btScalar(2.0*i + start_x),
846                                                                                         btScalar(20+2.0*k + start_y),
847                                                                                         btScalar(2.0*j + start_z)));
848
849                                 
850                                                 //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
851                                                 btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform);
852                                                 btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia);
853                                                 btRigidBody* body = new btRigidBody(rbInfo);
854                                                 
855                                                 m_dynamicsWorld->addRigidBody(body);
856                                                 //body->setActivationState(ISLAND_SLEEPING);
857                                         }
858                                 }
859                         }
860                 }
861
862                 int maxSerializeBufferSize = 1024*1024*5;
863
864                 btDefaultSerializer*    serializer = new btDefaultSerializer(maxSerializeBufferSize);
865
866                 static const char* groundName = "GroundName";
867                 serializer->registerNameForPointer(groundObject, groundName);
868
869                 for (int i=0;i<m_collisionShapes.size();i++)
870                 {
871                         char* name = new char[20];
872                         
873                         sprintf(name,"name%d",i);
874                         serializer->registerNameForPointer(m_collisionShapes[i],name);
875                 }
876
877                 btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*(btRigidBody*)getDynamicsWorld()->getCollisionObjectArray()[2],btVector3(0,1,0));
878                 m_dynamicsWorld->addConstraint(p2p);
879                 
880                 const char* name = "constraintje";
881                 serializer->registerNameForPointer(p2p,name);
882
883                 m_dynamicsWorld->serialize(serializer);
884 #if 1
885                 FILE* f2 = fopen("testFile.bullet","wb");
886                 fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2);
887                 fclose(f2);
888 #endif
889
890         }
891
892         //clientResetScene();
893
894 }
895         
896
897 void    SerializeDemo::exitPhysics()
898 {
899
900         //cleanup in the reverse order of creation/initialization
901
902         //remove the rigidbodies from the dynamics world and delete them
903         int i;
904         for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
905         {
906                 btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
907                 btRigidBody* body = btRigidBody::upcast(obj);
908                 if (body && body->getMotionState())
909                 {
910                         delete body->getMotionState();
911                 }
912                 m_dynamicsWorld->removeCollisionObject( obj );
913                 delete obj;
914         }
915
916         //delete collision shapes
917         for (int j=0;j<m_collisionShapes.size();j++)
918         {
919                 btCollisionShape* shape = m_collisionShapes[j];
920                 delete shape;
921         }
922
923         m_collisionShapes.clear();
924
925         delete m_dynamicsWorld;
926         
927         delete m_solver;
928         
929         delete m_broadphase;
930         
931         delete m_dispatcher;
932
933         delete m_collisionConfiguration;
934
935         
936 }
937
938
939
940