From 7bf65e95f4cad9e42f8ab04dae0fedcdec4143fe Mon Sep 17 00:00:00 2001 From: "erwin.coumans" Date: Fri, 1 Aug 2008 05:15:50 +0000 Subject: [PATCH] add patch for Havok 5.5 to add COLLADA Physics conversion --- Extras/khx2dae/SimpleLoadDemo.patch | 428 ++++++++++++++++++++++++++++ Extras/khx2dae/readme.txt | 2 +- 2 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 Extras/khx2dae/SimpleLoadDemo.patch diff --git a/Extras/khx2dae/SimpleLoadDemo.patch b/Extras/khx2dae/SimpleLoadDemo.patch new file mode 100644 index 000000000..196934826 --- /dev/null +++ b/Extras/khx2dae/SimpleLoadDemo.patch @@ -0,0 +1,428 @@ +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(); + diff --git a/Extras/khx2dae/readme.txt b/Extras/khx2dae/readme.txt index 3a07aace3..569efc13f 100644 --- a/Extras/khx2dae/readme.txt +++ b/Extras/khx2dae/readme.txt @@ -1,6 +1,6 @@ hkx2dae converts Havok HKX files to COLLADA Physics .dae files. So Havok tools can be used with any COLLADA Physics enabled application, such as the Bullet physics engine. -Use the diff in combination with the free Havok 5.5 version to add COLLADA Physics export to the Havok SimpleLoad serialization sample. +Use the patch in combination with the free Havok 5.5 version to add COLLADA Physics export to the Havok SimpleLoad serialization sample (hk550\Demo\Demos\Common\Api\Serialize\SimpleLoad). For precompiled binary and further information, visit: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=12&t=2218