429 lines
15 KiB
Diff
429 lines
15 KiB
Diff
|
Index: SimpleLoadDemo.cpp
|
||
|
===================================================================
|
||
|
--- SimpleLoadDemo.cpp (revision 37)
|
||
|
+++ SimpleLoadDemo.cpp (working copy)
|
||
|
@@ -9,6 +9,9 @@
|
||
|
#include <Demos/demos.h>
|
||
|
#include <Demos/Common/Api/Serialize/SimpleLoad/SimpleLoadDemo.h>
|
||
|
|
||
|
+#include "btBulletDynamicsCommon.h"
|
||
|
+#include "ColladaConverter.h"
|
||
|
+ColladaConverter* converter=0;
|
||
|
|
||
|
// Serialize includes
|
||
|
#include <Common/Base/System/Io/IStream/hkIStream.h>
|
||
|
@@ -20,6 +23,16 @@
|
||
|
#include <Common/Serialize/Util/hkRootLevelContainer.h>
|
||
|
#include <Common/Base/System/Io/FileSystem/hkNativeFileSystem.h>
|
||
|
|
||
|
+#include <Physics/Collide/Shape/Convex/Cylinder/hkpCylinderShape.h>
|
||
|
+#include <Physics/Collide/Shape/Convex/Capsule/hkpCapsuleShape.h>
|
||
|
+#include <Physics/Collide/Shape/Convex/ConvexTranslate/hkpConvexTranslateShape.h>
|
||
|
+
|
||
|
+#include <Physics/Collide/Shape/Convex/ConvexTransform/hkpConvexTransformShape.h>
|
||
|
+#include <Physics/Dynamics/Constraint/Bilateral/LimitedHinge/hkpLimitedHingeConstraintData.h>
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
// 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<hkVector4> 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;i<numChildren;i++)
|
||
|
+ {
|
||
|
+ hkpShapeContainer::ShapeBuffer buffer;
|
||
|
+ const hkpTriangleShape* child = (hkpTriangleShape*)moppShape->getShapeCollection()->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;r<numRigidBodies;r++)
|
||
|
+ {
|
||
|
+ hkpRigidBody* hrb = physSystem->getRigidBodies()[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;c<numConstraints;c++)
|
||
|
+ {
|
||
|
+ hkpConstraintInstance* constraint = physSystem->getConstraints()[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();
|
||
|
|