OpenMW
|
00001 #ifndef OENGINE_BULLET_PHYSIC_H 00002 #define OENGINE_BULLET_PHYSIC_H 00003 00004 #include <BulletDynamics/Dynamics/btRigidBody.h> 00005 #include "BulletCollision/CollisionDispatch/btGhostObject.h" 00006 #include <string> 00007 #include <list> 00008 #include <map> 00009 #include "BulletShapeLoader.h" 00010 #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" 00011 00012 00013 00014 class btRigidBody; 00015 class btBroadphaseInterface; 00016 class btDefaultCollisionConfiguration; 00017 class btSequentialImpulseConstraintSolver; 00018 class btCollisionDispatcher; 00019 class btDiscreteDynamicsWorld; 00020 class btHeightfieldTerrainShape; 00021 00022 namespace BtOgre 00023 { 00024 class DebugDrawer; 00025 } 00026 00027 namespace Ogre 00028 { 00029 class SceneManager; 00030 } 00031 00032 namespace MWWorld 00033 { 00034 class World; 00035 } 00036 00037 00038 namespace OEngine { 00039 namespace Physic 00040 { 00041 struct PhysicEvent; 00042 class PhysicEngine; 00043 class RigidBody; 00044 00045 enum CollisionType { 00046 CollisionType_Nothing = 0, //<Collide with nothing 00047 CollisionType_World = 1<<0, //<Collide with world objects 00048 CollisionType_Actor = 1<<1, //<Collide sith actors 00049 CollisionType_HeightMap = 1<<2, //<collide with heightmap 00050 CollisionType_Raycasting = 1<<3 //Still used? 00051 }; 00052 00056 class PairCachingGhostObject : public btPairCachingGhostObject 00057 { 00058 public: 00059 PairCachingGhostObject(std::string name) 00060 :btPairCachingGhostObject(),mName(name) 00061 { 00062 } 00063 virtual ~PairCachingGhostObject(){} 00064 00065 std::string mName; 00066 }; 00067 00073 class RigidBody: public btRigidBody 00074 { 00075 public: 00076 RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name); 00077 virtual ~RigidBody(); 00078 std::string mName; 00079 bool mPlaceable; 00080 }; 00081 00086 class PhysicActor 00087 { 00088 public: 00089 PhysicActor(const std::string &name, const std::string &mesh, PhysicEngine *engine, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, float scale); 00090 00091 ~PhysicActor(); 00092 00093 void setPosition(const Ogre::Vector3 &pos); 00094 00100 void setRotation(const Ogre::Quaternion &quat); 00101 00102 void enableCollisions(bool collision); 00103 00104 bool getCollisionMode() const 00105 { 00106 return mCollisionMode; 00107 } 00108 00109 00114 Ogre::Vector3 getPosition(); 00115 00119 Ogre::Quaternion getRotation(); 00120 00124 void setScale(float scale); 00125 00129 Ogre::Vector3 getHalfExtents() const; 00130 00134 void setInertialForce(const Ogre::Vector3 &force); 00135 00139 const Ogre::Vector3 &getInertialForce() const 00140 { 00141 return mForce; 00142 } 00143 00144 void setOnGround(bool grounded); 00145 00146 bool getOnGround() const 00147 { 00148 return mCollisionMode && mOnGround; 00149 } 00150 00151 btCollisionObject *getCollisionBody() const 00152 { 00153 return mBody; 00154 } 00155 00156 private: 00157 void disableCollisionBody(); 00158 void enableCollisionBody(); 00159 00160 OEngine::Physic::RigidBody* mBody; 00161 OEngine::Physic::RigidBody* mRaycastingBody; 00162 00163 Ogre::Vector3 mBoxScaledTranslation; 00164 Ogre::Quaternion mBoxRotation; 00165 btQuaternion mBoxRotationInverse; 00166 00167 Ogre::Vector3 mForce; 00168 bool mOnGround; 00169 bool mCollisionMode; 00170 00171 std::string mMesh; 00172 std::string mName; 00173 PhysicEngine *mEngine; 00174 }; 00175 00176 00177 struct HeightField 00178 { 00179 btHeightfieldTerrainShape* mShape; 00180 RigidBody* mBody; 00181 }; 00182 00189 class PhysicEngine 00190 { 00191 public: 00195 PhysicEngine(BulletShapeLoader* shapeLoader); 00196 00200 ~PhysicEngine(); 00201 00206 RigidBody* createAndAdjustRigidBody(const std::string &mesh, const std::string &name, 00207 float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, 00208 Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0, bool raycasting=false, bool placeable=false); 00209 00214 void adjustRigidBody(RigidBody* body, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, 00215 const Ogre::Vector3 &scaledBoxTranslation = Ogre::Vector3::ZERO, 00216 const Ogre::Quaternion &boxRotation = Ogre::Quaternion::IDENTITY); 00220 void boxAdjustExternal(const std::string &mesh, RigidBody* body, float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation); 00224 void addHeightField(float* heights, 00225 int x, int y, float yoffset, 00226 float triSize, float sqrtVerts); 00227 00231 void removeHeightField(int x, int y); 00232 00236 void addRigidBody(RigidBody* body, bool addToMap = true, RigidBody* raycastingBody = NULL,bool actor = false); 00237 00241 void removeRigidBody(const std::string &name); 00242 00246 void deleteRigidBody(const std::string &name); 00247 00251 RigidBody* getRigidBody(const std::string &name, bool raycasting=false); 00252 00256 void addCharacter(const std::string &name, const std::string &mesh, 00257 const Ogre::Vector3 &position, float scale, const Ogre::Quaternion &rotation); 00258 00262 void removeCharacter(const std::string &name); 00263 00268 PhysicActor* getCharacter(const std::string &name); 00269 00273 void stepSimulation(double deltaT); 00274 00278 void emptyEventLists(void); 00279 00284 void createDebugRendering(); 00285 00290 void setDebugRenderingMode(int mode); 00291 00292 bool toggleDebugRendering(); 00293 00294 void getObjectAABB(const std::string &mesh, float scale, btVector3 &min, btVector3 &max); 00295 00296 void setSceneManager(Ogre::SceneManager* sceneMgr); 00297 00298 bool isAnyActorStandingOn (const std::string& objectName); 00299 00303 std::pair<std::string,float> rayTest(btVector3& from,btVector3& to,bool raycastingObjectOnly = true,bool ignoreHeightMap = false); 00304 00308 std::vector< std::pair<float, std::string> > rayTest2(btVector3& from, btVector3& to); 00309 00310 std::pair<bool, float> sphereCast (float radius, btVector3& from, btVector3& to); 00312 00313 std::vector<std::string> getCollisions(const std::string& name); 00314 00315 // Get the nearest object that's inside the given object, filtering out objects of the 00316 // provided name 00317 std::pair<const RigidBody*,btVector3> getFilteredContact(const std::string &filter, 00318 const btVector3 &origin, 00319 btCollisionObject *object); 00320 00321 //Bullet Stuff 00322 btOverlappingPairCache* pairCache; 00323 btBroadphaseInterface* broadphase; 00324 btDefaultCollisionConfiguration* collisionConfiguration; 00325 btSequentialImpulseConstraintSolver* solver; 00326 btCollisionDispatcher* dispatcher; 00327 btDiscreteDynamicsWorld* dynamicsWorld; 00328 00329 //the NIF file loader. 00330 BulletShapeLoader* mShapeLoader; 00331 00332 typedef std::map<std::string, HeightField> HeightFieldContainer; 00333 HeightFieldContainer mHeightFieldMap; 00334 00335 typedef std::map<std::string,RigidBody*> RigidBodyContainer; 00336 RigidBodyContainer mCollisionObjectMap; 00337 00338 RigidBodyContainer mRaycastingObjectMap; 00339 00340 typedef std::map<std::string, PhysicActor*> PhysicActorContainer; 00341 PhysicActorContainer mActorMap; 00342 00343 Ogre::SceneManager* mSceneMgr; 00344 00345 //debug rendering 00346 BtOgre::DebugDrawer* mDebugDrawer; 00347 bool isDebugCreated; 00348 bool mDebugActive; 00349 }; 00350 00351 00352 struct MyRayResultCallback : public btCollisionWorld::RayResultCallback 00353 { 00354 virtual btScalar addSingleResult( btCollisionWorld::LocalRayResult& rayResult, bool bNormalInWorldSpace) 00355 { 00356 results.push_back( std::make_pair(rayResult.m_hitFraction, rayResult.m_collisionObject) ); 00357 return rayResult.m_hitFraction; 00358 } 00359 00360 static bool cmp( const std::pair<float, std::string>& i, const std::pair<float, std::string>& j ) 00361 { 00362 if( i.first > j.first ) return false; 00363 if( j.first > i.first ) return true; 00364 return false; 00365 } 00366 00367 std::vector < std::pair<float, const btCollisionObject*> > results; 00368 }; 00369 00370 }} 00371 00372 #endif