OpenMW
libs/openengine/bullet/physic.hpp
Go to the documentation of this file.
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