Index: SimpleLoadDemo.cpp =================================================================== --- SimpleLoadDemo.cpp (revision 37) +++ SimpleLoadDemo.cpp (working copy) @@ -9,6 +9,9 @@ #include #include +#include "btBulletDynamicsCommon.h" +#include "ColladaConverter.h" +ColladaConverter* converter=0; // Serialize includes #include @@ -20,6 +23,16 @@ #include #include +#include +#include +#include + +#include +#include + + + + // We can optionally version the packfile contents on load // This requires linking with hkcompat #define SIMPLE_LOAD_WITH_VERSIONING @@ -59,7 +72,167 @@ hkStructureLayout::HostLayoutRules.m_emptyBaseClassOptimization? 1 : 0); } +btTransform getBulletFromHavokTransform(const hkTransform& trans) +{ + btVector3 bulletStartPos(trans.getTranslation()(0), + trans.getTranslation()(1), + trans.getTranslation()(2)); + + //todo: check matrix storage + btMatrix3x3 bulletMatrix( + trans.getRotation()(0,0), + trans.getRotation()(0,1), + trans.getRotation()(0,2), + trans.getRotation()(1,0), + trans.getRotation()(1,1), + trans.getRotation()(1,2), + trans.getRotation()(2,0), + trans.getRotation()(2,1), + trans.getRotation()(2,2)); + + btTransform bulletTrans(bulletMatrix,bulletStartPos); + return bulletTrans; +} + +btCollisionShape* createBulletFromHavokShape(const hkpShape* havokShape) +{ + btCollisionShape* bulletShape = 0; + + switch (havokShape->getType()) + { + case HK_SHAPE_SPHERE: + { + hkpSphereShape* havokSphere = (hkpSphereShape*)havokShape; + bulletShape = new btSphereShape(havokSphere->getRadius()); + break; + } + case HK_SHAPE_CYLINDER: + { + hkpCylinderShape* havokCylinder = (hkpCylinderShape*)havokShape; + hkVector4 vec = havokCylinder->getVertex(0); + vec.sub4(havokCylinder->getVertex(1)); + hkReal len = vec.length3(); + hkReal radius = havokCylinder->getRadius(); + ///todo: convert cylinder, or create new Bullet shape + btVector3 halfExtents(radius,len,radius); + bulletShape = new btCylinderShape(halfExtents); + break; + } + case HK_SHAPE_BOX: + { + hkpBoxShape* havokBox = (hkpBoxShape*)havokShape; + bulletShape = new btBoxShape(btVector3(havokBox->getHalfExtents()(0),havokBox->getHalfExtents()(1),havokBox->getHalfExtents()(2))); + break; + } + case HK_SHAPE_CAPSULE: + { + hkpCapsuleShape* havokCapsule = (hkpCapsuleShape*)havokShape; + hkVector4 vec = havokCapsule->getVertex(0); + vec.sub4(havokCapsule->getVertex(1)); + hkReal len = vec.length3(); + hkReal radius = havokCapsule->getRadius(); + ///todo: convert capsule, or create new Bullet shape + bulletShape = new btCapsuleShape(radius,len); + break; + } + case HK_SHAPE_CONVEX_TRANSFORM: + { + hkpConvexTransformShape* convexTransform = (hkpConvexTransformShape*)havokShape; + btTransform localTrans = getBulletFromHavokTransform(convexTransform->getTransform()); + btCompoundShape* bulletCompound = new btCompoundShape(); + bulletCompound->addChildShape(localTrans,createBulletFromHavokShape(convexTransform->getChildShape())); + break; + } + case HK_SHAPE_CONVEX_TRANSLATE: + { + hkpConvexTranslateShape* convexTranslate = (hkpConvexTranslateShape*)havokShape; + btTransform localTrans; + localTrans.setIdentity(); + localTrans.setOrigin(btVector3(convexTranslate->getTranslation()(0),convexTranslate->getTranslation()(1),convexTranslate->getTranslation()(2))); + btCompoundShape* bulletCompound = new btCompoundShape(); + bulletCompound->addChildShape(localTrans,createBulletFromHavokShape(convexTranslate->getChildShape())); + + break; + } + case HK_SHAPE_CONVEX_VERTICES: + { + hkpConvexVerticesShape* havokConvex = (hkpConvexVerticesShape*)havokShape; + hkArray vertices; + havokConvex->getOriginalVertices(vertices); + bulletShape = new btConvexHullShape(&vertices[0](0),vertices.getSize(),sizeof(hkVector4)); + break; + }; + case HK_SHAPE_MOPP: + { + hkpMoppBvTreeShape* moppShape = (hkpMoppBvTreeShape*)havokShape; + switch (moppShape->getShapeCollection()->getType()) + { + case HK_SHAPE_TRIANGLE_COLLECTION: + { + int numChildren = moppShape->getShapeCollection()->getNumChildShapes(); + printf("found HK_SHAPE_TRIANGLE_COLLECTION with numChildren=%d\n",numChildren); + + if (numChildren) + { + + btTriangleMesh* meshInterface = new btTriangleMesh(); + + hkpShapeKey key = moppShape->getShapeCollection()->getFirstKey(); + for (int i=0;igetShapeCollection()->getChildShape(key,buffer); + btVector3 vtx0(child->getVertex(0)(0),child->getVertex(0)(1),child->getVertex(0)(2)); + btVector3 vtx1(child->getVertex(1)(0),child->getVertex(1)(1),child->getVertex(1)(2)); + btVector3 vtx2(child->getVertex(2)(0),child->getVertex(2)(1),child->getVertex(2)(2)); + + meshInterface->addTriangle(vtx0,vtx1,vtx2); + + key = moppShape->getShapeCollection()->getNextKey(key); + } + bulletShape = new btBvhTriangleMeshShape(meshInterface,true); + } + break; + } + default: + { + printf("Unrecognized MOPP getShapeCollection\n"); + } + + } + break; + } + + //HK_SHAPE_MOPP + //HK_SHAPE_TRIANGLE_COLLECTION + + + //HK_SHAPE_HEIGHT_FIELD + //btHeightField + + + //For those, create a btCompoundShape + //HK_SHAPE_CONVEX_TRANSFORM + // + //HK_SHAPE_LIST + //HK_SHAPE_MULTI_SPHERE + //HK_SHAPE_BV_TREE + + + + + default: + { + printf("unknown shape type=%d\n",havokShape->getType()); + } + }; + + return bulletShape; + + +} + SimpleLoadDemo::SimpleLoadDemo( hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { @@ -74,7 +247,9 @@ setupDefaultCameras( env, from, to, up ); } - hkString path("Common/Api/Serialize/SimpleLoad"); + //hkString path("Common/Api/Serialize/SimpleLoad"); + hkString path("."); + hkPackfileReader* reader = HK_NULL; { hkString fileName; @@ -83,7 +258,8 @@ { case hkPackfileReader::FORMAT_BINARY: { - SimpleLoadDemo_getBinaryFileName(fileName); + //SimpleLoadDemo_getBinaryFileName(fileName); + fileName = "inputfile.hkx"; reader = new hkBinaryPackfileReader(); break; } @@ -141,17 +317,206 @@ // Create a world and add the physics systems to it m_world = new hkpWorld( *m_physicsData->getWorldCinfo() ); + + int MAX_PROXIES = 16384; + btVector3 bulletGravity (m_physicsData->getWorldCinfo()->m_gravity(0),m_physicsData->getWorldCinfo()->m_gravity(1),m_physicsData->getWorldCinfo()->m_gravity(2)); + + btVector3 worldAabbMin( + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(0), + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(1), + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_min(2)); + btVector3 worldAabbMax( + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(0), + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(1), + m_physicsData->getWorldCinfo()->m_broadPhaseWorldAabb.m_max(2)); + + int bulletNumSolverIterations = m_physicsData->getWorldCinfo()->m_solverIterations; + + btBroadphaseInterface* bulletPairCache = new btAxisSweep3(worldAabbMin,worldAabbMax,MAX_PROXIES); + btConstraintSolver* bulletSolver = new btSequentialImpulseConstraintSolver(); + btDefaultCollisionConfiguration* bulletCollisionConfiguration = new btDefaultCollisionConfiguration(); + btCollisionDispatcher* bulletDispatcher = new btCollisionDispatcher(bulletCollisionConfiguration); + btDiscreteDynamicsWorld* bulletWorld = new btDiscreteDynamicsWorld(bulletDispatcher,bulletPairCache,bulletSolver,bulletCollisionConfiguration); + //bulletNumSolverIterations is not exported, but just to show how to use the Bullet API + bulletWorld->getSolverInfo().m_numIterations = bulletNumSolverIterations; + + m_world->lock(); // Register all collision agents hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() ); + printf("Number of Physics Systems:%d\n",m_physicsData->getPhysicsSystems().getSize()); + + converter = new ColladaConverter(bulletWorld); + // Add all the physics systems to the world for ( int i = 0; i < m_physicsData->getPhysicsSystems().getSize(); ++i ) { - m_world->addPhysicsSystem( m_physicsData->getPhysicsSystems()[i] ); + hkpPhysicsSystem* physSystem = m_physicsData->getPhysicsSystems()[i]; + m_world->addPhysicsSystem( physSystem ); + int numRigidBodies = physSystem->getRigidBodies().getSize(); + printf("Number of Rigid Bodies:%d\n",numRigidBodies); + for (int r=0;rgetRigidBodies()[r]; + bool isDynamic = !hrb->isFixedOrKeyframed(); + btTransform bulletTrans = getBulletFromHavokTransform(hrb->getCollidable()->getTransform()); + + const hkpShape* havokShape = hrb->getCollidable()->getShape(); + btCollisionShape* bulletShape = createBulletFromHavokShape(havokShape); + + if (bulletShape) + { + btRigidBody* body = converter->createRigidBody(isDynamic,hrb->getMass(),bulletTrans,bulletShape); + hrb->setUserData((hkUlong)body); + } + } + + int numConstraints = physSystem->getConstraints().getSize(); + printf("Number of Constraints:%d\n",numConstraints); + + for (int c=0;cgetConstraints()[c]; + switch (constraint->getData()->getType()) + { + + case hkpConstraintData::CONSTRAINT_TYPE_BALLANDSOCKET: + { + printf("TODO: create ballsocket constraint\n"); + break; + } + case hkpConstraintData::CONSTRAINT_TYPE_HINGE: + { + printf("TODO: create hinge constraint\n"); + break; + } + case hkpConstraintData::CONSTRAINT_TYPE_PRISMATIC: + { + printf("TODO: create prismatic (slider) constraint\n"); + break; + } + case hkpConstraintData::CONSTRAINT_TYPE_GENERIC: + { + printf("TODO: create generic constraint\n"); + break; + } + case hkpConstraintData::CONSTRAINT_TYPE_LIMITEDHINGE: + { + hkpLimitedHingeConstraintData* limHingeData = (hkpLimitedHingeConstraintData*)constraint->getData(); + + hkpConstraintData::ConstraintInfo infoOut; + limHingeData->getConstraintInfo(infoOut); + + int i=0; + + btTransform localAttachmentFrameRef; + localAttachmentFrameRef.setIdentity(); + btTransform localAttachmentFrameOther; + localAttachmentFrameOther.setIdentity(); + + if (infoOut.m_atoms) + { + while (infoOut.m_atoms[i].getType() != hkpConstraintAtom::TYPE_INVALID) + { + switch (infoOut.m_atoms[i].getType()) + { + + case hkpConstraintAtom::TYPE_SET_LOCAL_TRANSFORMS: + { + localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA); + localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB); + + break; + } + case hkpConstraintAtom::TYPE_SET_LOCAL_TRANSLATIONS: + { + //??? + localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA); + localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB); + break; + } + case hkpConstraintAtom::TYPE_SET_LOCAL_ROTATIONS: + { + //??? + localAttachmentFrameRef = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformA); + localAttachmentFrameOther = getBulletFromHavokTransform(limHingeData->m_atoms.m_transforms.m_transformB); + break; + } + + default: + { + printf("unhandled constraint atom\n"); + } + }; + i++; + } + + } + + + + bool disableCollisionsBetweenLinkedBodies = true; + btRigidBody* body0 = (btRigidBody*) constraint->getRigidBodyA()->getUserData(); + btRigidBody* body1 = (btRigidBody*) constraint->getRigidBodyB()->getUserData(); + //if (body0 || body1) + { + + + btVector3 linearMinLimits(0,0,0); + btVector3 linMaxLimits(0,0,0); + btVector3 angularMinLimits(1,0,0); + btVector3 angularMaxLimits(-1,0,0); + btTypedConstraint* constraint = converter->createUniversalD6Constraint(body0,body1,localAttachmentFrameRef,localAttachmentFrameOther,linearMinLimits,linMaxLimits,angularMinLimits,angularMaxLimits,disableCollisionsBetweenLinkedBodies); + if (constraint) + { + printf("create limited hinge constraint\n"); + } else + { + printf("unable to create limited hinge constraint\n"); + } + } + + break; + } + + //CONSTRAINT_TYPE_LIMITEDHINGE = 2, + //CONSTRAINT_TYPE_POINTTOPATH = 3, + //CONSTRAINT_TYPE_RAGDOLL = 7, + //CONSTRAINT_TYPE_STIFFSPRING = 8, + //CONSTRAINT_TYPE_WHEEL = 9, + //CONSTRAINT_TYPE_CONTACT = 11, + //CONSTRAINT_TYPE_BREAKABLE = 12, + //CONSTRAINT_TYPE_MALLEABLE = 13, + //CONSTRAINT_TYPE_POINTTOPLANE = 14, + //CONSTRAINT_TYPE_PULLEY = 15, + //CONSTRAINT_TYPE_ROTATIONAL = 16, + //CONSTRAINT_TYPE_HINGE_LIMITS = 18, + //CONSTRAINT_TYPE_RAGDOLL_LIMITS = 19, + //CONSTRAINT_TYPE_CUSTOM = 20, + // Constraint Chains + //BEGIN_CONSTRAINT_CHAIN_TYPES = 100, + //CONSTRAINT_TYPE_STIFF_SPRING_CHAIN = 100, + //CONSTRAINT_TYPE_BALL_SOCKET_CHAIN = 101, + //CONSTRAINT_TYPE_POWERED_CHAIN = 102 + default: + { + printf("Unrecognized constraint type=$d\n",constraint->getData()->getType()); + } + + }; + } + } + + + //Export the Bullet dynamics world to COLLADA .dae XML + + converter ->save("havokToCollada.dae"); + + // Setup graphics - this creates graphics objects for all rigid bodies and phantoms in the world setupGraphics();