1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-23 13:39:42 +00:00

Whitespace changes only (including new mangle with whitespace changes as well)

This commit is contained in:
Jan-Peter Nilsson 2011-04-03 13:12:12 +02:00
parent c78e61c96f
commit 0f7d59b4fb
15 changed files with 1911 additions and 1866 deletions

File diff suppressed because it is too large Load diff

View file

@ -35,26 +35,26 @@ typedef std::vector<Ogre::Vector3> Vector3Array;
class Convert class Convert
{ {
public: public:
Convert() {}; Convert() {};
~Convert() {}; ~Convert() {};
static btQuaternion toBullet(const Ogre::Quaternion &q) static btQuaternion toBullet(const Ogre::Quaternion &q)
{ {
return btQuaternion(q.x, q.y, q.z, q.w); return btQuaternion(q.x, q.y, q.z, q.w);
} }
static btVector3 toBullet(const Ogre::Vector3 &v) static btVector3 toBullet(const Ogre::Vector3 &v)
{ {
return btVector3(v.x, v.y, v.z); return btVector3(v.x, v.y, v.z);
} }
static Ogre::Quaternion toOgre(const btQuaternion &q) static Ogre::Quaternion toOgre(const btQuaternion &q)
{ {
return Ogre::Quaternion(q.w(), q.x(), q.y(), q.z()); return Ogre::Quaternion(q.w(), q.x(), q.y(), q.z());
} }
static Ogre::Vector3 toOgre(const btVector3 &v) static Ogre::Vector3 toOgre(const btVector3 &v)
{ {
return Ogre::Vector3(v.x(), v.y(), v.z()); return Ogre::Vector3(v.x(), v.y(), v.z());
} }
}; };
//From here on its debug-drawing stuff. ------------------------------------------------------------------ //From here on its debug-drawing stuff. ------------------------------------------------------------------
@ -181,20 +181,20 @@ private:
class DebugDrawer : public btIDebugDraw class DebugDrawer : public btIDebugDraw
{ {
protected: protected:
Ogre::SceneNode *mNode; Ogre::SceneNode *mNode;
btDynamicsWorld *mWorld; btDynamicsWorld *mWorld;
DynamicLines *mLineDrawer; DynamicLines *mLineDrawer;
bool mDebugOn; bool mDebugOn;
public: public:
DebugDrawer(Ogre::SceneNode *node, btDynamicsWorld *world) DebugDrawer(Ogre::SceneNode *node, btDynamicsWorld *world)
: mNode(node), : mNode(node),
mWorld(world), mWorld(world),
mDebugOn(true) mDebugOn(true)
{ {
mLineDrawer = new DynamicLines(Ogre::RenderOperation::OT_LINE_LIST); mLineDrawer = new DynamicLines(Ogre::RenderOperation::OT_LINE_LIST);
mNode->attachObject(mLineDrawer); mNode->attachObject(mLineDrawer);
if (!Ogre::ResourceGroupManager::getSingleton().resourceGroupExists("BtOgre")) if (!Ogre::ResourceGroupManager::getSingleton().resourceGroupExists("BtOgre"))
Ogre::ResourceGroupManager::getSingleton().createResourceGroup("BtOgre"); Ogre::ResourceGroupManager::getSingleton().createResourceGroup("BtOgre");
@ -205,68 +205,68 @@ public:
mat->setSelfIllumination(1,1,1); mat->setSelfIllumination(1,1,1);
} }
mLineDrawer->setMaterial("BtOgre/DebugLines"); mLineDrawer->setMaterial("BtOgre/DebugLines");
} }
~DebugDrawer() ~DebugDrawer()
{ {
Ogre::MaterialManager::getSingleton().remove("BtOgre/DebugLines"); Ogre::MaterialManager::getSingleton().remove("BtOgre/DebugLines");
Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("BtOgre"); Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("BtOgre");
delete mLineDrawer; delete mLineDrawer;
} }
void step() void step()
{ {
if (mDebugOn) if (mDebugOn)
{ {
mWorld->debugDrawWorld(); mWorld->debugDrawWorld();
mLineDrawer->update(); mLineDrawer->update();
mNode->needUpdate(); mNode->needUpdate();
mLineDrawer->clear(); mLineDrawer->clear();
} }
else else
{ {
mLineDrawer->clear(); mLineDrawer->clear();
mLineDrawer->update(); mLineDrawer->update();
mNode->needUpdate(); mNode->needUpdate();
} }
} }
void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)
{ {
mLineDrawer->addPoint(Convert::toOgre(from)); mLineDrawer->addPoint(Convert::toOgre(from));
mLineDrawer->addPoint(Convert::toOgre(to)); mLineDrawer->addPoint(Convert::toOgre(to));
} }
void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)
{ {
mLineDrawer->addPoint(Convert::toOgre(PointOnB)); mLineDrawer->addPoint(Convert::toOgre(PointOnB));
mLineDrawer->addPoint(Convert::toOgre(PointOnB) + (Convert::toOgre(normalOnB) * distance * 20)); mLineDrawer->addPoint(Convert::toOgre(PointOnB) + (Convert::toOgre(normalOnB) * distance * 20));
} }
void reportErrorWarning(const char* warningString) void reportErrorWarning(const char* warningString)
{ {
Ogre::LogManager::getSingleton().logMessage(warningString); Ogre::LogManager::getSingleton().logMessage(warningString);
} }
void draw3dText(const btVector3& location,const char* textString) void draw3dText(const btVector3& location,const char* textString)
{ {
} }
//0 for off, anything else for on. //0 for off, anything else for on.
void setDebugMode(int isOn) void setDebugMode(int isOn)
{ {
mDebugOn = (isOn == 0) ? false : true; mDebugOn = (isOn == 0) ? false : true;
if (!mDebugOn) if (!mDebugOn)
mLineDrawer->clear(); mLineDrawer->clear();
} }
//0 for off, anything else for on. //0 for off, anything else for on.
int getDebugMode() const int getDebugMode() const
{ {
return mDebugOn; return mDebugOn;
} }
}; };

View file

@ -29,49 +29,49 @@ typedef std::pair<unsigned short, Vector3Array*> BoneKeyIndex;
class VertexIndexToShape class VertexIndexToShape
{ {
public: public:
VertexIndexToShape(const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY); VertexIndexToShape(const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
~VertexIndexToShape(); ~VertexIndexToShape();
Ogre::Real getRadius(); Ogre::Real getRadius();
Ogre::Vector3 getSize(); Ogre::Vector3 getSize();
btSphereShape* createSphere(); btSphereShape* createSphere();
btBoxShape* createBox(); btBoxShape* createBox();
btBvhTriangleMeshShape* createTrimesh(); btBvhTriangleMeshShape* createTrimesh();
btCylinderShape* createCylinder(); btCylinderShape* createCylinder();
btConvexHullShape* createConvex(); btConvexHullShape* createConvex();
const Ogre::Vector3* getVertices(); const Ogre::Vector3* getVertices();
unsigned int getVertexCount(); unsigned int getVertexCount();
const unsigned int* getIndices(); const unsigned int* getIndices();
unsigned int getIndexCount(); unsigned int getIndexCount();
protected: protected:
void addStaticVertexData(const Ogre::VertexData *vertex_data); void addStaticVertexData(const Ogre::VertexData *vertex_data);
void addAnimatedVertexData(const Ogre::VertexData *vertex_data, void addAnimatedVertexData(const Ogre::VertexData *vertex_data,
const Ogre::VertexData *blended_data, const Ogre::VertexData *blended_data,
const Ogre::Mesh::IndexMap *indexMap); const Ogre::Mesh::IndexMap *indexMap);
void addIndexData(Ogre::IndexData *data, const unsigned int offset = 0); void addIndexData(Ogre::IndexData *data, const unsigned int offset = 0);
protected: protected:
Ogre::Vector3* mVertexBuffer; Ogre::Vector3* mVertexBuffer;
unsigned int* mIndexBuffer; unsigned int* mIndexBuffer;
unsigned int mVertexCount; unsigned int mVertexCount;
unsigned int mIndexCount; unsigned int mIndexCount;
Ogre::Matrix4 mTransform; Ogre::Matrix4 mTransform;
Ogre::Real mBoundRadius; Ogre::Real mBoundRadius;
Ogre::Vector3 mBounds; Ogre::Vector3 mBounds;
BoneIndex *mBoneIndex; BoneIndex *mBoneIndex;
Ogre::Vector3 mScale; Ogre::Vector3 mScale;
}; };
//For static (non-animated) meshes. //For static (non-animated) meshes.
@ -79,21 +79,21 @@ class StaticMeshToShapeConverter : public VertexIndexToShape
{ {
public: public:
StaticMeshToShapeConverter(Ogre::Renderable *rend, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY); StaticMeshToShapeConverter(Ogre::Renderable *rend, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
StaticMeshToShapeConverter(Ogre::Entity *entity, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY); StaticMeshToShapeConverter(Ogre::Entity *entity, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
StaticMeshToShapeConverter(); StaticMeshToShapeConverter();
~StaticMeshToShapeConverter(); ~StaticMeshToShapeConverter();
void addEntity(Ogre::Entity *entity,const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY); void addEntity(Ogre::Entity *entity,const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
void addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY); void addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
protected: protected:
Ogre::Entity* mEntity; Ogre::Entity* mEntity;
Ogre::SceneNode* mNode; Ogre::SceneNode* mNode;
}; };
//For animated meshes. //For animated meshes.
@ -101,41 +101,40 @@ class AnimatedMeshToShapeConverter : public VertexIndexToShape
{ {
public: public:
AnimatedMeshToShapeConverter(Ogre::Entity *entity, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY); AnimatedMeshToShapeConverter(Ogre::Entity *entity, const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
AnimatedMeshToShapeConverter(); AnimatedMeshToShapeConverter();
~AnimatedMeshToShapeConverter(); ~AnimatedMeshToShapeConverter();
void addEntity(Ogre::Entity *entity,const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY); void addEntity(Ogre::Entity *entity,const Ogre::Matrix4 &transform = Ogre::Matrix4::IDENTITY);
void addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform); void addMesh(const Ogre::MeshPtr &mesh, const Ogre::Matrix4 &transform);
btBoxShape* createAlignedBox(unsigned char bone, btBoxShape* createAlignedBox(unsigned char bone,
const Ogre::Vector3 &bonePosition, const Ogre::Vector3 &bonePosition,
const Ogre::Quaternion &boneOrientation); const Ogre::Quaternion &boneOrientation);
btBoxShape* createOrientedBox(unsigned char bone, btBoxShape* createOrientedBox(unsigned char bone,
const Ogre::Vector3 &bonePosition, const Ogre::Vector3 &bonePosition,
const Ogre::Quaternion &boneOrientation); const Ogre::Quaternion &boneOrientation);
protected: protected:
bool getBoneVertices(unsigned char bone, bool getBoneVertices(unsigned char bone,
unsigned int &vertex_count, unsigned int &vertex_count,
Ogre::Vector3* &vertices, Ogre::Vector3* &vertices,
const Ogre::Vector3 &bonePosition); const Ogre::Vector3 &bonePosition);
bool getOrientedBox(unsigned char bone, bool getOrientedBox(unsigned char bone,
const Ogre::Vector3 &bonePosition, const Ogre::Vector3 &bonePosition,
const Ogre::Quaternion &boneOrientation, const Ogre::Quaternion &boneOrientation,
Ogre::Vector3 &extents, Ogre::Vector3 &extents,
Ogre::Vector3 *axis, Ogre::Vector3 *axis,
Ogre::Vector3 &center); Ogre::Vector3 &center);
Ogre::Entity* mEntity;
Ogre::SceneNode* mNode;
Ogre::Entity* mEntity; Ogre::Vector3 *mTransformedVerticesTemp;
Ogre::SceneNode* mNode; size_t mTransformedVerticesTempSize;
Ogre::Vector3 *mTransformedVerticesTemp;
size_t mTransformedVerticesTempSize;
}; };
} }

View file

@ -128,11 +128,11 @@ class BulletShapeLoader : public Ogre::ManualResourceLoader
public: public:
BulletShapeLoader(){}; BulletShapeLoader(){};
virtual ~BulletShapeLoader() {} virtual ~BulletShapeLoader() {}
virtual void loadResource(Ogre::Resource *resource); virtual void loadResource(Ogre::Resource *resource);
virtual void load(const std::string &name,const std::string &group); virtual void load(const std::string &name,const std::string &group);
}; };
#endif #endif

View file

@ -10,36 +10,36 @@ namespace OEngine {
namespace Physic namespace Physic
{ {
CMotionState::CMotionState(PhysicEngine* eng,std::string name) CMotionState::CMotionState(PhysicEngine* eng,std::string name)
{ {
pEng = eng; pEng = eng;
tr.setIdentity(); tr.setIdentity();
pName = name; pName = name;
}; };
void CMotionState::getWorldTransform(btTransform &worldTrans) const void CMotionState::getWorldTransform(btTransform &worldTrans) const
{ {
worldTrans = tr; worldTrans = tr;
} }
void CMotionState::setWorldTransform(const btTransform &worldTrans) void CMotionState::setWorldTransform(const btTransform &worldTrans)
{ {
tr = worldTrans; tr = worldTrans;
PhysicEvent evt; PhysicEvent evt;
evt.isNPC = isNPC; evt.isNPC = isNPC;
evt.isPC = isPC; evt.isPC = isPC;
evt.newTransform = tr; evt.newTransform = tr;
evt.RigidBodyName = pName; evt.RigidBodyName = pName;
if(isPC) if(isPC)
{ {
pEng->PEventList.push_back(evt); pEng->PEventList.push_back(evt);
} }
else else
{ {
pEng->NPEventList.push_back(evt); pEng->NPEventList.push_back(evt);
} }
} }
}} }}

View file

@ -7,46 +7,46 @@
namespace OEngine { namespace OEngine {
namespace Physic namespace Physic
{ {
class PhysicEngine; class PhysicEngine;
/** /**
*A CMotionState is associated with a single RigidBody. * A CMotionState is associated with a single RigidBody.
*When the RigidBody is moved by bullet, bullet will call the function setWorldTransform. * When the RigidBody is moved by bullet, bullet will call the function setWorldTransform.
*for more info, see the bullet Wiki at btMotionState. * for more info, see the bullet Wiki at btMotionState.
*/ */
class CMotionState:public btMotionState class CMotionState:public btMotionState
{ {
public: public:
CMotionState(PhysicEngine* eng,std::string name); CMotionState(PhysicEngine* eng,std::string name);
/** /**
*Return the position of the RigidBody. * Return the position of the RigidBody.
*/ */
virtual void getWorldTransform(btTransform &worldTrans) const; virtual void getWorldTransform(btTransform &worldTrans) const;
/** /**
*Function called by bullet when the RigidBody is moved. * Function called by bullet when the RigidBody is moved.
*It add an event to the EventList of the PhysicEngine class. * It add an event to the EventList of the PhysicEngine class.
*/ */
virtual void setWorldTransform(const btTransform &worldTrans); virtual void setWorldTransform(const btTransform &worldTrans);
protected: protected:
PhysicEngine* pEng; PhysicEngine* pEng;
btTransform tr; btTransform tr;
bool isNPC; bool isNPC;
bool isPC; bool isPC;
std::string pName; std::string pName;
}; };
struct PhysicEvent struct PhysicEvent
{ {
bool isNPC; bool isNPC;
bool isPC; bool isPC;
btTransform newTransform; btTransform newTransform;
std::string RigidBodyName; std::string RigidBodyName;
}; };
}} }}
#endif #endif

View file

@ -28,109 +28,109 @@ subject to the following restrictions:
class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
{ {
public: public:
btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
{ {
m_me[0] = me; m_me[0] = me;
count = 1; count = 1;
} }
btKinematicClosestNotMeRayResultCallback (btCollisionObject* me[], int count_) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) btKinematicClosestNotMeRayResultCallback (btCollisionObject* me[], int count_) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
{ {
count = count_; count = count_;
for(int i = 0; i < count; i++) for(int i = 0; i < count; i++)
m_me[i] = me[i]; m_me[i] = me[i];
} }
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
{ {
for(int i = 0; i < count; i++) for(int i = 0; i < count; i++)
if (rayResult.m_collisionObject == m_me[i]) if (rayResult.m_collisionObject == m_me[i])
return 1.0; return 1.0;
return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace); return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
} }
protected: protected:
btCollisionObject* m_me[10]; btCollisionObject* m_me[10];
int count; int count;
}; };
class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
{ {
public: public:
btKinematicClosestNotMeConvexResultCallback( btCollisionObject* me, const btVector3& up, btScalar minSlopeDot ) btKinematicClosestNotMeConvexResultCallback( btCollisionObject* me, const btVector3& up, btScalar minSlopeDot )
: btCollisionWorld::ClosestConvexResultCallback( btVector3( 0.0, 0.0, 0.0 ), btVector3( 0.0, 0.0, 0.0 ) ), : btCollisionWorld::ClosestConvexResultCallback( btVector3( 0.0, 0.0, 0.0 ), btVector3( 0.0, 0.0, 0.0 ) ),
m_me( me ), m_up( up ), m_minSlopeDot( minSlopeDot ) m_me( me ), m_up( up ), m_minSlopeDot( minSlopeDot )
{ {
} }
virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
{ {
if( convexResult.m_hitCollisionObject == m_me ) if( convexResult.m_hitCollisionObject == m_me )
return btScalar( 1 ); return btScalar( 1 );
btVector3 hitNormalWorld; btVector3 hitNormalWorld;
if( normalInWorldSpace ) if( normalInWorldSpace )
{ {
hitNormalWorld = convexResult.m_hitNormalLocal; hitNormalWorld = convexResult.m_hitNormalLocal;
} }
else else
{ {
///need to transform normal into worldspace ///need to transform normal into worldspace
hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
} }
// NOTE : m_hitNormalLocal is not always vertical on the ground with a capsule or a box... // NOTE : m_hitNormalLocal is not always vertical on the ground with a capsule or a box...
btScalar dotUp = m_up.dot(hitNormalWorld); btScalar dotUp = m_up.dot(hitNormalWorld);
if( dotUp < m_minSlopeDot ) if( dotUp < m_minSlopeDot )
return btScalar( 1 ); return btScalar( 1 );
return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace); return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
} }
protected: protected:
btCollisionObject* m_me; btCollisionObject* m_me;
const btVector3 m_up; const btVector3 m_up;
btScalar m_minSlopeDot; btScalar m_minSlopeDot;
}; };
btKinematicCharacterController::btKinematicCharacterController( btPairCachingGhostObject* externalGhostObject_, btKinematicCharacterController::btKinematicCharacterController( btPairCachingGhostObject* externalGhostObject_,
btPairCachingGhostObject* internalGhostObject_, btPairCachingGhostObject* internalGhostObject_,
btScalar stepHeight, btScalar stepHeight,
btScalar constantScale, btScalar constantScale,
btScalar gravity, btScalar gravity,
btScalar fallVelocity, btScalar fallVelocity,
btScalar jumpVelocity, btScalar jumpVelocity,
btScalar recoveringFactor ) btScalar recoveringFactor )
{ {
m_upAxis = btKinematicCharacterController::Y_AXIS; m_upAxis = btKinematicCharacterController::Y_AXIS;
m_walkDirection.setValue( btScalar( 0 ), btScalar( 0 ), btScalar( 0 ) ); m_walkDirection.setValue( btScalar( 0 ), btScalar( 0 ), btScalar( 0 ) );
m_useGhostObjectSweepTest = true; m_useGhostObjectSweepTest = true;
externalGhostObject = externalGhostObject_; externalGhostObject = externalGhostObject_;
internalGhostObject = internalGhostObject_; internalGhostObject = internalGhostObject_;
m_recoveringFactor = recoveringFactor; m_recoveringFactor = recoveringFactor;
m_stepHeight = stepHeight; m_stepHeight = stepHeight;
m_useWalkDirection = true; // use walk direction by default, legacy behavior m_useWalkDirection = true; // use walk direction by default, legacy behavior
m_velocityTimeInterval = btScalar( 0 ); m_velocityTimeInterval = btScalar( 0 );
m_verticalVelocity = btScalar( 0 ); m_verticalVelocity = btScalar( 0 );
m_verticalOffset = btScalar( 0 ); m_verticalOffset = btScalar( 0 );
m_gravity = constantScale * gravity; m_gravity = constantScale * gravity;
m_fallSpeed = constantScale * fallVelocity; // Terminal velocity of a sky diver in m/s. m_fallSpeed = constantScale * fallVelocity; // Terminal velocity of a sky diver in m/s.
m_jumpSpeed = constantScale * jumpVelocity; // ? m_jumpSpeed = constantScale * jumpVelocity; // ?
m_wasJumping = false; m_wasJumping = false;
setMaxSlope( btRadians( 45.0 ) ); setMaxSlope( btRadians( 45.0 ) );
mCollision = true; mCollision = true;
} }
@ -147,78 +147,78 @@ void btKinematicCharacterController::setVerticalVelocity(float z)
bool btKinematicCharacterController::recoverFromPenetration( btCollisionWorld* collisionWorld ) bool btKinematicCharacterController::recoverFromPenetration( btCollisionWorld* collisionWorld )
{ {
bool penetration = false; bool penetration = false;
if(!mCollision) return penetration; if(!mCollision) return penetration;
collisionWorld->getDispatcher()->dispatchAllCollisionPairs( internalGhostObject->getOverlappingPairCache(), collisionWorld->getDispatcher()->dispatchAllCollisionPairs( internalGhostObject->getOverlappingPairCache(),
collisionWorld->getDispatchInfo(), collisionWorld->getDispatchInfo(),
collisionWorld->getDispatcher() ); collisionWorld->getDispatcher() );
btVector3 currentPosition = internalGhostObject->getWorldTransform().getOrigin(); btVector3 currentPosition = internalGhostObject->getWorldTransform().getOrigin();
btScalar maxPen = btScalar( 0 ); btScalar maxPen = btScalar( 0 );
for( int i = 0; i < internalGhostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++ ) for( int i = 0; i < internalGhostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++ )
{ {
m_manifoldArray.resize(0); m_manifoldArray.resize(0);
btBroadphasePair* collisionPair = &internalGhostObject->getOverlappingPairCache()->getOverlappingPairArray()[i]; btBroadphasePair* collisionPair = &internalGhostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
if( collisionPair->m_algorithm ) if( collisionPair->m_algorithm )
collisionPair->m_algorithm->getAllContactManifolds( m_manifoldArray ); collisionPair->m_algorithm->getAllContactManifolds( m_manifoldArray );
for( int j = 0; j < m_manifoldArray.size(); j++ ) for( int j = 0; j < m_manifoldArray.size(); j++ )
{ {
btPersistentManifold* manifold = m_manifoldArray[j]; btPersistentManifold* manifold = m_manifoldArray[j];
btScalar directionSign = manifold->getBody0() == internalGhostObject ? btScalar( -1.0 ) : btScalar( 1.0 ); btScalar directionSign = manifold->getBody0() == internalGhostObject ? btScalar( -1.0 ) : btScalar( 1.0 );
for( int p = 0; p < manifold->getNumContacts(); p++ ) for( int p = 0; p < manifold->getNumContacts(); p++ )
{ {
const btManifoldPoint&pt = manifold->getContactPoint( p ); const btManifoldPoint&pt = manifold->getContactPoint( p );
if( (manifold->getBody1() == externalGhostObject && manifold->getBody0() == internalGhostObject) if( (manifold->getBody1() == externalGhostObject && manifold->getBody0() == internalGhostObject)
||(manifold->getBody0() == externalGhostObject && manifold->getBody1() == internalGhostObject) ) ||(manifold->getBody0() == externalGhostObject && manifold->getBody1() == internalGhostObject) )
{ {
} }
else else
{ {
btScalar dist = pt.getDistance(); btScalar dist = pt.getDistance();
if( dist < 0.0 ) if( dist < 0.0 )
{ {
if( dist < maxPen ) if( dist < maxPen )
maxPen = dist; maxPen = dist;
// NOTE : btScalar affects the stairs but the parkinson... // NOTE : btScalar affects the stairs but the parkinson...
// 0.0 , the capsule can break the walls... // 0.0 , the capsule can break the walls...
currentPosition += pt.m_normalWorldOnB * directionSign * dist * m_recoveringFactor; currentPosition += pt.m_normalWorldOnB * directionSign * dist * m_recoveringFactor;
penetration = true; penetration = true;
} }
} }
} }
// ??? // ???
//manifold->clearManifold(); //manifold->clearManifold();
} }
} }
btTransform transform = internalGhostObject->getWorldTransform(); btTransform transform = internalGhostObject->getWorldTransform();
transform.setOrigin( currentPosition ); transform.setOrigin( currentPosition );
internalGhostObject->setWorldTransform( transform ); internalGhostObject->setWorldTransform( transform );
externalGhostObject->setWorldTransform( transform ); externalGhostObject->setWorldTransform( transform );
return penetration; return penetration;
} }
btVector3 btKinematicCharacterController::stepUp( btCollisionWorld* world, const btVector3& currentPosition, btScalar& currentStepOffset ) btVector3 btKinematicCharacterController::stepUp( btCollisionWorld* world, const btVector3& currentPosition, btScalar& currentStepOffset )
{ {
btVector3 targetPosition = currentPosition + getUpAxisDirections()[ m_upAxis ] * ( m_stepHeight + ( m_verticalOffset > btScalar( 0.0 ) ? m_verticalOffset : 0.0 ) ); btVector3 targetPosition = currentPosition + getUpAxisDirections()[ m_upAxis ] * ( m_stepHeight + ( m_verticalOffset > btScalar( 0.0 ) ? m_verticalOffset : 0.0 ) );
//if the no collisions mode is on, no need to go any further //if the no collisions mode is on, no need to go any further
if(!mCollision) if(!mCollision)
@ -227,248 +227,248 @@ btVector3 btKinematicCharacterController::stepUp( btCollisionWorld* world, const
return targetPosition; return targetPosition;
} }
// Retrieve the collision shape // Retrieve the collision shape
// //
btCollisionShape* collisionShape = externalGhostObject->getCollisionShape(); btCollisionShape* collisionShape = externalGhostObject->getCollisionShape();
btAssert( collisionShape->isConvex() ); btAssert( collisionShape->isConvex() );
btConvexShape* convexShape = ( btConvexShape* )collisionShape; btConvexShape* convexShape = ( btConvexShape* )collisionShape;
// FIXME: Handle penetration properly // FIXME: Handle penetration properly
// //
btTransform start; btTransform start;
start.setIdentity(); start.setIdentity();
start.setOrigin( currentPosition + getUpAxisDirections()[ m_upAxis ] * ( convexShape->getMargin() ) ); start.setOrigin( currentPosition + getUpAxisDirections()[ m_upAxis ] * ( convexShape->getMargin() ) );
btTransform end; btTransform end;
end.setIdentity(); end.setIdentity();
end.setOrigin( targetPosition ); end.setOrigin( targetPosition );
btKinematicClosestNotMeConvexResultCallback callback( externalGhostObject, -getUpAxisDirections()[ m_upAxis ], m_maxSlopeCosine ); btKinematicClosestNotMeConvexResultCallback callback( externalGhostObject, -getUpAxisDirections()[ m_upAxis ], m_maxSlopeCosine );
callback.m_collisionFilterGroup = externalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterGroup = externalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = externalGhostObject->getBroadphaseHandle()->m_collisionFilterMask; callback.m_collisionFilterMask = externalGhostObject->getBroadphaseHandle()->m_collisionFilterMask;
// Sweep test // Sweep test
// //
if( m_useGhostObjectSweepTest ) if( m_useGhostObjectSweepTest )
externalGhostObject->convexSweepTest( convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration ); externalGhostObject->convexSweepTest( convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration );
else else
world->convexSweepTest( convexShape, start, end, callback ); world->convexSweepTest( convexShape, start, end, callback );
if( callback.hasHit() ) if( callback.hasHit() )
{ {
// Only modify the position if the hit was a slope and not a wall or ceiling. // Only modify the position if the hit was a slope and not a wall or ceiling.
// //
if( callback.m_hitNormalWorld.dot(getUpAxisDirections()[m_upAxis]) > btScalar( 0.0 ) ) if( callback.m_hitNormalWorld.dot(getUpAxisDirections()[m_upAxis]) > btScalar( 0.0 ) )
{ {
// We moved up only a fraction of the step height // We moved up only a fraction of the step height
// //
currentStepOffset = m_stepHeight * callback.m_closestHitFraction; currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
return currentPosition.lerp( targetPosition, callback.m_closestHitFraction ); return currentPosition.lerp( targetPosition, callback.m_closestHitFraction );
} }
m_verticalVelocity = btScalar( 0.0 ); m_verticalVelocity = btScalar( 0.0 );
m_verticalOffset = btScalar( 0.0 ); m_verticalOffset = btScalar( 0.0 );
return currentPosition; return currentPosition;
} }
else else
{ {
currentStepOffset = m_stepHeight; currentStepOffset = m_stepHeight;
return targetPosition; return targetPosition;
} }
} }
///Reflect the vector d around the vector r ///Reflect the vector d around the vector r
inline btVector3 reflect( const btVector3& d, const btVector3& r ) inline btVector3 reflect( const btVector3& d, const btVector3& r )
{ {
return d - ( btScalar( 2.0 ) * d.dot( r ) ) * r; return d - ( btScalar( 2.0 ) * d.dot( r ) ) * r;
} }
///Project a vector u on another vector v ///Project a vector u on another vector v
inline btVector3 project( const btVector3& u, const btVector3& v ) inline btVector3 project( const btVector3& u, const btVector3& v )
{ {
return v * u.dot( v ); return v * u.dot( v );
} }
///Helper for computing the character sliding ///Helper for computing the character sliding
inline btVector3 slide( const btVector3& direction, const btVector3& planeNormal ) inline btVector3 slide( const btVector3& direction, const btVector3& planeNormal )
{ {
return direction - project( direction, planeNormal ); return direction - project( direction, planeNormal );
} }
btVector3 slideOnCollision( const btVector3& fromPosition, const btVector3& toPosition, const btVector3& hitNormal ) btVector3 slideOnCollision( const btVector3& fromPosition, const btVector3& toPosition, const btVector3& hitNormal )
{ {
btVector3 moveDirection = toPosition - fromPosition; btVector3 moveDirection = toPosition - fromPosition;
btScalar moveLength = moveDirection.length(); btScalar moveLength = moveDirection.length();
if( moveLength <= btScalar( SIMD_EPSILON ) ) if( moveLength <= btScalar( SIMD_EPSILON ) )
return toPosition; return toPosition;
moveDirection.normalize(); moveDirection.normalize();
btVector3 reflectDir = reflect( moveDirection, hitNormal ); btVector3 reflectDir = reflect( moveDirection, hitNormal );
reflectDir.normalize(); reflectDir.normalize();
return fromPosition + slide( reflectDir, hitNormal ) * moveLength; return fromPosition + slide( reflectDir, hitNormal ) * moveLength;
} }
btVector3 btKinematicCharacterController::stepForwardAndStrafe( btCollisionWorld* collisionWorld, const btVector3& currentPosition, const btVector3& walkMove ) btVector3 btKinematicCharacterController::stepForwardAndStrafe( btCollisionWorld* collisionWorld, const btVector3& currentPosition, const btVector3& walkMove )
{ {
// We go to ! // We go to !
// //
btVector3 targetPosition = currentPosition + walkMove; btVector3 targetPosition = currentPosition + walkMove;
//if the no collisions mode is on, no need to go any further //if the no collisions mode is on, no need to go any further
if(!mCollision) return targetPosition; if(!mCollision) return targetPosition;
// Retrieve the collision shape // Retrieve the collision shape
// //
btCollisionShape* collisionShape = externalGhostObject->getCollisionShape(); btCollisionShape* collisionShape = externalGhostObject->getCollisionShape();
btAssert( collisionShape->isConvex() ); btAssert( collisionShape->isConvex() );
btConvexShape* convexShape = ( btConvexShape* )collisionShape; btConvexShape* convexShape = ( btConvexShape* )collisionShape;
btTransform start; btTransform start;
start.setIdentity(); start.setIdentity();
btTransform end; btTransform end;
end.setIdentity(); end.setIdentity();
btScalar fraction = btScalar( 1.0 ); btScalar fraction = btScalar( 1.0 );
// This optimization scheme suffers in the corners. // This optimization scheme suffers in the corners.
// It basically jumps from a wall to another, then fails to find a new // It basically jumps from a wall to another, then fails to find a new
// position (after 4 iterations here) and finally don't move at all. // position (after 4 iterations here) and finally don't move at all.
// //
// The stepping algorithm adds some problems with stairs. It seems // The stepping algorithm adds some problems with stairs. It seems
// the treads create some fake corner using capsules for collisions. // the treads create some fake corner using capsules for collisions.
// //
for( int i = 0; i < 4 && fraction > btScalar( 0.01 ); i++ ) for( int i = 0; i < 4 && fraction > btScalar( 0.01 ); i++ )
{ {
start.setOrigin( currentPosition ); start.setOrigin( currentPosition );
end.setOrigin( targetPosition ); end.setOrigin( targetPosition );
btVector3 sweepDirNegative = currentPosition - targetPosition; btVector3 sweepDirNegative = currentPosition - targetPosition;
btKinematicClosestNotMeConvexResultCallback callback( externalGhostObject, sweepDirNegative, btScalar( 0.0 ) ); btKinematicClosestNotMeConvexResultCallback callback( externalGhostObject, sweepDirNegative, btScalar( 0.0 ) );
callback.m_collisionFilterGroup = externalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterGroup = externalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = externalGhostObject->getBroadphaseHandle()->m_collisionFilterMask; callback.m_collisionFilterMask = externalGhostObject->getBroadphaseHandle()->m_collisionFilterMask;
if( m_useGhostObjectSweepTest ) if( m_useGhostObjectSweepTest )
externalGhostObject->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration ); externalGhostObject->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration );
else else
collisionWorld->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration ); collisionWorld->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration );
if( callback.hasHit() ) if( callback.hasHit() )
{ {
// Try another target position // Try another target position
// //
targetPosition = slideOnCollision( currentPosition, targetPosition, callback.m_hitNormalWorld ); targetPosition = slideOnCollision( currentPosition, targetPosition, callback.m_hitNormalWorld );
fraction = callback.m_closestHitFraction; fraction = callback.m_closestHitFraction;
} }
else else
// Move to the valid target position // Move to the valid target position
// //
return targetPosition; return targetPosition;
} }
// Don't move if you can't find a valid target position... // Don't move if you can't find a valid target position...
// It prevents some flickering. // It prevents some flickering.
// //
return currentPosition; return currentPosition;
} }
///Handle the gravity ///Handle the gravity
btScalar btKinematicCharacterController::addFallOffset( bool wasOnGround, btScalar currentStepOffset, btScalar dt ) btScalar btKinematicCharacterController::addFallOffset( bool wasOnGround, btScalar currentStepOffset, btScalar dt )
{ {
btScalar downVelocity = ( m_verticalVelocity < 0.0 ? -m_verticalVelocity : btScalar( 0.0 ) ) * dt; btScalar downVelocity = ( m_verticalVelocity < 0.0 ? -m_verticalVelocity : btScalar( 0.0 ) ) * dt;
if( downVelocity > btScalar( 0.0 ) && downVelocity < m_stepHeight && ( wasOnGround || !m_wasJumping ) ) if( downVelocity > btScalar( 0.0 ) && downVelocity < m_stepHeight && ( wasOnGround || !m_wasJumping ) )
downVelocity = m_stepHeight; downVelocity = m_stepHeight;
return currentStepOffset + downVelocity; return currentStepOffset + downVelocity;
} }
btVector3 btKinematicCharacterController::stepDown( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar currentStepOffset ) btVector3 btKinematicCharacterController::stepDown( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar currentStepOffset )
{ {
btVector3 stepDrop = getUpAxisDirections()[ m_upAxis ] * currentStepOffset; btVector3 stepDrop = getUpAxisDirections()[ m_upAxis ] * currentStepOffset;
// Be sure we are falling from the last m_currentPosition // Be sure we are falling from the last m_currentPosition
// It prevents some flickering // It prevents some flickering
// //
btVector3 targetPosition = currentPosition - stepDrop; btVector3 targetPosition = currentPosition - stepDrop;
//if the no collisions mode is on, no need to go any further //if the no collisions mode is on, no need to go any further
if(!mCollision) return targetPosition; if(!mCollision) return targetPosition;
btTransform start; btTransform start;
start.setIdentity(); start.setIdentity();
start.setOrigin( currentPosition ); start.setOrigin( currentPosition );
btTransform end; btTransform end;
end.setIdentity(); end.setIdentity();
end.setOrigin( targetPosition ); end.setOrigin( targetPosition );
btKinematicClosestNotMeConvexResultCallback callback( internalGhostObject, getUpAxisDirections()[ m_upAxis ], m_maxSlopeCosine ); btKinematicClosestNotMeConvexResultCallback callback( internalGhostObject, getUpAxisDirections()[ m_upAxis ], m_maxSlopeCosine );
callback.m_collisionFilterGroup = internalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterGroup = internalGhostObject->getBroadphaseHandle()->m_collisionFilterGroup;
callback.m_collisionFilterMask = internalGhostObject->getBroadphaseHandle()->m_collisionFilterMask; callback.m_collisionFilterMask = internalGhostObject->getBroadphaseHandle()->m_collisionFilterMask;
// Retrieve the collision shape // Retrieve the collision shape
// //
btCollisionShape* collisionShape = internalGhostObject->getCollisionShape(); btCollisionShape* collisionShape = internalGhostObject->getCollisionShape();
btAssert( collisionShape->isConvex() ); btAssert( collisionShape->isConvex() );
btConvexShape* convexShape = ( btConvexShape* )collisionShape; btConvexShape* convexShape = ( btConvexShape* )collisionShape;
if( m_useGhostObjectSweepTest ) if( m_useGhostObjectSweepTest )
externalGhostObject->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration ); externalGhostObject->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration );
else else
collisionWorld->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration ); collisionWorld->convexSweepTest( convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration );
if( callback.hasHit() ) if( callback.hasHit() )
{ {
m_verticalVelocity = btScalar( 0.0 ); m_verticalVelocity = btScalar( 0.0 );
m_verticalOffset = btScalar( 0.0 ); m_verticalOffset = btScalar( 0.0 );
m_wasJumping = false; m_wasJumping = false;
// We dropped a fraction of the height -> hit floor // We dropped a fraction of the height -> hit floor
// //
return currentPosition.lerp( targetPosition, callback.m_closestHitFraction ); return currentPosition.lerp( targetPosition, callback.m_closestHitFraction );
} }
else else
// We dropped the full height // We dropped the full height
// //
return targetPosition; return targetPosition;
} }
void btKinematicCharacterController::setWalkDirection( const btVector3& walkDirection ) void btKinematicCharacterController::setWalkDirection( const btVector3& walkDirection )
{ {
m_useWalkDirection = true; m_useWalkDirection = true;
m_walkDirection = walkDirection; m_walkDirection = walkDirection;
} }
void btKinematicCharacterController::setVelocityForTimeInterval( const btVector3& velocity, btScalar timeInterval ) void btKinematicCharacterController::setVelocityForTimeInterval( const btVector3& velocity, btScalar timeInterval )
{ {
m_useWalkDirection = false; m_useWalkDirection = false;
m_walkDirection = velocity; m_walkDirection = velocity;
m_velocityTimeInterval = timeInterval; m_velocityTimeInterval = timeInterval;
} }
@ -479,162 +479,162 @@ void btKinematicCharacterController::reset()
void btKinematicCharacterController::warp( const btVector3& origin ) void btKinematicCharacterController::warp( const btVector3& origin )
{ {
btTransform transform; btTransform transform;
transform.setIdentity(); transform.setIdentity();
transform.setOrigin( -origin ); transform.setOrigin( -origin );
externalGhostObject->setWorldTransform( transform ); externalGhostObject->setWorldTransform( transform );
internalGhostObject->setWorldTransform( transform ); internalGhostObject->setWorldTransform( transform );
} }
void btKinematicCharacterController::preStep( btCollisionWorld* collisionWorld ) void btKinematicCharacterController::preStep( btCollisionWorld* collisionWorld )
{ {
BT_PROFILE( "preStep" ); BT_PROFILE( "preStep" );
for( int i = 0; i < 4 && recoverFromPenetration ( collisionWorld ); i++ ); for( int i = 0; i < 4 && recoverFromPenetration ( collisionWorld ); i++ );
} }
void btKinematicCharacterController::playerStep( btCollisionWorld* collisionWorld, btScalar dt ) void btKinematicCharacterController::playerStep( btCollisionWorld* collisionWorld, btScalar dt )
{ {
BT_PROFILE( "playerStep" ); BT_PROFILE( "playerStep" );
if( !m_useWalkDirection && m_velocityTimeInterval <= btScalar( 0.0 ) ) if( !m_useWalkDirection && m_velocityTimeInterval <= btScalar( 0.0 ) )
return; return;
bool wasOnGround = onGround(); bool wasOnGround = onGround();
// Handle the gravity // Handle the gravity
// //
m_verticalVelocity -= m_gravity * dt; m_verticalVelocity -= m_gravity * dt;
if( m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed ) if( m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed )
m_verticalVelocity = m_jumpSpeed; m_verticalVelocity = m_jumpSpeed;
if( m_verticalVelocity < 0.0 && btFabs( m_verticalVelocity ) > btFabs( m_fallSpeed ) ) if( m_verticalVelocity < 0.0 && btFabs( m_verticalVelocity ) > btFabs( m_fallSpeed ) )
m_verticalVelocity = -btFabs( m_fallSpeed ); m_verticalVelocity = -btFabs( m_fallSpeed );
m_verticalOffset = m_verticalVelocity * dt; m_verticalOffset = m_verticalVelocity * dt;
// This forced stepping up can cause problems when the character // This forced stepping up can cause problems when the character
// walks (jump in fact...) under too low ceilings. // walks (jump in fact...) under too low ceilings.
// //
btVector3 currentPosition = externalGhostObject->getWorldTransform().getOrigin(); btVector3 currentPosition = externalGhostObject->getWorldTransform().getOrigin();
btScalar currentStepOffset; btScalar currentStepOffset;
currentPosition = stepUp( collisionWorld, currentPosition, currentStepOffset ); currentPosition = stepUp( collisionWorld, currentPosition, currentStepOffset );
// Move in the air and slide against the walls ignoring the stair steps. // Move in the air and slide against the walls ignoring the stair steps.
// //
if( m_useWalkDirection ) if( m_useWalkDirection )
currentPosition = stepForwardAndStrafe( collisionWorld, currentPosition, m_walkDirection ); currentPosition = stepForwardAndStrafe( collisionWorld, currentPosition, m_walkDirection );
else else
{ {
btScalar dtMoving = ( dt < m_velocityTimeInterval ) ? dt : m_velocityTimeInterval; btScalar dtMoving = ( dt < m_velocityTimeInterval ) ? dt : m_velocityTimeInterval;
m_velocityTimeInterval -= dt; m_velocityTimeInterval -= dt;
// How far will we move while we are moving ? // How far will we move while we are moving ?
// //
btVector3 moveDirection = m_walkDirection * dtMoving; btVector3 moveDirection = m_walkDirection * dtMoving;
currentPosition = stepForwardAndStrafe( collisionWorld, currentPosition, moveDirection ); currentPosition = stepForwardAndStrafe( collisionWorld, currentPosition, moveDirection );
} }
// Finally find the ground. // Finally find the ground.
// //
currentStepOffset = addFallOffset( wasOnGround, currentStepOffset, dt ); currentStepOffset = addFallOffset( wasOnGround, currentStepOffset, dt );
currentPosition = stepDown( collisionWorld, currentPosition, currentStepOffset ); currentPosition = stepDown( collisionWorld, currentPosition, currentStepOffset );
// Apply the new position to the collision objects. // Apply the new position to the collision objects.
// //
btTransform tranform; btTransform tranform;
tranform = externalGhostObject->getWorldTransform(); tranform = externalGhostObject->getWorldTransform();
tranform.setOrigin( currentPosition ); tranform.setOrigin( currentPosition );
externalGhostObject->setWorldTransform( tranform ); externalGhostObject->setWorldTransform( tranform );
internalGhostObject->setWorldTransform( tranform ); internalGhostObject->setWorldTransform( tranform );
} }
void btKinematicCharacterController::setFallSpeed( btScalar fallSpeed ) void btKinematicCharacterController::setFallSpeed( btScalar fallSpeed )
{ {
m_fallSpeed = fallSpeed; m_fallSpeed = fallSpeed;
} }
void btKinematicCharacterController::setJumpSpeed( btScalar jumpSpeed ) void btKinematicCharacterController::setJumpSpeed( btScalar jumpSpeed )
{ {
m_jumpSpeed = jumpSpeed; m_jumpSpeed = jumpSpeed;
} }
void btKinematicCharacterController::setMaxJumpHeight( btScalar maxJumpHeight ) void btKinematicCharacterController::setMaxJumpHeight( btScalar maxJumpHeight )
{ {
m_maxJumpHeight = maxJumpHeight; m_maxJumpHeight = maxJumpHeight;
} }
bool btKinematicCharacterController::canJump() const bool btKinematicCharacterController::canJump() const
{ {
return onGround(); return onGround();
} }
void btKinematicCharacterController::jump() void btKinematicCharacterController::jump()
{ {
if( !canJump() ) if( !canJump() )
return; return;
m_verticalVelocity = m_jumpSpeed; m_verticalVelocity = m_jumpSpeed;
m_wasJumping = true; m_wasJumping = true;
} }
void btKinematicCharacterController::setGravity( btScalar gravity ) void btKinematicCharacterController::setGravity( btScalar gravity )
{ {
m_gravity = gravity; m_gravity = gravity;
} }
btScalar btKinematicCharacterController::getGravity() const btScalar btKinematicCharacterController::getGravity() const
{ {
return m_gravity; return m_gravity;
} }
void btKinematicCharacterController::setMaxSlope( btScalar slopeRadians ) void btKinematicCharacterController::setMaxSlope( btScalar slopeRadians )
{ {
m_maxSlopeRadians = slopeRadians; m_maxSlopeRadians = slopeRadians;
m_maxSlopeCosine = btCos( slopeRadians ); m_maxSlopeCosine = btCos( slopeRadians );
} }
btScalar btKinematicCharacterController::getMaxSlope() const btScalar btKinematicCharacterController::getMaxSlope() const
{ {
return m_maxSlopeRadians; return m_maxSlopeRadians;
} }
bool btKinematicCharacterController::onGround() const bool btKinematicCharacterController::onGround() const
{ {
return btFabs( m_verticalVelocity ) < btScalar( SIMD_EPSILON ) && return btFabs( m_verticalVelocity ) < btScalar( SIMD_EPSILON ) &&
btFabs( m_verticalOffset ) < btScalar( SIMD_EPSILON ); btFabs( m_verticalOffset ) < btScalar( SIMD_EPSILON );
} }
btVector3* btKinematicCharacterController::getUpAxisDirections() btVector3* btKinematicCharacterController::getUpAxisDirections()
{ {
static btVector3 sUpAxisDirection[] = static btVector3 sUpAxisDirection[] =
{ {
btVector3( btScalar( 0.0 ), btScalar( 0.0 ), btScalar( 0.0 ) ), btVector3( btScalar( 0.0 ), btScalar( 0.0 ), btScalar( 0.0 ) ),
btVector3( btScalar( 0.0 ), btScalar( 1.0 ), btScalar( 0.0 ) ), btVector3( btScalar( 0.0 ), btScalar( 1.0 ), btScalar( 0.0 ) ),
btVector3( btScalar( 0.0 ), btScalar( 0.0 ), btScalar( 1.0 ) ) btVector3( btScalar( 0.0 ), btScalar( 0.0 ), btScalar( 1.0 ) )
}; };
return sUpAxisDirection; return sUpAxisDirection;
} }

View file

@ -44,41 +44,41 @@ public:
}; };
private: private:
btPairCachingGhostObject* externalGhostObject; // use this for querying collisions for sliding and move btPairCachingGhostObject* externalGhostObject; // use this for querying collisions for sliding and move
btPairCachingGhostObject* internalGhostObject; // and this for recoreving from penetrations btPairCachingGhostObject* internalGhostObject; // and this for recoreving from penetrations
btScalar m_verticalVelocity; btScalar m_verticalVelocity;
btScalar m_verticalOffset; btScalar m_verticalOffset;
btScalar m_fallSpeed; btScalar m_fallSpeed;
btScalar m_jumpSpeed; btScalar m_jumpSpeed;
btScalar m_maxJumpHeight; btScalar m_maxJumpHeight;
btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value) btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value)
btScalar m_maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization) btScalar m_maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization)
btScalar m_gravity; btScalar m_gravity;
btScalar m_recoveringFactor; btScalar m_recoveringFactor;
btScalar m_stepHeight; btScalar m_stepHeight;
///this is the desired walk direction, set by the user ///this is the desired walk direction, set by the user
btVector3 m_walkDirection; btVector3 m_walkDirection;
///keep track of the contact manifolds ///keep track of the contact manifolds
btManifoldArray m_manifoldArray; btManifoldArray m_manifoldArray;
///Gravity attributes ///Gravity attributes
bool m_wasJumping; bool m_wasJumping;
bool m_useGhostObjectSweepTest; bool m_useGhostObjectSweepTest;
bool m_useWalkDirection; bool m_useWalkDirection;
btScalar m_velocityTimeInterval; btScalar m_velocityTimeInterval;
UpAxis m_upAxis; UpAxis m_upAxis;
static btVector3* getUpAxisDirections(); static btVector3* getUpAxisDirections();
bool recoverFromPenetration ( btCollisionWorld* collisionWorld ); bool recoverFromPenetration ( btCollisionWorld* collisionWorld );
btVector3 stepUp( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar& currentStepOffset ); btVector3 stepUp( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar& currentStepOffset );
btVector3 stepForwardAndStrafe( btCollisionWorld* collisionWorld, const btVector3& currentPosition, const btVector3& walkMove ); btVector3 stepForwardAndStrafe( btCollisionWorld* collisionWorld, const btVector3& currentPosition, const btVector3& walkMove );
btScalar addFallOffset( bool wasJumping, btScalar currentStepOffset, btScalar dt ); btScalar addFallOffset( bool wasJumping, btScalar currentStepOffset, btScalar dt );
btVector3 stepDown( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar currentStepOffset ); btVector3 stepDown( btCollisionWorld* collisionWorld, const btVector3& currentPosition, btScalar currentStepOffset );
@ -90,7 +90,7 @@ public:
/// Using a smaller internalGhostObject can help for removing some flickering but create some /// Using a smaller internalGhostObject can help for removing some flickering but create some
/// stopping artefacts when sliding along stairs or small walls. /// stopping artefacts when sliding along stairs or small walls.
/// Don't forget to scale gravity and fallSpeed if you scale the world. /// Don't forget to scale gravity and fallSpeed if you scale the world.
btKinematicCharacterController( btPairCachingGhostObject* externalGhostObject, btKinematicCharacterController( btPairCachingGhostObject* externalGhostObject,
btPairCachingGhostObject* internalGhostObject, btPairCachingGhostObject* internalGhostObject,
btScalar stepHeight, btScalar stepHeight,
btScalar constantScale = btScalar( 1.0 ), btScalar constantScale = btScalar( 1.0 ),
@ -99,67 +99,67 @@ public:
btScalar jumpVelocity = btScalar( 9.8 ), btScalar jumpVelocity = btScalar( 9.8 ),
btScalar recoveringFactor = btScalar( 0.2 ) ); btScalar recoveringFactor = btScalar( 0.2 ) );
~btKinematicCharacterController (); ~btKinematicCharacterController ();
void setVerticalVelocity(float z); void setVerticalVelocity(float z);
///btActionInterface interface ///btActionInterface interface
virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTime ) virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTime )
{ {
preStep( collisionWorld ); preStep( collisionWorld );
playerStep( collisionWorld, deltaTime ); playerStep( collisionWorld, deltaTime );
} }
///btActionInterface interface ///btActionInterface interface
void debugDraw( btIDebugDraw* debugDrawer ); void debugDraw( btIDebugDraw* debugDrawer );
void setUpAxis( UpAxis axis ) void setUpAxis( UpAxis axis )
{ {
m_upAxis = axis; m_upAxis = axis;
} }
/// This should probably be called setPositionIncrementPerSimulatorStep. /// This should probably be called setPositionIncrementPerSimulatorStep.
/// This is neither a direction nor a velocity, but the amount to /// This is neither a direction nor a velocity, but the amount to
/// increment the position each simulation iteration, regardless /// increment the position each simulation iteration, regardless
/// of dt. /// of dt.
/// This call will reset any velocity set by setVelocityForTimeInterval(). /// This call will reset any velocity set by setVelocityForTimeInterval().
virtual void setWalkDirection(const btVector3& walkDirection); virtual void setWalkDirection(const btVector3& walkDirection);
/// Caller provides a velocity with which the character should move for /// Caller provides a velocity with which the character should move for
/// the given time period. After the time period, velocity is reset /// the given time period. After the time period, velocity is reset
/// to zero. /// to zero.
/// This call will reset any walk direction set by setWalkDirection(). /// This call will reset any walk direction set by setWalkDirection().
/// Negative time intervals will result in no motion. /// Negative time intervals will result in no motion.
virtual void setVelocityForTimeInterval(const btVector3& velocity, virtual void setVelocityForTimeInterval(const btVector3& velocity,
btScalar timeInterval); btScalar timeInterval);
void reset(); void reset();
void warp( const btVector3& origin ); void warp( const btVector3& origin );
void preStep( btCollisionWorld* collisionWorld ); void preStep( btCollisionWorld* collisionWorld );
void playerStep( btCollisionWorld* collisionWorld, btScalar dt ); void playerStep( btCollisionWorld* collisionWorld, btScalar dt );
void setFallSpeed( btScalar fallSpeed ); void setFallSpeed( btScalar fallSpeed );
void setJumpSpeed( btScalar jumpSpeed ); void setJumpSpeed( btScalar jumpSpeed );
void setMaxJumpHeight( btScalar maxJumpHeight ); void setMaxJumpHeight( btScalar maxJumpHeight );
bool canJump() const; bool canJump() const;
void jump(); void jump();
void setGravity( btScalar gravity ); void setGravity( btScalar gravity );
btScalar getGravity() const; btScalar getGravity() const;
/// The max slope determines the maximum angle that the controller can walk up. /// The max slope determines the maximum angle that the controller can walk up.
/// The slope angle is measured in radians. /// The slope angle is measured in radians.
void setMaxSlope( btScalar slopeRadians ); void setMaxSlope( btScalar slopeRadians );
btScalar getMaxSlope() const; btScalar getMaxSlope() const;
void setUseGhostSweepTest( bool useGhostObjectSweepTest ) void setUseGhostSweepTest( bool useGhostObjectSweepTest )
{ {
m_useGhostObjectSweepTest = useGhostObjectSweepTest; m_useGhostObjectSweepTest = useGhostObjectSweepTest;
} }
bool onGround() const; bool onGround() const;
//if set to false, there will be no collision. //if set to false, there will be no collision.
bool mCollision; bool mCollision;

View file

@ -15,63 +15,63 @@
namespace OEngine { namespace OEngine {
namespace Physic namespace Physic
{ {
enum collisiontypes { enum collisiontypes {
COL_NOTHING = 0, //<Collide with nothing COL_NOTHING = 0, //<Collide with nothing
COL_WORLD = BIT(0), //<Collide with world objects COL_WORLD = BIT(0), //<Collide with world objects
COL_ACTOR_INTERNAL = BIT(1), //<Collide internal capsule COL_ACTOR_INTERNAL = BIT(1), //<Collide internal capsule
COL_ACTOR_EXTERNAL = BIT(2) //<collide with external capsule COL_ACTOR_EXTERNAL = BIT(2) //<collide with external capsule
}; };
PhysicActor::PhysicActor(std::string name) PhysicActor::PhysicActor(std::string name)
{ {
mName = name; mName = name;
// The capsule is at the origin // The capsule is at the origin
btTransform transform; btTransform transform;
transform.setIdentity(); transform.setIdentity();
// External capsule // External capsule
externalGhostObject = new PairCachingGhostObject(name); externalGhostObject = new PairCachingGhostObject(name);
externalGhostObject->setWorldTransform( transform ); externalGhostObject->setWorldTransform( transform );
btScalar externalCapsuleHeight = 130; btScalar externalCapsuleHeight = 130;
btScalar externalCapsuleWidth = 16; btScalar externalCapsuleWidth = 16;
externalCollisionShape = new btCapsuleShapeZ( externalCapsuleWidth, externalCapsuleHeight ); externalCollisionShape = new btCapsuleShapeZ( externalCapsuleWidth, externalCapsuleHeight );
externalCollisionShape->setMargin( 0.1 ); externalCollisionShape->setMargin( 0.1 );
externalGhostObject->setCollisionShape( externalCollisionShape ); externalGhostObject->setCollisionShape( externalCollisionShape );
externalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT ); externalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT );
// Internal capsule // Internal capsule
internalGhostObject = new PairCachingGhostObject(name); internalGhostObject = new PairCachingGhostObject(name);
internalGhostObject->setWorldTransform( transform ); internalGhostObject->setWorldTransform( transform );
//internalGhostObject->getBroadphaseHandle()->s //internalGhostObject->getBroadphaseHandle()->s
btScalar internalCapsuleHeight = 120; btScalar internalCapsuleHeight = 120;
btScalar internalCapsuleWidth = 15; btScalar internalCapsuleWidth = 15;
internalCollisionShape = new btCapsuleShapeZ( internalCapsuleWidth, internalCapsuleHeight ); internalCollisionShape = new btCapsuleShapeZ( internalCapsuleWidth, internalCapsuleHeight );
internalCollisionShape->setMargin( 0.1 ); internalCollisionShape->setMargin( 0.1 );
internalGhostObject->setCollisionShape( internalCollisionShape ); internalGhostObject->setCollisionShape( internalCollisionShape );
internalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT ); internalGhostObject->setCollisionFlags( btCollisionObject::CF_CHARACTER_OBJECT );
mCharacter = new btKinematicCharacterController( externalGhostObject,internalGhostObject,btScalar( 40 ),1,4,20,9.8,0.2 ); mCharacter = new btKinematicCharacterController( externalGhostObject,internalGhostObject,btScalar( 40 ),1,4,20,9.8,0.2 );
mCharacter->setUpAxis(btKinematicCharacterController::Z_AXIS); mCharacter->setUpAxis(btKinematicCharacterController::Z_AXIS);
mCharacter->setUseGhostSweepTest(false); mCharacter->setUseGhostSweepTest(false);
mCharacter->mCollision = false; mCharacter->mCollision = false;
setGravity(0); setGravity(0);
} }
PhysicActor::~PhysicActor() PhysicActor::~PhysicActor()
{ {
delete mCharacter; delete mCharacter;
delete internalGhostObject; delete internalGhostObject;
delete internalCollisionShape; delete internalCollisionShape;
delete externalGhostObject; delete externalGhostObject;
delete externalCollisionShape; delete externalCollisionShape;
} }
void PhysicActor::setGravity(float gravity) void PhysicActor::setGravity(float gravity)
{ {
@ -94,100 +94,100 @@ namespace Physic
return mCharacter->mCollision; return mCharacter->mCollision;
} }
void PhysicActor::setWalkDirection(const btVector3& mvt) void PhysicActor::setWalkDirection(const btVector3& mvt)
{ {
mCharacter->setWalkDirection( mvt ); mCharacter->setWalkDirection( mvt );
} }
void PhysicActor::Rotate(const btQuaternion& quat) void PhysicActor::Rotate(const btQuaternion& quat)
{ {
externalGhostObject->getWorldTransform().setRotation( externalGhostObject->getWorldTransform().getRotation() * quat ); externalGhostObject->getWorldTransform().setRotation( externalGhostObject->getWorldTransform().getRotation() * quat );
internalGhostObject->getWorldTransform().setRotation( internalGhostObject->getWorldTransform().getRotation() * quat ); internalGhostObject->getWorldTransform().setRotation( internalGhostObject->getWorldTransform().getRotation() * quat );
} }
void PhysicActor::setRotation(const btQuaternion& quat) void PhysicActor::setRotation(const btQuaternion& quat)
{ {
externalGhostObject->getWorldTransform().setRotation( quat ); externalGhostObject->getWorldTransform().setRotation( quat );
internalGhostObject->getWorldTransform().setRotation( quat ); internalGhostObject->getWorldTransform().setRotation( quat );
} }
btVector3 PhysicActor::getPosition(void) btVector3 PhysicActor::getPosition(void)
{ {
return internalGhostObject->getWorldTransform().getOrigin(); return internalGhostObject->getWorldTransform().getOrigin();
} }
btQuaternion PhysicActor::getRotation(void) btQuaternion PhysicActor::getRotation(void)
{ {
return internalGhostObject->getWorldTransform().getRotation(); return internalGhostObject->getWorldTransform().getRotation();
} }
void PhysicActor::setPosition(const btVector3& pos) void PhysicActor::setPosition(const btVector3& pos)
{ {
internalGhostObject->getWorldTransform().setOrigin(pos); internalGhostObject->getWorldTransform().setOrigin(pos);
externalGhostObject->getWorldTransform().setOrigin(pos); externalGhostObject->getWorldTransform().setOrigin(pos);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
RigidBody::RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name) RigidBody::RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name)
:btRigidBody(CI),mName(name) :btRigidBody(CI),mName(name)
{ {
}; };
/////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////
PhysicEngine::PhysicEngine(BulletShapeLoader* shapeLoader) PhysicEngine::PhysicEngine(BulletShapeLoader* shapeLoader)
{ {
// Set up the collision configuration and dispatcher // Set up the collision configuration and dispatcher
collisionConfiguration = new btDefaultCollisionConfiguration(); collisionConfiguration = new btDefaultCollisionConfiguration();
dispatcher = new btCollisionDispatcher(collisionConfiguration); dispatcher = new btCollisionDispatcher(collisionConfiguration);
// The actual physics solver // The actual physics solver
solver = new btSequentialImpulseConstraintSolver; solver = new btSequentialImpulseConstraintSolver;
//TODO: memory leak? //TODO: memory leak?
btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache(); btOverlappingPairCache* pairCache = new btSortedOverlappingPairCache();
pairCache->setInternalGhostPairCallback( new btGhostPairCallback() ); pairCache->setInternalGhostPairCallback( new btGhostPairCallback() );
broadphase = new btDbvtBroadphase(pairCache); broadphase = new btDbvtBroadphase(pairCache);
// The world. // The world.
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration); dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0,0,-10)); dynamicsWorld->setGravity(btVector3(0,0,-10));
if(BulletShapeManager::getSingletonPtr() == NULL) if(BulletShapeManager::getSingletonPtr() == NULL)
{ {
new BulletShapeManager(); new BulletShapeManager();
} }
//TODO:singleton? //TODO:singleton?
mShapeLoader = shapeLoader; mShapeLoader = shapeLoader;
isDebugCreated = false; isDebugCreated = false;
} }
void PhysicEngine::createDebugRendering() void PhysicEngine::createDebugRendering()
{ {
if(!isDebugCreated) if(!isDebugCreated)
{ {
Ogre::SceneManagerEnumerator::SceneManagerIterator iter = Ogre::Root::getSingleton().getSceneManagerIterator(); Ogre::SceneManagerEnumerator::SceneManagerIterator iter = Ogre::Root::getSingleton().getSceneManagerIterator();
iter.begin(); iter.begin();
Ogre::SceneManager* scn = iter.getNext(); Ogre::SceneManager* scn = iter.getNext();
Ogre::SceneNode* node = scn->getRootSceneNode()->createChildSceneNode(); Ogre::SceneNode* node = scn->getRootSceneNode()->createChildSceneNode();
node->pitch(Ogre::Degree(-90)); node->pitch(Ogre::Degree(-90));
mDebugDrawer = new BtOgre::DebugDrawer(node, dynamicsWorld); mDebugDrawer = new BtOgre::DebugDrawer(node, dynamicsWorld);
dynamicsWorld->setDebugDrawer(mDebugDrawer); dynamicsWorld->setDebugDrawer(mDebugDrawer);
isDebugCreated = true; isDebugCreated = true;
dynamicsWorld->debugDrawWorld(); dynamicsWorld->debugDrawWorld();
} }
} }
void PhysicEngine::setDebugRenderingMode(int mode) void PhysicEngine::setDebugRenderingMode(int mode)
{ {
@ -198,69 +198,69 @@ namespace Physic
mDebugDrawer->setDebugMode(mode); mDebugDrawer->setDebugMode(mode);
} }
PhysicEngine::~PhysicEngine() PhysicEngine::~PhysicEngine()
{ {
delete dynamicsWorld; delete dynamicsWorld;
delete solver; delete solver;
delete collisionConfiguration; delete collisionConfiguration;
delete dispatcher; delete dispatcher;
delete broadphase; delete broadphase;
delete mShapeLoader; delete mShapeLoader;
} }
RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name) RigidBody* PhysicEngine::createRigidBody(std::string mesh,std::string name)
{ {
//get the shape from the .nif //get the shape from the .nif
mShapeLoader->load(mesh,"General"); mShapeLoader->load(mesh,"General");
BulletShapeManager::getSingletonPtr()->load(mesh,"General"); BulletShapeManager::getSingletonPtr()->load(mesh,"General");
BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(mesh,"General"); BulletShapePtr shape = BulletShapeManager::getSingleton().getByName(mesh,"General");
//create the motionState //create the motionState
CMotionState* newMotionState = new CMotionState(this,name); CMotionState* newMotionState = new CMotionState(this,name);
//create the real body //create the real body
btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape); btRigidBody::btRigidBodyConstructionInfo CI = btRigidBody::btRigidBodyConstructionInfo(0,newMotionState,shape->Shape);
RigidBody* body = new RigidBody(CI,name); RigidBody* body = new RigidBody(CI,name);
body->collide = shape->collide; body->collide = shape->collide;
return body; return body;
} }
void PhysicEngine::addRigidBody(RigidBody* body) void PhysicEngine::addRigidBody(RigidBody* body)
{ {
if(body->collide) if(body->collide)
{ {
dynamicsWorld->addRigidBody(body,COL_WORLD,COL_WORLD|COL_ACTOR_INTERNAL|COL_ACTOR_EXTERNAL); dynamicsWorld->addRigidBody(body,COL_WORLD,COL_WORLD|COL_ACTOR_INTERNAL|COL_ACTOR_EXTERNAL);
} }
else else
{ {
dynamicsWorld->addRigidBody(body,COL_WORLD,COL_NOTHING); dynamicsWorld->addRigidBody(body,COL_WORLD,COL_NOTHING);
} }
body->setActivationState(DISABLE_DEACTIVATION); body->setActivationState(DISABLE_DEACTIVATION);
RigidBodyMap[body->mName] = body; RigidBodyMap[body->mName] = body;
} }
void PhysicEngine::removeRigidBody(std::string name) void PhysicEngine::removeRigidBody(std::string name)
{ {
std::map<std::string,RigidBody*>::iterator it = RigidBodyMap.find(name); std::map<std::string,RigidBody*>::iterator it = RigidBodyMap.find(name);
if (it != RigidBodyMap.end() ) if (it != RigidBodyMap.end() )
{ {
RigidBody* body = it->second; RigidBody* body = it->second;
if(body != NULL) if(body != NULL)
{ {
// broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher); // broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher);
/*std::map<std::string,PhysicActor*>::iterator it2 = PhysicActorMap.begin(); /*std::map<std::string,PhysicActor*>::iterator it2 = PhysicActorMap.begin();
for(;it2!=PhysicActorMap.end();it++) for(;it2!=PhysicActorMap.end();it++)
{ {
it2->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher); it2->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher);
it2->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher); it2->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(body->getBroadphaseProxy(),dispatcher);
}*/ }*/
dynamicsWorld->removeRigidBody(RigidBodyMap[name]); dynamicsWorld->removeRigidBody(RigidBodyMap[name]);
} }
} }
} }
void PhysicEngine::deleteRigidBody(std::string name) void PhysicEngine::deleteRigidBody(std::string name)
{ {
std::map<std::string,RigidBody*>::iterator it = RigidBodyMap.find(name); std::map<std::string,RigidBody*>::iterator it = RigidBodyMap.find(name);
if (it != RigidBodyMap.end() ) if (it != RigidBodyMap.end() )
{ {
@ -271,34 +271,34 @@ namespace Physic
} }
RigidBodyMap.erase(it); RigidBodyMap.erase(it);
} }
} }
RigidBody* PhysicEngine::getRigidBody(std::string name) RigidBody* PhysicEngine::getRigidBody(std::string name)
{ {
RigidBody* body = RigidBodyMap[name]; RigidBody* body = RigidBodyMap[name];
return body; return body;
} }
void PhysicEngine::stepSimulation(double deltaT) void PhysicEngine::stepSimulation(double deltaT)
{ {
dynamicsWorld->stepSimulation(deltaT,1,1/50.); dynamicsWorld->stepSimulation(deltaT,1,1/50.);
if(isDebugCreated) if(isDebugCreated)
{ {
mDebugDrawer->step(); mDebugDrawer->step();
} }
} }
void PhysicEngine::addCharacter(std::string name) void PhysicEngine::addCharacter(std::string name)
{ {
PhysicActor* newActor = new PhysicActor(name); PhysicActor* newActor = new PhysicActor(name);
dynamicsWorld->addCollisionObject( newActor->externalGhostObject, COL_ACTOR_EXTERNAL, COL_WORLD |COL_ACTOR_EXTERNAL ); dynamicsWorld->addCollisionObject( newActor->externalGhostObject, COL_ACTOR_EXTERNAL, COL_WORLD |COL_ACTOR_EXTERNAL );
dynamicsWorld->addCollisionObject( newActor->internalGhostObject, COL_ACTOR_INTERNAL, COL_WORLD |COL_ACTOR_INTERNAL ); dynamicsWorld->addCollisionObject( newActor->internalGhostObject, COL_ACTOR_INTERNAL, COL_WORLD |COL_ACTOR_INTERNAL );
dynamicsWorld->addAction( newActor->mCharacter ); dynamicsWorld->addAction( newActor->mCharacter );
PhysicActorMap[name] = newActor; PhysicActorMap[name] = newActor;
} }
void PhysicEngine::removeCharacter(std::string name) void PhysicEngine::removeCharacter(std::string name)
{ {
//std::cout << "remove"; //std::cout << "remove";
std::map<std::string,PhysicActor*>::iterator it = PhysicActorMap.find(name); std::map<std::string,PhysicActor*>::iterator it = PhysicActorMap.find(name);
if (it != PhysicActorMap.end() ) if (it != PhysicActorMap.end() )
@ -307,15 +307,15 @@ namespace Physic
if(act != NULL) if(act != NULL)
{ {
/*broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher); /*broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher); broadphase->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
std::map<std::string,PhysicActor*>::iterator it2 = PhysicActorMap.begin(); std::map<std::string,PhysicActor*>::iterator it2 = PhysicActorMap.begin();
for(;it2!=PhysicActorMap.end();it++) for(;it2!=PhysicActorMap.end();it++)
{ {
it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher); it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher); it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->externalGhostObject->getBroadphaseHandle(),dispatcher);
it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher); it->second->internalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher); it->second->externalGhostObject->getOverlappingPairCache()->removeOverlappingPairsContainingProxy(act->internalGhostObject->getBroadphaseHandle(),dispatcher);
}*/ }*/
//act->externalGhostObject-> //act->externalGhostObject->
dynamicsWorld->removeCollisionObject(act->externalGhostObject); dynamicsWorld->removeCollisionObject(act->externalGhostObject);
dynamicsWorld->removeCollisionObject(act->internalGhostObject); dynamicsWorld->removeCollisionObject(act->internalGhostObject);
@ -325,17 +325,17 @@ namespace Physic
PhysicActorMap.erase(it); PhysicActorMap.erase(it);
} }
//std::cout << "ok"; //std::cout << "ok";
} }
PhysicActor* PhysicEngine::getCharacter(std::string name) PhysicActor* PhysicEngine::getCharacter(std::string name)
{ {
PhysicActor* act = PhysicActorMap[name]; PhysicActor* act = PhysicActorMap[name];
return act; return act;
} }
void PhysicEngine::emptyEventLists(void) void PhysicEngine::emptyEventLists(void)
{ {
} }
std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to) std::pair<std::string,float> PhysicEngine::rayTest(btVector3& from,btVector3& to)
{ {

View file

@ -18,19 +18,19 @@ class btKinematicCharacterController;
namespace BtOgre namespace BtOgre
{ {
class DebugDrawer; class DebugDrawer;
} }
namespace MWWorld namespace MWWorld
{ {
class World; class World;
} }
namespace OEngine { namespace OEngine {
namespace Physic namespace Physic
{ {
class CMotionState; class CMotionState;
struct PhysicEvent; struct PhysicEvent;
/** /**
*This is just used to be able to name objects. *This is just used to be able to name objects.
@ -45,26 +45,26 @@ namespace Physic
std::string mName; std::string mName;
}; };
/** /**
*A physic Actor use a modifed KinematicCharacterController taken in the bullet forum. * A physic Actor use a modifed KinematicCharacterController taken in the bullet forum.
*/ */
class PhysicActor class PhysicActor
{ {
public: public:
PhysicActor(std::string name); PhysicActor(std::string name);
~PhysicActor(); ~PhysicActor();
/** /**
*This function set the walkDirection. This is not relative to the actor orientation. * This function set the walkDirection. This is not relative to the actor orientation.
*I think it's also needed to take time into account. A typical call should look like this: * I think it's also needed to take time into account. A typical call should look like this:
*setWalkDirection( mvt * orientation * dt) * setWalkDirection( mvt * orientation * dt)
*/ */
void setWalkDirection(const btVector3& mvt); void setWalkDirection(const btVector3& mvt);
void Rotate(const btQuaternion& quat); void Rotate(const btQuaternion& quat);
void setRotation(const btQuaternion& quat); void setRotation(const btQuaternion& quat);
void setGravity(float gravity); void setGravity(float gravity);
@ -74,150 +74,150 @@ namespace Physic
bool getCollisionMode(); bool getCollisionMode();
btVector3 getPosition(void); btVector3 getPosition(void);
btQuaternion getRotation(void); btQuaternion getRotation(void);
void setPosition(const btVector3& pos); void setPosition(const btVector3& pos);
btKinematicCharacterController* mCharacter; btKinematicCharacterController* mCharacter;
PairCachingGhostObject* internalGhostObject; PairCachingGhostObject* internalGhostObject;
btCollisionShape* internalCollisionShape; btCollisionShape* internalCollisionShape;
PairCachingGhostObject* externalGhostObject; PairCachingGhostObject* externalGhostObject;
btCollisionShape* externalCollisionShape; btCollisionShape* externalCollisionShape;
std::string mName; std::string mName;
}; };
/** /**
*This class is just an extension of normal btRigidBody in order to add extra info. *This class is just an extension of normal btRigidBody in order to add extra info.
*When bullet give back a btRigidBody, you can just do a static_cast to RigidBody, *When bullet give back a btRigidBody, you can just do a static_cast to RigidBody,
*so one never should use btRigidBody directly! *so one never should use btRigidBody directly!
*/ */
class RigidBody: public btRigidBody class RigidBody: public btRigidBody
{ {
public: public:
RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name); RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name);
std::string mName; std::string mName;
//is this body used for raycasting only? //is this body used for raycasting only?
bool collide; bool collide;
}; };
/** /**
*The PhysicEngine class contain everything which is needed for Physic. * The PhysicEngine class contain everything which is needed for Physic.
*It's needed that Ogre Resources are set up before the PhysicEngine is created. * It's needed that Ogre Resources are set up before the PhysicEngine is created.
*Note:deleting it WILL NOT delete the RigidBody! * Note:deleting it WILL NOT delete the RigidBody!
*TODO:unload unused resources? * TODO:unload unused resources?
*/ */
class PhysicEngine class PhysicEngine
{ {
public: public:
/** /**
*Note that the shapeLoader IS destroyed by the phyic Engine!! * Note that the shapeLoader IS destroyed by the phyic Engine!!
*/ */
PhysicEngine(BulletShapeLoader* shapeLoader); PhysicEngine(BulletShapeLoader* shapeLoader);
/** /**
*It DOES destroy the shape loader! * It DOES destroy the shape loader!
*/ */
~PhysicEngine(); ~PhysicEngine();
/**
*create a RigidBody.It does not add it to the simulation, but it does add it to the rigidBody Map,
*so you can get it with the getRigidBody function.
*/
RigidBody* createRigidBody(std::string mesh,std::string name);
/**
*Add a RigidBody to the simulation
*/
void addRigidBody(RigidBody* body);
/**
*Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap.
*/
void removeRigidBody(std::string name);
/**
*delete a RigidBody, and remove it from RigidBodyMap.
*/
void deleteRigidBody(std::string name);
/**
*Return a pointer to a given rigid body.
*TODO:check if exist
*/
RigidBody* getRigidBody(std::string name);
/**
*Create and add a character to the scene, and add it to the ActorMap.
*/
void addCharacter(std::string name);
/**
*Remove a character from the scene. TODO:delete it! for now, a small memory leak^^ done?
*/
void removeCharacter(std::string name);
/**
*return a pointer to a character
*TODO:check if the actor exist...
*/
PhysicActor* getCharacter(std::string name);
/**
*This step the simulation of a given time.
*/
void stepSimulation(double deltaT);
/**
*Empty events lists
*/
void emptyEventLists(void);
/**
*Create a debug rendering. It is called by setDebgRenderingMode if it's not created yet.
*Important Note: this will crash if the Render is not yet initialise!
*/
void createDebugRendering();
/**
*Set the debug rendering mode. 0 to turn it off.
*Important Note: this will crash if the Render is not yet initialise!
*/
void setDebugRenderingMode(int mode);
/** /**
*Return the closest object hit by a ray. If there are no objects, it will return ("",-1). * Create a RigidBody.It does not add it to the simulation, but it does add it to the rigidBody Map,
*/ * so you can get it with the getRigidBody function.
*/
RigidBody* createRigidBody(std::string mesh,std::string name);
/**
* Add a RigidBody to the simulation
*/
void addRigidBody(RigidBody* body);
/**
* Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap.
*/
void removeRigidBody(std::string name);
/**
* Delete a RigidBody, and remove it from RigidBodyMap.
*/
void deleteRigidBody(std::string name);
/**
* Return a pointer to a given rigid body.
* TODO:check if exist
*/
RigidBody* getRigidBody(std::string name);
/**
* Create and add a character to the scene, and add it to the ActorMap.
*/
void addCharacter(std::string name);
/**
* Remove a character from the scene. TODO:delete it! for now, a small memory leak^^ done?
*/
void removeCharacter(std::string name);
/**
* Return a pointer to a character
* TODO:check if the actor exist...
*/
PhysicActor* getCharacter(std::string name);
/**
* This step the simulation of a given time.
*/
void stepSimulation(double deltaT);
/**
* Empty events lists
*/
void emptyEventLists(void);
/**
* Create a debug rendering. It is called by setDebgRenderingMode if it's not created yet.
* Important Note: this will crash if the Render is not yet initialise!
*/
void createDebugRendering();
/**
* Set the debug rendering mode. 0 to turn it off.
* Important Note: this will crash if the Render is not yet initialise!
*/
void setDebugRenderingMode(int mode);
/**
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
*/
std::pair<std::string,float> rayTest(btVector3& from,btVector3& to); std::pair<std::string,float> rayTest(btVector3& from,btVector3& to);
//event list of non player object //event list of non player object
std::list<PhysicEvent> NPEventList; std::list<PhysicEvent> NPEventList;
//event list affecting the player //event list affecting the player
std::list<PhysicEvent> PEventList; std::list<PhysicEvent> PEventList;
//Bullet Stuff //Bullet Stuff
btBroadphaseInterface* broadphase; btBroadphaseInterface* broadphase;
btDefaultCollisionConfiguration* collisionConfiguration; btDefaultCollisionConfiguration* collisionConfiguration;
btSequentialImpulseConstraintSolver* solver; btSequentialImpulseConstraintSolver* solver;
btCollisionDispatcher* dispatcher; btCollisionDispatcher* dispatcher;
btDiscreteDynamicsWorld* dynamicsWorld; btDiscreteDynamicsWorld* dynamicsWorld;
//the NIF file loader. //the NIF file loader.
BulletShapeLoader* mShapeLoader; BulletShapeLoader* mShapeLoader;
std::map<std::string,RigidBody*> RigidBodyMap; std::map<std::string,RigidBody*> RigidBodyMap;
std::map<std::string,PhysicActor*> PhysicActorMap; std::map<std::string,PhysicActor*> PhysicActorMap;
//debug rendering //debug rendering
BtOgre::DebugDrawer* mDebugDrawer; BtOgre::DebugDrawer* mDebugDrawer;
bool isDebugCreated; bool isDebugCreated;
}; };
}} }}

2
mangle

@ -1 +1 @@
Subproject commit a05046026ec9edb1e528fac2c70f887239302237 Subproject commit f3c9694bf249a34eae05f0304e6bfc120014ce8c

View file

@ -10,48 +10,48 @@ using namespace OEngine::Render;
void MouseLookEvent::event(Type type, int index, const void *p) void MouseLookEvent::event(Type type, int index, const void *p)
{ {
if(type != EV_MouseMove || camera == NULL) return; if(type != EV_MouseMove || camera == NULL) return;
MouseEvent *arg = (MouseEvent*)(p); MouseEvent *arg = (MouseEvent*)(p);
float x = arg->state.X.rel * sensX; float x = arg->state.X.rel * sensX;
float y = arg->state.Y.rel * sensY; float y = arg->state.Y.rel * sensY;
camera->getParentSceneNode()->getParentSceneNode()->yaw(Degree(-x)); camera->getParentSceneNode()->getParentSceneNode()->yaw(Degree(-x));
camera->getParentSceneNode()->pitch(Degree(-y)); camera->getParentSceneNode()->pitch(Degree(-y));
if(flipProt) if(flipProt)
{ {
// The camera before pitching // The camera before pitching
/*Quaternion nopitch = camera->getParentSceneNode()->getOrientation(); /*Quaternion nopitch = camera->getParentSceneNode()->getOrientation();
camera->getParentSceneNode()->pitch(Degree(-y)); camera->getParentSceneNode()->pitch(Degree(-y));
// Apply some failsafe measures against the camera flipping // Apply some failsafe measures against the camera flipping
// upside down. Is the camera close to pointing straight up or // upside down. Is the camera close to pointing straight up or
// down? // down?
if(Ogre::Vector3(camera->getParentSceneNode()->getOrientation()*Ogre::Vector3::UNIT_Y)[1] <= 0.1) if(Ogre::Vector3(camera->getParentSceneNode()->getOrientation()*Ogre::Vector3::UNIT_Y)[1] <= 0.1)
// If so, undo the last pitch // If so, undo the last pitch
camera->getParentSceneNode()->setOrientation(nopitch);*/ camera->getParentSceneNode()->setOrientation(nopitch);*/
//camera->getU //camera->getU
// Angle of rotation around the X-axis. // Angle of rotation around the X-axis.
float pitchAngle = (2 * Ogre::Degree(Ogre::Math::ACos(camera->getParentSceneNode()->getOrientation().w)).valueDegrees()); float pitchAngle = (2 * Ogre::Degree(Ogre::Math::ACos(camera->getParentSceneNode()->getOrientation().w)).valueDegrees());
// Just to determine the sign of the angle we pick up above, the // Just to determine the sign of the angle we pick up above, the
// value itself does not interest us. // value itself does not interest us.
float pitchAngleSign = camera->getParentSceneNode()->getOrientation().x; float pitchAngleSign = camera->getParentSceneNode()->getOrientation().x;
// Limit the pitch between -90 degress and +90 degrees, Quake3-style. // Limit the pitch between -90 degress and +90 degrees, Quake3-style.
if (pitchAngle > 90.0f) if (pitchAngle > 90.0f)
{ {
if (pitchAngleSign > 0) if (pitchAngleSign > 0)
// Set orientation to 90 degrees on X-axis. // Set orientation to 90 degrees on X-axis.
camera->getParentSceneNode()->setOrientation(Ogre::Quaternion(Ogre::Math::Sqrt(0.5f), camera->getParentSceneNode()->setOrientation(Ogre::Quaternion(Ogre::Math::Sqrt(0.5f),
Ogre::Math::Sqrt(0.5f), 0, 0)); Ogre::Math::Sqrt(0.5f), 0, 0));
else if (pitchAngleSign < 0) else if (pitchAngleSign < 0)
// Sets orientation to -90 degrees on X-axis. // Sets orientation to -90 degrees on X-axis.
camera->getParentSceneNode()->setOrientation(Ogre::Quaternion(Ogre::Math::Sqrt(0.5f), camera->getParentSceneNode()->setOrientation(Ogre::Quaternion(Ogre::Math::Sqrt(0.5f),
-Ogre::Math::Sqrt(0.5f), 0, 0)); -Ogre::Math::Sqrt(0.5f), 0, 0));
} }
} }
} }