1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-04-11 00:44:33 +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. ------------------------------------------------------------------
@ -151,11 +151,11 @@ public:
/// Remove all points from the point list /// Remove all points from the point list
void clear(); void clear();
/// Call this to update the hardware buffer after making changes. /// Call this to update the hardware buffer after making changes.
void update(); void update();
/** Set the type of operation to draw with. /** Set the type of operation to draw with.
* @param opType Can be one of * @param opType Can be one of
* - RenderOperation::OT_LINE_STRIP * - RenderOperation::OT_LINE_STRIP
* - RenderOperation::OT_LINE_LIST * - RenderOperation::OT_LINE_LIST
* - RenderOperation::OT_POINT_LIST * - RenderOperation::OT_POINT_LIST
@ -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.
void setDebugMode(int isOn)
{
mDebugOn = (isOn == 0) ? false : true;
if (!mDebugOn) //0 for off, anything else for on.
mLineDrawer->clear(); void setDebugMode(int isOn)
} {
mDebugOn = (isOn == 0) ? false : true;
//0 for off, anything else for on.
int getDebugMode() const if (!mDebugOn)
{ mLineDrawer->clear();
return mDebugOn; }
}
//0 for off, anything else for on.
int getDebugMode() const
{
return mDebugOn;
}
}; };

View File

@ -3,7 +3,7 @@
* *
* Filename: BtOgreGP.h * Filename: BtOgreGP.h
* *
* Description: The part of BtOgre that handles information transfer from Ogre to * Description: The part of BtOgre that handles information transfer from Ogre to
* Bullet (like mesh data for making trimeshes). * Bullet (like mesh data for making trimeshes).
* *
* Version: 1.0 * Version: 1.0
@ -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,43 +101,42 @@ 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::Entity* mEntity; Ogre::SceneNode* mNode;
Ogre::SceneNode* mNode;
Ogre::Vector3 *mTransformedVerticesTemp; Ogre::Vector3 *mTransformedVerticesTemp;
size_t mTransformedVerticesTempSize; size_t mTransformedVerticesTempSize;
}; };
} }
#endif #endif

View File

@ -3,7 +3,7 @@
* *
* Filename: BtOgrePG.h * Filename: BtOgrePG.h
* *
* Description: The part of BtOgre that handles information transfer from Bullet to * Description: The part of BtOgre that handles information transfer from Bullet to
* Ogre (like updating graphics object positions). * Ogre (like updating graphics object positions).
* *
* Version: 1.0 * Version: 1.0
@ -25,7 +25,7 @@ namespace BtOgre {
//A MotionState is Bullet's way of informing you about updates to an object. //A MotionState is Bullet's way of informing you about updates to an object.
//Pass this MotionState to a btRigidBody to have your SceneNode updated automaticaly. //Pass this MotionState to a btRigidBody to have your SceneNode updated automaticaly.
class RigidBodyState : public btMotionState class RigidBodyState : public btMotionState
{ {
protected: protected:
btTransform mTransform; btTransform mTransform;
@ -42,19 +42,19 @@ class RigidBodyState : public btMotionState
} }
RigidBodyState(Ogre::SceneNode *node) RigidBodyState(Ogre::SceneNode *node)
: mTransform(((node != NULL) ? BtOgre::Convert::toBullet(node->getOrientation()) : btQuaternion(0,0,0,1)), : mTransform(((node != NULL) ? BtOgre::Convert::toBullet(node->getOrientation()) : btQuaternion(0,0,0,1)),
((node != NULL) ? BtOgre::Convert::toBullet(node->getPosition()) : btVector3(0,0,0))), ((node != NULL) ? BtOgre::Convert::toBullet(node->getPosition()) : btVector3(0,0,0))),
mCenterOfMassOffset(btTransform::getIdentity()), mCenterOfMassOffset(btTransform::getIdentity()),
mNode(node) mNode(node)
{ {
} }
virtual void getWorldTransform(btTransform &ret) const virtual void getWorldTransform(btTransform &ret) const
{ {
ret = mCenterOfMassOffset.inverse() * mTransform; ret = mCenterOfMassOffset.inverse() * mTransform;
} }
virtual void setWorldTransform(const btTransform &in) virtual void setWorldTransform(const btTransform &in)
{ {
if (mNode == NULL) if (mNode == NULL)
return; return;
@ -68,7 +68,7 @@ class RigidBodyState : public btMotionState
mNode->setPosition(pos.x(), pos.y(), pos.z()); mNode->setPosition(pos.x(), pos.y(), pos.z());
} }
void setNode(Ogre::SceneNode *node) void setNode(Ogre::SceneNode *node)
{ {
mNode = node; mNode = node;
} }

View File

@ -2,8 +2,8 @@
BulletShape::BulletShape(Ogre::ResourceManager* creator, const Ogre::String &name, BulletShape::BulletShape(Ogre::ResourceManager* creator, const Ogre::String &name,
Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual, Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual,
Ogre::ManualResourceLoader *loader) : Ogre::ManualResourceLoader *loader) :
Ogre::Resource(creator, name, handle, group, isManual, loader) Ogre::Resource(creator, name, handle, group, isManual, loader)
{ {
@ -12,9 +12,9 @@ Ogre::Resource(creator, name, handle, group, isManual, loader)
/* For consistency with StringInterface, but we don't add any parameters here /* For consistency with StringInterface, but we don't add any parameters here
That's because the Resource implementation of StringInterface is to That's because the Resource implementation of StringInterface is to
list all the options that need to be set before loading, of which list all the options that need to be set before loading, of which
we have none as such. Full details can be set through scripts. we have none as such. Full details can be set through scripts.
*/ */
Shape = NULL; Shape = NULL;
collide = true; collide = true;
createParamDictionary("BulletShape"); createParamDictionary("BulletShape");
@ -70,8 +70,8 @@ BulletShapeManager *BulletShapeManager::getSingletonPtr()
} }
BulletShapeManager &BulletShapeManager::getSingleton() BulletShapeManager &BulletShapeManager::getSingleton()
{ {
assert(ms_Singleton); assert(ms_Singleton);
return(*ms_Singleton); return(*ms_Singleton);
} }
@ -103,8 +103,8 @@ BulletShapePtr BulletShapeManager::load(const Ogre::String &name, const Ogre::St
return textf; return textf;
} }
Ogre::Resource *BulletShapeManager::createImpl(const Ogre::String &name, Ogre::ResourceHandle handle, Ogre::Resource *BulletShapeManager::createImpl(const Ogre::String &name, Ogre::ResourceHandle handle,
const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader, const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader,
const Ogre::NameValuePairList *createParams) const Ogre::NameValuePairList *createParams)
{ {
BulletShape* res = new BulletShape(this, name, handle, group, isManual, loader); BulletShape* res = new BulletShape(this, name, handle, group, isManual, loader);
@ -121,4 +121,4 @@ void BulletShapeLoader::loadResource(Ogre::Resource *resource)
{} {}
void BulletShapeLoader::load(const std::string &name,const std::string &group) void BulletShapeLoader::load(const std::string &name,const std::string &group)
{} {}

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

@ -4,8 +4,8 @@ Copyright (c) 2003-2008 Erwin Coumans http://bulletphysics.com
This software is provided 'as-is', without any express or implied warranty. This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software. In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely, including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions: subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
@ -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,179 +45,179 @@ 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);
void setVerticalVelocity(float z); void setVerticalVelocity(float z);
void enableCollisions(bool collision); void enableCollisions(bool collision);
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));
} }
} }
} }

View File

@ -104,7 +104,7 @@ void OgreRenderer::createScene(const std::string camName, float fov, float nearC
mCamera = mScene->createCamera(camName); mCamera = mScene->createCamera(camName);
mCamera->setNearClipDistance(nearClip); mCamera->setNearClipDistance(nearClip);
mCamera->setFOVy(Degree(fov)); mCamera->setFOVy(Degree(fov));
// Create one viewport, entire window // Create one viewport, entire window
mView = mWindow->addViewport(mCamera); mView = mWindow->addViewport(mCamera);