2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2010 Erwin Coumans http://continuousphysics.com/Bullet/
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:
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.
16 #define TEST_SERIALIZATION 1
17 //#undef DESERIALIZE_SOFT_BODIES
19 #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
20 #define CREATE_NEW_BULLETFILE 1
21 #endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES
23 ///create 125 (5x5x5) dynamic object
24 #define ARRAY_SIZE_X 5
25 #define ARRAY_SIZE_Y 5
26 #define ARRAY_SIZE_Z 5
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)
31 ///scaling of the objects (0.1 = 20 centimeter boxes )
33 #define START_POS_X -5
34 #define START_POS_Y -5
35 #define START_POS_Z -3
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
47 #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h"
48 #include <stdio.h> //printf debugging
52 #ifdef DESERIALIZE_SOFT_BODIES
53 #include "BulletSoftBody/btSoftBodySolvers.h"
57 #include <BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h>
58 #include <BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h>
59 #include "../SharedOpenCL/btOpenCLUtils.h"
61 extern cl_context g_cxMainContext;
62 extern cl_device_id g_cdDevice;
63 extern cl_command_queue g_cqCommandQue;
66 btSoftBodySolver* fSoftBodySolver=0;
68 #include "BulletSoftBody/btSoftBodyHelpers.h"
69 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
70 #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
73 void SerializeDemo::keyboardCallback(unsigned char key, int x, int y)
75 btAlignedObjectArray<btRigidBody*> bodies;
78 int numManifolds = getDynamicsWorld()->getDispatcher()->getNumManifolds();
80 for (int i=0;i<numManifolds;i++)
82 btPersistentManifold* manifold = getDynamicsWorld()->getDispatcher()->getManifoldByIndexInternal(i);
83 if (!manifold->getNumContacts())
86 btScalar minDist = 1e30f;
88 for (int v=0;v<manifold->getNumContacts();v++)
90 if (minDist >manifold->getContactPoint(v).getDistance())
92 minDist = manifold->getContactPoint(v).getDistance();
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);
112 if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject())
114 if (body0->checkCollideWithOverride(body1))
120 btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA;
121 btTransform globalFrame;
122 globalFrame.setIdentity();
123 globalFrame.setOrigin(contactPosWorld);
125 trA = body0->getWorldTransform().inverse()*globalFrame;
126 trB = body1->getWorldTransform().inverse()*globalFrame;
128 btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true);
129 dof6->setOverrideNumSolverIterations(100);
131 dof6->setBreakingImpulseThreshold(35);
133 for (int i=0;i<6;i++)
134 dof6->setLimit(i,0,0);
135 getDynamicsWorld()->addConstraint(dof6,true);
144 for (int i=0;i<bodies.size();i++)
146 getDynamicsWorld()->removeRigidBody(bodies[i]);
147 getDynamicsWorld()->addRigidBody(bodies[i]);
151 PlatformDemoApplication::keyboardCallback(key,x,y);
156 void SerializeDemo::clientMoveAndDisplay()
158 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
160 //simple dynamics world doesn't handle fixed-time-stepping
161 float ms = getDeltaTimeMicroseconds();
163 ///step the simulation
166 m_dynamicsWorld->stepSimulation(ms / 1000000.f);
169 #ifdef DESERIALIZE_SOFT_BODIES
171 fSoftBodySolver->copyBackToSoftBodies();
174 m_dynamicsWorld->debugDrawWorld();
176 #ifdef DESERIALIZE_SOFT_BODIES
177 if (m_dynamicsWorld->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD)
179 //optional but useful: debug drawing
180 btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
182 for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
184 btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
185 if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
187 btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
188 btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
192 #endif //DESERIALIZE_SOFT_BODIES
203 #ifdef USE_AMD_OPENCL
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
208 cl_device_id m_device;
212 CachingCLFuncs (cl_command_queue cqCommandQue, cl_context cxMainContext, cl_device_id device)
213 :CLFunctions(cqCommandQue,cxMainContext),
218 virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros, const char* srcFileNameForCaching)
224 prog = btOpenCLUtils::compileCLProgramFromFile( m_cxMainContext,m_device, &pErrNum,additionalMacros ,srcFileNameForCaching);
227 printf("Using embedded kernel source instead:\n");
228 prog = btOpenCLUtils::compileCLProgramFromString( m_cxMainContext,m_device, kernelSource, &pErrNum,additionalMacros);
231 return btOpenCLUtils::compileCLKernelFromString( m_cxMainContext,m_device, kernelSource, kernelName, &pErrNum, prog,additionalMacros);
238 void SerializeDemo::displayCallback(void) {
240 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
242 if (m_dynamicsWorld->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD)
244 #ifdef DESERIALIZE_SOFT_BODIES
246 //optional but useful: debug drawing
247 btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
249 for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
251 btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
252 if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
254 btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
255 btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
258 #endif //DESERIALIZE_SOFT_BODIES
263 //optional but useful: debug drawing to detect problems
265 m_dynamicsWorld->debugDrawWorld();
273 kSolverAccelerationOpenCL_CPU = 1,
274 kSolverAccelerationOpenCL_GPU = 2,
275 kSolverAccelerationNone = 3
279 void SerializeDemo::setupEmptyDynamicsWorld()
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();
286 m_collisionConfiguration = new btDefaultCollisionConfiguration();
287 #endif //DESERIALIZE_SOFT_BODIES
289 //m_collisionConfiguration->setConvexConvexMultipointIterations();
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);
295 m_broadphase = new btDbvtBroadphase();
298 ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
299 btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;
302 #ifdef DESERIALIZE_SOFT_BODIES
306 #ifdef USE_AMD_OPENCL
308 int solverAccel = kSolverAccelerationOpenCL_GPU;
313 case kSolverAccelerationOpenCL_GPU:
315 btOpenCLSoftBodySolverSIMDAware* softSolv= new btOpenCLSoftBodySolverSIMDAware( g_cqCommandQue, g_cxMainContext );
316 //btOpenCLSoftBodySolver* softSolv= new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext);
317 fSoftBodySolver = softSolv;
319 CLFunctions* funcs = new CachingCLFuncs(g_cqCommandQue, g_cxMainContext,g_cdDevice);
320 softSolv->setCLFunctions(funcs);
325 case kSolverAccelerationOpenCL_CPU:
327 //fSoftBodySolver = new btCPUSoftBodySolver();
330 case kSolverAccelerationNone:
333 fSoftBodySolver = NULL;
339 if ( solverAccel != kSolverAccelerationNone )
345 fSoftBodySolver = NULL;
349 fSoftBodySolver = NULL;
352 btSoftRigidDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver,
353 m_collisionConfiguration, fSoftBodySolver);
354 m_dynamicsWorld = world;
357 //world->setDrawFlags(world->getDrawFlags()^fDrawFlags::Clusters);
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
365 //btGImpactCollisionAlgorithm::registerAlgorithm((btCollisionDispatcher*)m_dynamicsWorld->getDispatcher());
367 m_dynamicsWorld->setGravity(btVector3(0,-10,0));
372 #ifdef DESERIALIZE_SOFT_BODIES
373 #include "BulletSoftBody/btSoftBodyData.h"
374 class MySoftBulletWorldImporter : public btBulletWorldImporter
377 btSoftRigidDynamicsWorld* m_softRigidWorld;
379 btHashMap<btHashPtr,btSoftBody::Material*> m_materialMap;
381 btHashMap<btHashPtr,btSoftBody*> m_clusterBodyMap;
382 btHashMap<btHashPtr,btSoftBody*> m_softBodyMap;
388 MySoftBulletWorldImporter(btSoftRigidDynamicsWorld* world)
389 :btBulletWorldImporter(world),
390 m_softRigidWorld(world)
395 virtual ~MySoftBulletWorldImporter()
400 virtual bool convertAllObjects( bParse::btBulletFile* bulletFile2)
402 bool result = btBulletWorldImporter::convertAllObjects(bulletFile2);
404 //now the soft bodies
405 for (i=0;i<bulletFile2->m_softBodies.size();i++)
407 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
409 btAssert(0); //not yet
410 //btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
413 btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
415 int numNodes = softBodyData->m_numNodes;
418 btSoftBody* psb=new btSoftBody(&m_softRigidWorld->getWorldInfo());
419 m_softBodyMap.insert(softBodyData,psb);
422 for (i=0;i<softBodyData->m_numMaterials;i++)
424 SoftBodyMaterialData* matData = softBodyData->m_materials[i];
425 btSoftBody::Material** matPtr = m_materialMap.find(matData);
426 btSoftBody::Material* mat = 0;
427 if (matPtr&& *matPtr)
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);
444 for (i=0;i<numNodes;i++)
446 SoftBodyNodeData& nodeData = softBodyData->m_nodes[i];
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;
457 btSoftBody::Material** matPtr = m_materialMap.find(nodeData.m_material);
458 if (matPtr && *matPtr)
460 node->m_material = *matPtr;
466 node->m_n.deSerializeFloat(nodeData.m_normal);
467 node->m_q = node->m_x;
468 node->m_v.deSerializeFloat(nodeData.m_velocity);
472 for (i=0;i<softBodyData->m_numLinks;i++)
474 SoftBodyLinkData& linkData = softBodyData->m_links[i];
475 btSoftBody::Material** matPtr = m_materialMap.find(linkData.m_material);
476 if (matPtr && *matPtr)
478 psb->appendLink(linkData.m_nodeIndices[0],linkData.m_nodeIndices[1],*matPtr);
481 psb->appendLink(linkData.m_nodeIndices[0],linkData.m_nodeIndices[1]);
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;
488 for (i=0;i<softBodyData->m_numFaces;i++)
490 SoftBodyFaceData& faceData = softBodyData->m_faces[i];
491 btSoftBody::Material** matPtr = m_materialMap.find(faceData.m_material);
492 if (matPtr && *matPtr)
494 psb->appendFace(faceData.m_nodeIndices[0],faceData.m_nodeIndices[1],faceData.m_nodeIndices[2],*matPtr);
497 psb->appendFace(faceData.m_nodeIndices[0],faceData.m_nodeIndices[1],faceData.m_nodeIndices[2]);
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;
507 for (i=0;i<softBodyData->m_numAnchors;i++)
509 btCollisionObject** colAptr = m_bodyMap.find(softBodyData->m_anchors[i].m_rigidBody);
510 if (colAptr && *colAptr)
512 btRigidBody* body = btRigidBody::upcast(*colAptr);
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);
523 if (softBodyData->m_pose)
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);
530 psb->m_pose.m_pos.resize(softBodyData->m_pose->m_numPositions);
531 for (i=0;i<softBodyData->m_pose->m_numPositions;i++)
533 psb->m_pose.m_pos[i].deSerializeFloat(softBodyData->m_pose->m_positions[i]);
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++)
540 psb->m_pose.m_wgh[i] = softBodyData->m_pose->m_weights[i];
542 psb->m_pose.m_volume = softBodyData->m_pose->m_restVolume;
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;
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;
573 if (softBodyData->m_numClusters)
575 m_clusterBodyMap.insert(softBodyData->m_clusters,psb);
577 psb->m_clusters.resize(softBodyData->m_numClusters);
578 for (i=0;i<softBodyData->m_numClusters;i++)
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]);
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++)
593 psb->m_clusters[i]->m_framerefs[j].deSerializeFloat(softBodyData->m_clusters[i].m_framerefs[j]);
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++)
598 int nodeIndex = softBodyData->m_clusters[i].m_nodeIndices[j];
599 psb->m_clusters[i]->m_nodes[j] = &psb->m_nodes[nodeIndex];
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++)
605 psb->m_clusters[i]->m_masses[j] = softBodyData->m_clusters[i].m_masses[j];
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]);
624 //psb->initializeClusters();
625 //psb->updateClusters();
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);
635 psb->generateClusters(8);
642 psb->updateConstants();
643 m_softRigidWorld->getWorldInfo().m_dispatcher = m_softRigidWorld->getDispatcher();
645 m_softRigidWorld->addSoftBody(psb);
652 //now the soft body joints
653 for (i=0;i<bulletFile2->m_softBodies.size();i++)
655 if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)
657 btAssert(0); //not yet
658 //btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
661 btSoftBodyFloatData* softBodyData = (btSoftBodyFloatData*)bulletFile2->m_softBodies[i];
662 btSoftBody** sbp = m_softBodyMap.find(softBodyData);
665 btSoftBody* sb = *sbp;
666 for (int i=0;i<softBodyData->m_numJoints;i++)
668 btSoftBodyJointData* sbjoint = &softBodyData->m_joints[i];
671 btSoftBody::Body bdyB;
675 transA.setIdentity();
676 transA = sb->m_clusters[0]->m_framexform;
678 btCollisionObject** colBptr = m_bodyMap.find(sbjoint->m_bodyB);
679 if (colBptr && *colBptr)
681 btRigidBody* rbB = btRigidBody::upcast(*colBptr);
692 btSoftBody** bodyBptr = m_clusterBodyMap.find(sbjoint->m_bodyB);
693 if (bodyBptr && *bodyBptr )
696 bdyB = sbB->m_clusters[0];
700 if (sbjoint->m_jointType==btSoftBody::Joint::eType::Linear)
702 btSoftBody::LJoint::Specs specs;
703 specs.cfm = sbjoint->m_cfm;
704 specs.erp = sbjoint->m_erp;
705 specs.split = sbjoint->m_split;
707 relA.deSerializeFloat(sbjoint->m_refs[0]);
708 specs.position = transA*relA;
709 sb->appendLinearJoint(specs,sb->m_clusters[0],bdyB);
712 if (sbjoint->m_jointType==btSoftBody::Joint::eType::Angular)
714 btSoftBody::AJoint::Specs specs;
715 specs.cfm = sbjoint->m_cfm;
716 specs.erp = sbjoint->m_erp;
717 specs.split = sbjoint->m_split;
719 relA.deSerializeFloat(sbjoint->m_refs[0]);
720 specs.axis = transA.getBasis()*relA;
721 sb->appendAngularJoint(specs,sb->m_clusters[0],bdyB);
733 #endif //DESERIALIZE_SOFT_BODIES
735 SerializeDemo::SerializeDemo()
737 m_fileName("testFile.bullet")
742 SerializeDemo::~SerializeDemo()
744 m_fileLoader->deleteAllData();
749 void SerializeDemo::initPhysics()
752 setShadows(false);//true);
754 setCameraDistance(btScalar(SCALING*30.));
756 setupEmptyDynamicsWorld();
758 #ifdef DESERIALIZE_SOFT_BODIES
759 m_fileLoader = new MySoftBulletWorldImporter((btSoftRigidDynamicsWorld*)m_dynamicsWorld);
761 m_fileLoader = new btBulletWorldImporter(m_dynamicsWorld);
762 #endif //DESERIALIZE_SOFT_BODIES
764 m_fileLoader->setVerboseMode(m_verboseMode);
768 if (!m_fileLoader->loadFile("testFile.bullet"))
769 // if (!m_fileLoader->loadFile("../SoftDemo/testFile.bullet"))
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;
777 m_collisionShapes.push_back(groundShape);
779 btTransform groundTransform;
780 groundTransform.setIdentity();
781 groundTransform.setOrigin(btVector3(0,-50,0));
783 //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
787 //rigidbody is dynamic if and only if mass is non zero, otherwise static
788 bool isDynamic = (mass != 0.f);
790 btVector3 localInertia(0,0,0);
792 groundShape->calculateLocalInertia(mass,localInertia);
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);
799 //add the body to the dynamics world
800 m_dynamicsWorld->addRigidBody(body);
806 //create a few dynamic rigidbodies
807 // Re-using the same collision is better for memory usage and performance
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};
813 btMultiSphereShape* colShape = new btMultiSphereShape(positions,radii,numSpheres);
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);
821 /// Create Dynamic Objects
822 btTransform startTransform;
823 startTransform.setIdentity();
827 //rigidbody is dynamic if and only if mass is non zero, otherwise static
828 bool isDynamic = (mass != 0.f);
830 btVector3 localInertia(0,0,0);
832 colShape->calculateLocalInertia(mass,localInertia);
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;
838 for (int k=0;k<ARRAY_SIZE_Y;k++)
840 for (int i=0;i<ARRAY_SIZE_X;i++)
842 for(int j = 0;j<ARRAY_SIZE_Z;j++)
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)));
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);
855 m_dynamicsWorld->addRigidBody(body);
856 //body->setActivationState(ISLAND_SLEEPING);
862 int maxSerializeBufferSize = 1024*1024*5;
864 btDefaultSerializer* serializer = new btDefaultSerializer(maxSerializeBufferSize);
866 static const char* groundName = "GroundName";
867 serializer->registerNameForPointer(groundObject, groundName);
869 for (int i=0;i<m_collisionShapes.size();i++)
871 char* name = new char[20];
873 sprintf(name,"name%d",i);
874 serializer->registerNameForPointer(m_collisionShapes[i],name);
877 btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*(btRigidBody*)getDynamicsWorld()->getCollisionObjectArray()[2],btVector3(0,1,0));
878 m_dynamicsWorld->addConstraint(p2p);
880 const char* name = "constraintje";
881 serializer->registerNameForPointer(p2p,name);
883 m_dynamicsWorld->serialize(serializer);
885 FILE* f2 = fopen("testFile.bullet","wb");
886 fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1,f2);
892 //clientResetScene();
897 void SerializeDemo::exitPhysics()
900 //cleanup in the reverse order of creation/initialization
902 //remove the rigidbodies from the dynamics world and delete them
904 for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)
906 btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
907 btRigidBody* body = btRigidBody::upcast(obj);
908 if (body && body->getMotionState())
910 delete body->getMotionState();
912 m_dynamicsWorld->removeCollisionObject( obj );
916 //delete collision shapes
917 for (int j=0;j<m_collisionShapes.size();j++)
919 btCollisionShape* shape = m_collisionShapes[j];
923 m_collisionShapes.clear();
925 delete m_dynamicsWorld;
933 delete m_collisionConfiguration;