1 Index: SimpleLoadDemo.cpp
2 ===================================================================
3 --- SimpleLoadDemo.cpp (revision 37)
4 +++ SimpleLoadDemo.cpp (working copy)
6 #include <Demos/demos.h>
\r
7 #include <Demos/Common/Api/Serialize/SimpleLoad/SimpleLoadDemo.h>
\r
9 +#include "btBulletDynamicsCommon.h"
\r
10 +#include "ColladaConverter.h"
\r
11 +ColladaConverter* converter=0;
\r
13 // Serialize includes
\r
14 #include <Common/Base/System/Io/IStream/hkIStream.h>
\r
16 #include <Common/Serialize/Util/hkRootLevelContainer.h>
\r
17 #include <Common/Base/System/Io/FileSystem/hkNativeFileSystem.h>
\r
19 +#include <Physics/Collide/Shape/Convex/Cylinder/hkpCylinderShape.h>
\r
20 +#include <Physics/Collide/Shape/Convex/Capsule/hkpCapsuleShape.h>
\r
21 +#include <Physics/Collide/Shape/Convex/ConvexTranslate/hkpConvexTranslateShape.h>
\r
23 +#include <Physics/Collide/Shape/Convex/ConvexTransform/hkpConvexTransformShape.h>
\r
24 +#include <Physics/Dynamics/Constraint/Bilateral/LimitedHinge/hkpLimitedHingeConstraintData.h>
\r
29 // We can optionally version the packfile contents on load
\r
30 // This requires linking with hkcompat
\r
31 #define SIMPLE_LOAD_WITH_VERSIONING
\r
33 hkStructureLayout::HostLayoutRules.m_emptyBaseClassOptimization? 1 : 0);
\r
36 +btTransform getBulletFromHavokTransform(const hkTransform& trans)
\r
39 + btVector3 bulletStartPos(trans.getTranslation()(0),
\r
40 + trans.getTranslation()(1),
\r
41 + trans.getTranslation()(2));
\r
43 + //todo: check matrix storage
\r
44 + btMatrix3x3 bulletMatrix(
\r
45 + trans.getRotation()(0,0),
\r
46 + trans.getRotation()(0,1),
\r
47 + trans.getRotation()(0,2),
\r
48 + trans.getRotation()(1,0),
\r
49 + trans.getRotation()(1,1),
\r
50 + trans.getRotation()(1,2),
\r
51 + trans.getRotation()(2,0),
\r
52 + trans.getRotation()(2,1),
\r
53 + trans.getRotation()(2,2));
\r
55 + btTransform bulletTrans(bulletMatrix,bulletStartPos);
\r
56 + return bulletTrans;
\r
59 +btCollisionShape* createBulletFromHavokShape(const hkpShape* havokShape)
\r
61 + btCollisionShape* bulletShape = 0;
\r
63 + switch (havokShape->getType())
\r
65 + case HK_SHAPE_SPHERE:
\r
67 + hkpSphereShape* havokSphere = (hkpSphereShape*)havokShape;
\r
68 + bulletShape = new btSphereShape(havokSphere->getRadius());
\r
71 + case HK_SHAPE_CYLINDER:
\r
73 + hkpCylinderShape* havokCylinder = (hkpCylinderShape*)havokShape;
\r
74 + hkVector4 vec = havokCylinder->getVertex(0);
\r
75 + vec.sub4(havokCylinder->getVertex(1));
\r
76 + hkReal len = vec.length3();
\r
77 + hkReal radius = havokCylinder->getRadius();
\r
78 + ///todo: convert cylinder, or create new Bullet shape
\r
79 + btVector3 halfExtents(radius,len,radius);
\r
80 + bulletShape = new btCylinderShape(halfExtents);
\r
83 + case HK_SHAPE_BOX:
\r
85 + hkpBoxShape* havokBox = (hkpBoxShape*)havokShape;
\r
86 + bulletShape = new btBoxShape(btVector3(havokBox->getHalfExtents()(0),havokBox->getHalfExtents()(1),havokBox->getHalfExtents()(2)));
\r
89 + case HK_SHAPE_CAPSULE:
\r
91 + hkpCapsuleShape* havokCapsule = (hkpCapsuleShape*)havokShape;
\r
92 + hkVector4 vec = havokCapsule->getVertex(0);
\r
93 + vec.sub4(havokCapsule->getVertex(1));
\r
94 + hkReal len = vec.length3();
\r
95 + hkReal radius = havokCapsule->getRadius();
\r
96 + ///todo: convert capsule, or create new Bullet shape
\r
97 + bulletShape = new btCapsuleShape(radius,len);
\r
100 + case HK_SHAPE_CONVEX_TRANSFORM:
\r
102 + hkpConvexTransformShape* convexTransform = (hkpConvexTransformShape*)havokShape;
\r
103 + btTransform localTrans = getBulletFromHavokTransform(convexTransform->getTransform());
\r
104 + btCompoundShape* bulletCompound = new btCompoundShape();
\r
105 + bulletCompound->addChildShape(localTrans,createBulletFromHavokShape(convexTransform->getChildShape()));
\r
108 + case HK_SHAPE_CONVEX_TRANSLATE:
\r
110 + hkpConvexTranslateShape* convexTranslate = (hkpConvexTranslateShape*)havokShape;
\r
111 + btTransform localTrans;
\r
112 + localTrans.setIdentity();
\r
113 + localTrans.setOrigin(btVector3(convexTranslate->getTranslation()(0),convexTranslate->getTranslation()(1),convexTranslate->getTranslation()(2)));
\r
114 + btCompoundShape* bulletCompound = new btCompoundShape();
\r
115 + bulletCompound->addChildShape(localTrans,createBulletFromHavokShape(convexTranslate->getChildShape()));
\r
119 + case HK_SHAPE_CONVEX_VERTICES:
\r
121 + hkpConvexVerticesShape* havokConvex = (hkpConvexVerticesShape*)havokShape;
\r
122 + hkArray<hkVector4> vertices;
\r
123 + havokConvex->getOriginalVertices(vertices);
\r
124 + bulletShape = new btConvexHullShape(&vertices[0](0),vertices.getSize(),sizeof(hkVector4));
\r
127 + case HK_SHAPE_MOPP:
\r
129 + hkpMoppBvTreeShape* moppShape = (hkpMoppBvTreeShape*)havokShape;
\r
130 + switch (moppShape->getShapeCollection()->getType())
\r
132 + case HK_SHAPE_TRIANGLE_COLLECTION:
\r
134 + int numChildren = moppShape->getShapeCollection()->getNumChildShapes();
\r
135 + printf("found HK_SHAPE_TRIANGLE_COLLECTION with numChildren=%d\n",numChildren);
\r
140 + btTriangleMesh* meshInterface = new btTriangleMesh();
\r
142 + hkpShapeKey key = moppShape->getShapeCollection()->getFirstKey();
\r
143 + for (int i=0;i<numChildren;i++)
\r
145 + hkpShapeContainer::ShapeBuffer buffer;
\r
146 + const hkpTriangleShape* child = (hkpTriangleShape*)moppShape->getShapeCollection()->getChildShape(key,buffer);
\r
147 + btVector3 vtx0(child->getVertex(0)(0),child->getVertex(0)(1),child->getVertex(0)(2));
\r
148 + btVector3 vtx1(child->getVertex(1)(0),child->getVertex(1)(1),child->getVertex(1)(2));
\r
149 + btVector3 vtx2(child->getVertex(2)(0),child->getVertex(2)(1),child->getVertex(2)(2));
\r
151 + meshInterface->addTriangle(vtx0,vtx1,vtx2);
\r
153 + key = moppShape->getShapeCollection()->getNextKey(key);
\r
155 + bulletShape = new btBvhTriangleMeshShape(meshInterface,true);
\r
161 + printf("Unrecognized MOPP getShapeCollection\n");
\r
169 + //HK_SHAPE_TRIANGLE_COLLECTION
\r
172 + //HK_SHAPE_HEIGHT_FIELD
\r
176 + //For those, create a btCompoundShape
\r
177 + //HK_SHAPE_CONVEX_TRANSFORM
\r
180 + //HK_SHAPE_MULTI_SPHERE
\r
181 + //HK_SHAPE_BV_TREE
\r
188 + printf("unknown shape type=%d\n",havokShape->getType());
\r
192 + return bulletShape;
\r
197 SimpleLoadDemo::SimpleLoadDemo( hkDemoEnvironment* env)
\r
198 : hkDefaultPhysicsDemo(env)
\r
201 setupDefaultCameras( env, from, to, up );
\r
204 - hkString path("Common/Api/Serialize/SimpleLoad");
\r
205 + //hkString path("Common/Api/Serialize/SimpleLoad");
\r
206 + hkString path(".");
\r
208 hkPackfileReader* reader = HK_NULL;
\r
213 case hkPackfileReader::FORMAT_BINARY:
\r
215 - SimpleLoadDemo_getBinaryFileName(fileName);
\r
216 + //SimpleLoadDemo_getBinaryFileName(fileName);
\r
217 + fileName = "inputfile.hkx";
\r
218 reader = new hkBinaryPackfileReader();
\r
221 @@ -141,17 +317,206 @@
223 // Create a world and add the physics systems to it
\r
224 m_world = new hkpWorld( *m_physicsData->getWorldCinfo() );
\r
226 + int MAX_PROXIES = 16384;
\r
227 + btVector3 bulletGravity (m_physicsData->getWorldCinfo()->m_gravity(0),m_physicsData->getWorldCinfo()->m_gravity(1),m_physicsData->getWorldCinfo()->m_gravity(2));
\r
229 + btVector3 worldAabbMin(
\r
230 + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(0),
\r
231 + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(1),
\r
232 + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(2));
\r
233 + btVector3 worldAabbMax(
\r
234 + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(0),
\r
235 + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(1),
\r
236 + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(2));
\r
238 + int bulletNumSolverIterations = m_physicsData->getWorldCinfo()->m_solverIterations;
\r
240 + btBroadphaseInterface* bulletPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,MAX_PROXIES);
\r
241 + btConstraintSolver* bulletSolver = new btSequentialImpulseConstraintSolver();
\r
242 + btDefaultCollisionConfiguration* bulletCollisionConfiguration = new btDefaultCollisionConfiguration();
\r
243 + btCollisionDispatcher* bulletDispatcher = new btCollisionDispatcher(bulletCollisionConfiguration);
\r
244 + btDiscreteDynamicsWorld* bulletWorld = new btDiscreteDynamicsWorld(bulletDispatcher,bulletPairCache,bulletSolver,bulletCollisionConfiguration);
\r
245 + //bulletNumSolverIterations is not exported, but just to show how to use the Bullet API
\r
246 + bulletWorld->getSolverInfo().m_numIterations = bulletNumSolverIterations;
\r
251 // Register all collision agents
\r
252 hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() );
\r
254 + printf("Number of Physics Systems:%d\n",m_physicsData->getPhysicsSystems().getSize());
\r
256 + converter = new ColladaConverter(bulletWorld);
\r
258 // Add all the physics systems to the world
\r
259 for ( int i = 0; i < m_physicsData->getPhysicsSystems().getSize(); ++i )
\r
261 - m_world->addPhysicsSystem( m_physicsData->getPhysicsSystems()[i] );
\r
262 + hkpPhysicsSystem* physSystem = m_physicsData->getPhysicsSystems()[i];
\r
263 + m_world->addPhysicsSystem( physSystem );
\r
264 + int numRigidBodies = physSystem->getRigidBodies().getSize();
\r
265 + printf("Number of Rigid Bodies:%d\n",numRigidBodies);
\r
266 + for (int r=0;r<numRigidBodies;r++)
\r
268 + hkpRigidBody* hrb = physSystem->getRigidBodies()[r];
\r
269 + bool isDynamic = !hrb->isFixedOrKeyframed();
\r
270 + btTransform bulletTrans = getBulletFromHavokTransform(hrb->getCollidable()->getTransform());
\r
272 + const hkpShape* havokShape = hrb->getCollidable()->getShape();
\r
273 + btCollisionShape* bulletShape = createBulletFromHavokShape(havokShape);
\r
277 + btRigidBody* body = converter->createRigidBody(isDynamic,hrb->getMass(),bulletTrans,bulletShape);
\r
278 + hrb->setUserData((hkUlong)body);
\r
282 + int numConstraints = physSystem->getConstraints().getSize();
\r
283 + printf("Number of Constraints:%d\n",numConstraints);
\r
285 + for (int c=0;c<numConstraints;c++)
\r
287 + hkpConstraintInstance* constraint = physSystem->getConstraints()[c];
\r
288 + switch (constraint->getData()->getType())
\r
291 + case hkpConstraintData::CONSTRAINT_TYPE_BALLANDSOCKET:
\r
293 + printf("TODO: create ballsocket constraint\n");
\r
296 + case hkpConstraintData::CONSTRAINT_TYPE_HINGE:
\r
298 + printf("TODO: create hinge constraint\n");
\r
301 + case hkpConstraintData::CONSTRAINT_TYPE_PRISMATIC:
\r
303 + printf("TODO: create prismatic (slider) constraint\n");
\r
306 + case hkpConstraintData::CONSTRAINT_TYPE_GENERIC:
\r
308 + printf("TODO: create generic constraint\n");
\r
311 + case hkpConstraintData::CONSTRAINT_TYPE_LIMITEDHINGE:
\r
313 + hkpLimitedHingeConstraintData* limHingeData = (hkpLimitedHingeConstraintData*)constraint->getData();
\r
315 + hkpConstraintData::ConstraintInfo infoOut;
\r
316 + limHingeData->getConstraintInfo(infoOut);
\r
320 + btTransform localAttachmentFrameRef;
\r
321 + localAttachmentFrameRef.setIdentity();
\r
322 + btTransform localAttachmentFrameOther;
\r
323 + localAttachmentFrameOther.setIdentity();
\r
325 + if (infoOut.m_atoms)
\r
327 + while (infoOut.m_atoms[i].getType() != hkpConstraintAtom::TYPE_INVALID)
\r
329 + switch (infoOut.m_atoms[i].getType())
\r
332 + case hkpConstraintAtom::TYPE_SET_LOCAL_TRANSFORMS:
\r
334 + localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA);
\r
335 + localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB);
\r
339 + case hkpConstraintAtom::TYPE_SET_LOCAL_TRANSLATIONS:
\r
342 + localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA);
\r
343 + localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB);
\r
346 + case hkpConstraintAtom::TYPE_SET_LOCAL_ROTATIONS:
\r
349 + localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA);
\r
350 + localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB);
\r
356 + printf("unhandled constraint atom\n");
\r
366 + bool disableCollisionsBetweenLinkedBodies = true;
\r
367 + btRigidBody* body0 = (btRigidBody*) constraint->getRigidBodyA()->getUserData();
\r
368 + btRigidBody* body1 = (btRigidBody*) constraint->getRigidBodyB()->getUserData();
\r
369 + //if (body0 || body1)
\r
373 + btVector3 linearMinLimits(0,0,0);
\r
374 + btVector3 linMaxLimits(0,0,0);
\r
375 + btVector3 angularMinLimits(1,0,0);
\r
376 + btVector3 angularMaxLimits(-1,0,0);
\r
377 + btTypedConstraint* constraint = converter->createUniversalD6Constraint(body0,body1,localAttachmentFrameRef,localAttachmentFrameOther,linearMinLimits,linMaxLimits,angularMinLimits,angularMaxLimits,disableCollisionsBetweenLinkedBodies);
\r
380 + printf("create limited hinge constraint\n");
\r
383 + printf("unable to create limited hinge constraint\n");
\r
390 + //CONSTRAINT_TYPE_LIMITEDHINGE = 2,
\r
391 + //CONSTRAINT_TYPE_POINTTOPATH = 3,
\r
392 + //CONSTRAINT_TYPE_RAGDOLL = 7,
\r
393 + //CONSTRAINT_TYPE_STIFFSPRING = 8,
\r
394 + //CONSTRAINT_TYPE_WHEEL = 9,
\r
395 + //CONSTRAINT_TYPE_CONTACT = 11,
\r
396 + //CONSTRAINT_TYPE_BREAKABLE = 12,
\r
397 + //CONSTRAINT_TYPE_MALLEABLE = 13,
\r
398 + //CONSTRAINT_TYPE_POINTTOPLANE = 14,
\r
399 + //CONSTRAINT_TYPE_PULLEY = 15,
\r
400 + //CONSTRAINT_TYPE_ROTATIONAL = 16,
\r
401 + //CONSTRAINT_TYPE_HINGE_LIMITS = 18,
\r
402 + //CONSTRAINT_TYPE_RAGDOLL_LIMITS = 19,
\r
403 + //CONSTRAINT_TYPE_CUSTOM = 20,
\r
404 + // Constraint Chains
\r
405 + //BEGIN_CONSTRAINT_CHAIN_TYPES = 100,
\r
406 + //CONSTRAINT_TYPE_STIFF_SPRING_CHAIN = 100,
\r
407 + //CONSTRAINT_TYPE_BALL_SOCKET_CHAIN = 101,
\r
408 + //CONSTRAINT_TYPE_POWERED_CHAIN = 102
\r
411 + printf("Unrecognized constraint type=$d\n",constraint->getData()->getType());
\r
421 + //Export the Bullet dynamics world to COLLADA .dae XML
\r
423 + converter ->save("havokToCollada.dae");
\r
426 // Setup graphics - this creates graphics objects for all rigid bodies and phantoms in the world
\r