2011-02-22 14:02:50 +01:00
|
|
|
#ifndef OENGINE_BULLET_PHYSIC_H
|
|
|
|
#define OENGINE_BULLET_PHYSIC_H
|
|
|
|
|
2011-02-26 16:34:43 +01:00
|
|
|
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
2011-02-22 14:02:50 +01:00
|
|
|
#include "BulletCollision/CollisionDispatch/btGhostObject.h"
|
|
|
|
#include <string>
|
|
|
|
#include <list>
|
|
|
|
#include <map>
|
2011-03-18 13:24:47 +01:00
|
|
|
#include "BulletShapeLoader.h"
|
2012-06-17 20:56:10 -04:00
|
|
|
#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h"
|
2014-08-30 23:11:09 +02:00
|
|
|
#include <boost/shared_ptr.hpp>
|
2012-09-15 18:17:42 -04:00
|
|
|
|
2011-02-22 14:02:50 +01:00
|
|
|
class btRigidBody;
|
|
|
|
class btBroadphaseInterface;
|
|
|
|
class btDefaultCollisionConfiguration;
|
|
|
|
class btSequentialImpulseConstraintSolver;
|
|
|
|
class btCollisionDispatcher;
|
|
|
|
class btDiscreteDynamicsWorld;
|
2012-06-06 21:08:20 +02:00
|
|
|
class btHeightfieldTerrainShape;
|
2011-02-22 14:02:50 +01:00
|
|
|
|
|
|
|
namespace BtOgre
|
|
|
|
{
|
2011-04-03 13:12:12 +02:00
|
|
|
class DebugDrawer;
|
2011-02-22 14:02:50 +01:00
|
|
|
}
|
|
|
|
|
2013-02-19 04:03:24 +01:00
|
|
|
namespace Ogre
|
|
|
|
{
|
|
|
|
class SceneManager;
|
|
|
|
}
|
|
|
|
|
2011-02-22 14:02:50 +01:00
|
|
|
namespace MWWorld
|
|
|
|
{
|
2011-04-03 13:12:12 +02:00
|
|
|
class World;
|
2011-02-22 14:02:50 +01:00
|
|
|
}
|
|
|
|
|
2012-09-15 18:17:42 -04:00
|
|
|
|
2011-02-22 14:02:50 +01:00
|
|
|
namespace OEngine {
|
|
|
|
namespace Physic
|
|
|
|
{
|
2011-04-03 13:12:12 +02:00
|
|
|
struct PhysicEvent;
|
2012-09-03 20:32:20 -04:00
|
|
|
class PhysicEngine;
|
|
|
|
class RigidBody;
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2013-03-06 17:31:57 +00:00
|
|
|
enum CollisionType {
|
|
|
|
CollisionType_Nothing = 0, //<Collide with nothing
|
|
|
|
CollisionType_World = 1<<0, //<Collide with world objects
|
2013-05-07 19:43:44 +01:00
|
|
|
CollisionType_Actor = 1<<1, //<Collide sith actors
|
|
|
|
CollisionType_HeightMap = 1<<2, //<collide with heightmap
|
2013-03-06 17:31:57 +00:00
|
|
|
CollisionType_Raycasting = 1<<3 //Still used?
|
|
|
|
};
|
|
|
|
|
2011-02-22 20:53:02 +01:00
|
|
|
/**
|
2011-02-26 16:34:43 +01:00
|
|
|
*This is just used to be able to name objects.
|
2011-02-22 20:53:02 +01:00
|
|
|
*/
|
|
|
|
class PairCachingGhostObject : public btPairCachingGhostObject
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PairCachingGhostObject(std::string name)
|
|
|
|
:btPairCachingGhostObject(),mName(name)
|
|
|
|
{
|
|
|
|
}
|
2012-03-25 16:12:23 +02:00
|
|
|
virtual ~PairCachingGhostObject(){}
|
|
|
|
|
2011-02-22 20:53:02 +01:00
|
|
|
std::string mName;
|
|
|
|
};
|
|
|
|
|
2013-08-17 02:51:19 -07:00
|
|
|
/**
|
|
|
|
*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,
|
|
|
|
*so one never should use btRigidBody directly!
|
|
|
|
*/
|
|
|
|
class RigidBody: public btRigidBody
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
RigidBody(btRigidBody::btRigidBodyConstructionInfo& CI,std::string name);
|
|
|
|
virtual ~RigidBody();
|
|
|
|
std::string mName;
|
2014-06-21 23:32:58 +02:00
|
|
|
|
|
|
|
// Hack: placeable objects (that can be picked up by the player) have different collision behaviour.
|
|
|
|
// This variable needs to be passed to BulletNifLoader.
|
2013-08-17 02:51:19 -07:00
|
|
|
bool mPlaceable;
|
|
|
|
};
|
|
|
|
|
2014-06-22 16:43:41 +02:00
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
class PhysicActor
|
|
|
|
{
|
|
|
|
public:
|
2013-02-07 16:18:29 -08:00
|
|
|
PhysicActor(const std::string &name, const std::string &mesh, PhysicEngine *engine, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, float scale);
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
~PhysicActor();
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2013-02-19 04:18:15 -08:00
|
|
|
void setPosition(const Ogre::Vector3 &pos);
|
|
|
|
|
2014-05-13 01:43:52 +02:00
|
|
|
/**
|
|
|
|
* Sets the collisionMode for this actor. If disabled, the actor can fly and clip geometry.
|
|
|
|
*/
|
|
|
|
void enableCollisionMode(bool collision);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Enables or disables the *external* collision body. If disabled, other actors will not collide with this actor.
|
|
|
|
*/
|
|
|
|
void enableCollisionBody(bool collision);
|
2011-03-17 11:00:46 +01:00
|
|
|
|
2013-02-18 22:39:43 -08:00
|
|
|
bool getCollisionMode() const
|
|
|
|
{
|
2014-06-21 23:32:58 +02:00
|
|
|
return mInternalCollisionMode;
|
2013-02-18 22:39:43 -08:00
|
|
|
}
|
|
|
|
|
2012-09-15 16:45:50 -04:00
|
|
|
/**
|
|
|
|
* Sets the scale of the PhysicActor
|
|
|
|
*/
|
2012-09-12 18:30:32 -04:00
|
|
|
void setScale(float scale);
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2014-06-21 23:32:58 +02:00
|
|
|
void setRotation (const Ogre::Quaternion& rotation);
|
|
|
|
|
|
|
|
const Ogre::Vector3& getPosition() const;
|
|
|
|
|
2013-02-05 07:41:57 -08:00
|
|
|
/**
|
2014-06-23 20:43:24 +02:00
|
|
|
* Returns the (scaled) half extents
|
2013-02-05 07:41:57 -08:00
|
|
|
*/
|
|
|
|
Ogre::Vector3 getHalfExtents() const;
|
|
|
|
|
2013-02-05 09:24:22 -08:00
|
|
|
/**
|
2013-08-18 05:38:50 -07:00
|
|
|
* Sets the current amount of inertial force (incl. gravity) affecting this physic actor
|
2013-02-05 09:24:22 -08:00
|
|
|
*/
|
2013-08-18 05:38:50 -07:00
|
|
|
void setInertialForce(const Ogre::Vector3 &force);
|
2013-02-05 09:24:22 -08:00
|
|
|
|
|
|
|
/**
|
2013-08-18 05:38:50 -07:00
|
|
|
* Gets the current amount of inertial force (incl. gravity) affecting this physic actor
|
2013-02-05 09:24:22 -08:00
|
|
|
*/
|
2013-08-18 05:38:50 -07:00
|
|
|
const Ogre::Vector3 &getInertialForce() const
|
|
|
|
{
|
|
|
|
return mForce;
|
|
|
|
}
|
2013-02-05 09:24:22 -08:00
|
|
|
|
2013-02-06 21:44:58 -08:00
|
|
|
void setOnGround(bool grounded);
|
|
|
|
|
2013-08-18 05:38:50 -07:00
|
|
|
bool getOnGround() const
|
|
|
|
{
|
2014-06-21 23:32:58 +02:00
|
|
|
return mInternalCollisionMode && mOnGround;
|
2013-08-18 05:38:50 -07:00
|
|
|
}
|
2013-02-06 21:44:58 -08:00
|
|
|
|
2013-08-17 02:51:19 -07:00
|
|
|
btCollisionObject *getCollisionBody() const
|
|
|
|
{
|
|
|
|
return mBody;
|
|
|
|
}
|
|
|
|
|
2013-07-30 22:00:48 +02:00
|
|
|
private:
|
2013-06-27 19:42:27 -07:00
|
|
|
void disableCollisionBody();
|
|
|
|
void enableCollisionBody();
|
2012-09-03 20:32:20 -04:00
|
|
|
|
2014-06-21 23:32:58 +02:00
|
|
|
boost::shared_ptr<btCollisionShape> mShape;
|
|
|
|
|
2013-03-04 12:08:35 +00:00
|
|
|
OEngine::Physic::RigidBody* mBody;
|
2013-08-17 02:51:19 -07:00
|
|
|
|
2014-06-21 23:32:58 +02:00
|
|
|
Ogre::Quaternion mMeshOrientation;
|
|
|
|
Ogre::Vector3 mMeshTranslation;
|
|
|
|
Ogre::Vector3 mHalfExtents;
|
|
|
|
|
|
|
|
float mScale;
|
|
|
|
Ogre::Vector3 mPosition;
|
2013-08-17 02:51:19 -07:00
|
|
|
|
2013-08-18 05:38:50 -07:00
|
|
|
Ogre::Vector3 mForce;
|
|
|
|
bool mOnGround;
|
2014-06-21 23:32:58 +02:00
|
|
|
bool mInternalCollisionMode;
|
|
|
|
bool mExternalCollisionMode;
|
2013-08-17 02:51:19 -07:00
|
|
|
|
2012-09-03 20:32:20 -04:00
|
|
|
std::string mMesh;
|
2012-09-15 16:45:50 -04:00
|
|
|
std::string mName;
|
2013-08-17 02:51:19 -07:00
|
|
|
PhysicEngine *mEngine;
|
2011-04-03 13:12:12 +02:00
|
|
|
};
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
|
2012-06-06 21:08:20 +02:00
|
|
|
struct HeightField
|
|
|
|
{
|
|
|
|
btHeightfieldTerrainShape* mShape;
|
|
|
|
RigidBody* mBody;
|
|
|
|
};
|
|
|
|
|
2014-06-23 20:43:24 +02:00
|
|
|
struct AnimatedShapeInstance
|
|
|
|
{
|
|
|
|
btCollisionShape* mCompound;
|
|
|
|
|
|
|
|
// Maps bone name to child index in the compound shape
|
|
|
|
std::map<std::string, int> mAnimatedShapes;
|
|
|
|
};
|
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
/**
|
|
|
|
* The PhysicEngine class contain everything which is needed for Physic.
|
|
|
|
* It's needed that Ogre Resources are set up before the PhysicEngine is created.
|
|
|
|
* Note:deleting it WILL NOT delete the RigidBody!
|
|
|
|
* TODO:unload unused resources?
|
|
|
|
*/
|
|
|
|
class PhysicEngine
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Note that the shapeLoader IS destroyed by the phyic Engine!!
|
|
|
|
*/
|
|
|
|
PhysicEngine(BulletShapeLoader* shapeLoader);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* It DOES destroy the shape loader!
|
|
|
|
*/
|
|
|
|
~PhysicEngine();
|
|
|
|
|
|
|
|
/**
|
2012-09-05 17:44:11 -04:00
|
|
|
* Creates a RigidBody. It does not add it to the simulation.
|
|
|
|
* After created, the body is set to the correct rotation, position, and scale
|
2011-04-03 13:12:12 +02:00
|
|
|
*/
|
2013-02-07 16:18:29 -08:00
|
|
|
RigidBody* createAndAdjustRigidBody(const std::string &mesh, const std::string &name,
|
|
|
|
float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation,
|
2013-03-14 03:04:02 +01:00
|
|
|
Ogre::Vector3* scaledBoxTranslation = 0, Ogre::Quaternion* boxRotation = 0, bool raycasting=false, bool placeable=false);
|
2011-04-03 13:12:12 +02:00
|
|
|
|
2012-08-15 16:47:26 -04:00
|
|
|
/**
|
|
|
|
* Adjusts a rigid body to the right position and rotation
|
|
|
|
*/
|
|
|
|
|
2013-02-07 16:18:29 -08:00
|
|
|
void adjustRigidBody(RigidBody* body, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation,
|
|
|
|
const Ogre::Vector3 &scaledBoxTranslation = Ogre::Vector3::ZERO,
|
|
|
|
const Ogre::Quaternion &boxRotation = Ogre::Quaternion::IDENTITY);
|
2012-08-15 16:47:26 -04:00
|
|
|
/**
|
|
|
|
Mainly used to (but not limited to) adjust rigid bodies based on box shapes to the right position and rotation.
|
|
|
|
*/
|
2013-02-07 16:18:29 -08:00
|
|
|
void boxAdjustExternal(const std::string &mesh, RigidBody* body, float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation);
|
2012-03-13 17:09:50 +01:00
|
|
|
/**
|
|
|
|
* Add a HeightField to the simulation
|
|
|
|
*/
|
|
|
|
void addHeightField(float* heights,
|
|
|
|
int x, int y, float yoffset,
|
|
|
|
float triSize, float sqrtVerts);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove a HeightField from the simulation
|
|
|
|
*/
|
|
|
|
void removeHeightField(int x, int y);
|
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
/**
|
|
|
|
* Remove a RigidBody from the simulation. It does not delete it, and does not remove it from the RigidBodyMap.
|
|
|
|
*/
|
2013-02-07 16:18:29 -08:00
|
|
|
void removeRigidBody(const std::string &name);
|
2011-04-03 13:12:12 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Delete a RigidBody, and remove it from RigidBodyMap.
|
|
|
|
*/
|
2013-02-07 16:18:29 -08:00
|
|
|
void deleteRigidBody(const std::string &name);
|
2011-04-03 13:12:12 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a pointer to a given rigid body.
|
|
|
|
*/
|
2013-03-08 23:46:25 +01:00
|
|
|
RigidBody* getRigidBody(const std::string &name, bool raycasting=false);
|
2011-04-03 13:12:12 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create and add a character to the scene, and add it to the ActorMap.
|
|
|
|
*/
|
2013-02-07 16:18:29 -08:00
|
|
|
void addCharacter(const std::string &name, const std::string &mesh,
|
|
|
|
const Ogre::Vector3 &position, float scale, const Ogre::Quaternion &rotation);
|
2011-04-03 13:12:12 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove a character from the scene. TODO:delete it! for now, a small memory leak^^ done?
|
|
|
|
*/
|
2013-02-07 16:18:29 -08:00
|
|
|
void removeCharacter(const std::string &name);
|
2011-04-03 13:12:12 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Return a pointer to a character
|
|
|
|
* TODO:check if the actor exist...
|
|
|
|
*/
|
2013-02-07 16:18:29 -08:00
|
|
|
PhysicActor* getCharacter(const std::string &name);
|
2011-04-03 13:12:12 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
|
2012-03-30 16:02:41 +02:00
|
|
|
bool toggleDebugRendering();
|
|
|
|
|
2012-07-26 16:14:11 +04:00
|
|
|
void getObjectAABB(const std::string &mesh, float scale, btVector3 &min, btVector3 &max);
|
2012-07-24 18:52:08 +04:00
|
|
|
|
2013-02-19 04:03:24 +01:00
|
|
|
void setSceneManager(Ogre::SceneManager* sceneMgr);
|
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
/**
|
|
|
|
* Return the closest object hit by a ray. If there are no objects, it will return ("",-1).
|
2014-05-27 17:39:04 +02:00
|
|
|
* If \a normal is non-NULL, the hit normal will be written there (if there is a hit)
|
2011-04-03 13:12:12 +02:00
|
|
|
*/
|
2014-07-26 18:01:53 +02:00
|
|
|
std::pair<std::string,float> rayTest(const btVector3& from,const btVector3& to,bool raycastingObjectOnly = true,
|
2014-05-27 17:39:04 +02:00
|
|
|
bool ignoreHeightMap = false, Ogre::Vector3* normal = NULL);
|
2011-02-22 20:53:02 +01:00
|
|
|
|
2012-03-25 12:26:44 +02:00
|
|
|
/**
|
|
|
|
* Return all objects hit by a ray.
|
|
|
|
*/
|
2014-07-26 18:01:53 +02:00
|
|
|
std::vector< std::pair<float, std::string> > rayTest2(const btVector3 &from, const btVector3 &to);
|
2012-03-25 12:26:44 +02:00
|
|
|
|
2013-04-30 20:26:59 +02:00
|
|
|
std::pair<bool, float> sphereCast (float radius, btVector3& from, btVector3& to);
|
|
|
|
///< @return (hit, relative distance)
|
|
|
|
|
2014-08-11 04:43:06 +02:00
|
|
|
std::vector<std::string> getCollisions(const std::string& name, int collisionGroup, int collisionMask);
|
2013-04-28 14:59:15 +02:00
|
|
|
|
2013-08-23 12:25:57 -07:00
|
|
|
// Get the nearest object that's inside the given object, filtering out objects of the
|
|
|
|
// provided name
|
|
|
|
std::pair<const RigidBody*,btVector3> getFilteredContact(const std::string &filter,
|
|
|
|
const btVector3 &origin,
|
|
|
|
btCollisionObject *object);
|
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
//Bullet Stuff
|
2012-03-25 18:12:00 +02:00
|
|
|
btOverlappingPairCache* pairCache;
|
2011-04-03 13:12:12 +02:00
|
|
|
btBroadphaseInterface* broadphase;
|
|
|
|
btDefaultCollisionConfiguration* collisionConfiguration;
|
|
|
|
btSequentialImpulseConstraintSolver* solver;
|
|
|
|
btCollisionDispatcher* dispatcher;
|
2014-06-21 23:32:58 +02:00
|
|
|
btDiscreteDynamicsWorld* mDynamicsWorld;
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
//the NIF file loader.
|
|
|
|
BulletShapeLoader* mShapeLoader;
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2012-06-06 21:08:20 +02:00
|
|
|
typedef std::map<std::string, HeightField> HeightFieldContainer;
|
|
|
|
HeightFieldContainer mHeightFieldMap;
|
|
|
|
|
2012-03-25 16:12:23 +02:00
|
|
|
typedef std::map<std::string,RigidBody*> RigidBodyContainer;
|
2013-03-08 23:46:25 +01:00
|
|
|
RigidBodyContainer mCollisionObjectMap;
|
|
|
|
|
2014-06-23 20:43:24 +02:00
|
|
|
// Compound shapes that must be animated each frame based on bone positions
|
|
|
|
// the index refers to an element in mCollisionObjectMap
|
|
|
|
std::map<RigidBody*, AnimatedShapeInstance > mAnimatedShapes;
|
|
|
|
|
2013-03-08 23:46:25 +01:00
|
|
|
RigidBodyContainer mRaycastingObjectMap;
|
2012-03-25 16:12:23 +02:00
|
|
|
|
2014-06-23 20:43:24 +02:00
|
|
|
std::map<RigidBody*, AnimatedShapeInstance > mAnimatedRaycastingShapes;
|
|
|
|
|
2012-03-25 16:12:23 +02:00
|
|
|
typedef std::map<std::string, PhysicActor*> PhysicActorContainer;
|
2013-05-01 11:15:43 +02:00
|
|
|
PhysicActorContainer mActorMap;
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2013-02-19 04:03:24 +01:00
|
|
|
Ogre::SceneManager* mSceneMgr;
|
|
|
|
|
2011-04-03 13:12:12 +02:00
|
|
|
//debug rendering
|
|
|
|
BtOgre::DebugDrawer* mDebugDrawer;
|
|
|
|
bool isDebugCreated;
|
2012-03-30 16:02:41 +02:00
|
|
|
bool mDebugActive;
|
2011-04-03 13:12:12 +02:00
|
|
|
};
|
2011-02-22 14:02:50 +01:00
|
|
|
|
2012-03-25 12:26:44 +02:00
|
|
|
|
|
|
|
struct MyRayResultCallback : public btCollisionWorld::RayResultCallback
|
|
|
|
{
|
|
|
|
virtual btScalar addSingleResult( btCollisionWorld::LocalRayResult& rayResult, bool bNormalInWorldSpace)
|
|
|
|
{
|
|
|
|
results.push_back( std::make_pair(rayResult.m_hitFraction, rayResult.m_collisionObject) );
|
|
|
|
return rayResult.m_hitFraction;
|
|
|
|
}
|
|
|
|
|
2012-03-25 22:53:00 +02:00
|
|
|
static bool cmp( const std::pair<float, std::string>& i, const std::pair<float, std::string>& j )
|
2012-03-25 12:26:44 +02:00
|
|
|
{
|
2012-03-25 20:52:56 +02:00
|
|
|
if( i.first > j.first ) return false;
|
|
|
|
if( j.first > i.first ) return true;
|
2012-03-25 12:26:44 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-06-20 18:22:18 +02:00
|
|
|
std::vector < std::pair<float, const btCollisionObject*> > results;
|
2011-04-03 13:12:12 +02:00
|
|
|
};
|
2011-02-22 14:02:50 +01:00
|
|
|
|
|
|
|
}}
|
|
|
|
|
2011-02-26 16:34:43 +01:00
|
|
|
#endif
|