2015-05-12 01:02:15 +00:00
# ifndef OPENMW_MWPHYSICS_PHYSICSSYSTEM_H
# define OPENMW_MWPHYSICS_PHYSICSSYSTEM_H
2011-08-01 13:55:36 +00:00
2014-10-05 20:24:11 +00:00
# include <memory>
2015-06-03 21:04:35 +00:00
# include <map>
2015-11-19 22:33:08 +00:00
# include <set>
2014-10-05 20:24:11 +00:00
2015-06-03 21:04:35 +00:00
# include <osg/Quat>
2015-05-02 22:39:01 +00:00
# include <osg/ref_ptr>
2015-05-09 23:09:00 +00:00
# include "../mwworld/ptr.hpp"
2013-08-17 14:48:45 +00:00
2015-05-31 23:57:15 +00:00
# include "collisiontype.hpp"
2015-05-02 22:39:01 +00:00
namespace osg
{
class Group ;
}
2013-02-07 20:11:10 +00:00
2015-05-02 22:39:01 +00:00
namespace MWRender
{
class DebugDrawer ;
}
2015-11-16 22:30:10 +00:00
namespace Resource
2015-05-12 01:02:15 +00:00
{
class BulletShapeManager ;
2016-02-09 18:04:59 +00:00
class ResourceSystem ;
2015-05-12 01:02:15 +00:00
}
2016-02-09 18:04:59 +00:00
namespace SceneUtil
2015-05-12 01:02:15 +00:00
{
2016-02-09 18:04:59 +00:00
class UnrefQueue ;
2015-05-12 01:02:15 +00:00
}
2015-05-27 21:09:38 +00:00
class btCollisionWorld ;
2015-05-27 20:32:11 +00:00
class btBroadphaseInterface ;
class btDefaultCollisionConfiguration ;
class btCollisionDispatcher ;
class btCollisionObject ;
class btCollisionShape ;
2015-05-10 00:08:25 +00:00
2015-05-09 23:09:00 +00:00
namespace MWPhysics
2011-08-01 13:55:36 +00:00
{
2015-05-12 01:02:15 +00:00
typedef std : : vector < std : : pair < MWWorld : : Ptr , osg : : Vec3f > > PtrVelocityList ;
2015-05-10 00:08:25 +00:00
class HeightField ;
2015-05-12 01:02:15 +00:00
class Object ;
class Actor ;
2015-05-10 00:08:25 +00:00
2011-08-01 13:55:36 +00:00
class PhysicsSystem
{
public :
2015-05-12 14:24:53 +00:00
PhysicsSystem ( Resource : : ResourceSystem * resourceSystem , osg : : ref_ptr < osg : : Group > parentNode ) ;
2011-08-01 13:55:36 +00:00
~ PhysicsSystem ( ) ;
2011-08-22 19:34:51 +00:00
2016-02-09 18:04:59 +00:00
void setUnrefQueue ( SceneUtil : : UnrefQueue * unrefQueue ) ;
2016-02-06 23:07:02 +00:00
Resource : : BulletShapeManager * getShapeManager ( ) ;
2014-10-05 20:24:11 +00:00
void enableWater ( float height ) ;
void setWaterHeight ( float height ) ;
void disableWater ( ) ;
2015-12-18 17:32:42 +00:00
void addObject ( const MWWorld : : Ptr & ptr , const std : : string & mesh , int collisionType = CollisionType_World ) ;
2015-05-12 17:02:56 +00:00
void addActor ( const MWWorld : : Ptr & ptr , const std : : string & mesh ) ;
void updatePtr ( const MWWorld : : Ptr & old , const MWWorld : : Ptr & updated ) ;
Actor * getActor ( const MWWorld : : Ptr & ptr ) ;
2015-12-18 16:36:14 +00:00
const Actor * getActor ( const MWWorld : : ConstPtr & ptr ) const ;
2015-05-12 01:02:15 +00:00
// Object or Actor
void remove ( const MWWorld : : Ptr & ptr ) ;
void updateScale ( const MWWorld : : Ptr & ptr ) ;
void updateRotation ( const MWWorld : : Ptr & ptr ) ;
void updatePosition ( const MWWorld : : Ptr & ptr ) ;
2011-08-22 19:34:51 +00:00
2015-08-31 14:08:19 +00:00
void addHeightField ( const float * heights , int x , int y , float triSize , float sqrtVerts ) ;
2012-03-13 16:09:50 +00:00
void removeHeightField ( int x , int y ) ;
2011-08-01 13:55:36 +00:00
bool toggleCollisionMode ( ) ;
2013-08-20 18:31:49 +00:00
2014-06-23 18:43:24 +00:00
void stepSimulation ( float dt ) ;
2015-06-07 15:00:00 +00:00
void debugDraw ( ) ;
2014-06-23 18:43:24 +00:00
2015-12-18 16:56:48 +00:00
std : : vector < MWWorld : : Ptr > getCollisions ( const MWWorld : : ConstPtr & ptr , int collisionGroup , int collisionMask ) const ; ///< get handles this object collides with
2015-05-12 01:02:15 +00:00
osg : : Vec3f traceDown ( const MWWorld : : Ptr & ptr , float maxHeight ) ;
2013-02-05 20:45:10 +00:00
2015-12-18 16:38:21 +00:00
std : : pair < MWWorld : : Ptr , osg : : Vec3f > getHitContact ( const MWWorld : : ConstPtr & actor ,
2015-05-22 02:36:17 +00:00
const osg : : Vec3f & origin ,
const osg : : Quat & orientation ,
2013-08-23 14:01:30 +00:00
float queryDistance ) ;
2012-03-25 18:52:56 +00:00
2015-11-18 18:00:43 +00:00
/// Get distance from \a point to the collision shape of \a target. Uses a raycast to find where the
/// target vector hits the collision shape and then calculates distance from the intersection point.
/// This can be used to find out how much nearer we need to move to the target for a "getHitContact" to be successful.
/// \note Only Actor targets are supported at the moment.
2015-12-18 16:36:14 +00:00
float getHitDistance ( const osg : : Vec3f & point , const MWWorld : : ConstPtr & target ) const ;
2015-11-18 18:00:43 +00:00
2015-05-31 23:57:15 +00:00
struct RayResult
{
bool mHit ;
osg : : Vec3f mHitPos ;
osg : : Vec3f mHitNormal ;
MWWorld : : Ptr mHitObject ;
} ;
/// @param me Optional, a Ptr to ignore in the list of results
2015-12-18 17:32:42 +00:00
RayResult castRay ( const osg : : Vec3f & from , const osg : : Vec3f & to , MWWorld : : ConstPtr ignore = MWWorld : : ConstPtr ( ) , int mask =
CollisionType_World | CollisionType_HeightMap | CollisionType_Actor | CollisionType_Door , int group = 0xff ) const ;
2011-08-22 19:34:51 +00:00
2015-06-01 13:34:46 +00:00
RayResult castSphere ( const osg : : Vec3f & from , const osg : : Vec3f & to , float radius ) ;
2015-05-31 23:57:15 +00:00
/// Return true if actor1 can see actor2.
2015-12-18 17:02:57 +00:00
bool getLineOfSight ( const MWWorld : : ConstPtr & actor1 , const MWWorld : : ConstPtr & actor2 ) const ;
2012-07-25 16:25:53 +00:00
2015-06-01 00:40:42 +00:00
bool isOnGround ( const MWWorld : : Ptr & actor ) ;
2015-09-16 23:08:16 +00:00
/// Get physical half extents (scaled) of the given actor.
2015-12-18 16:36:14 +00:00
osg : : Vec3f getHalfExtents ( const MWWorld : : ConstPtr & actor ) const ;
2015-06-01 19:41:13 +00:00
2015-11-01 20:45:58 +00:00
/// @see MWPhysics::Actor::getRenderingHalfExtents
2015-12-18 16:36:14 +00:00
osg : : Vec3f getRenderingHalfExtents ( const MWWorld : : ConstPtr & actor ) const ;
2015-11-03 17:15:47 +00:00
/// Get the position of the collision shape for the actor. Use together with getHalfExtents() to get the collision bounds in world space.
/// @note The collision shape's origin is in its center, so the position returned can be described as center of the actor collision box in world space.
2016-02-13 01:56:41 +00:00
osg : : Vec3f getCollisionObjectPosition ( const MWWorld : : ConstPtr & actor ) const ;
2015-11-01 20:45:58 +00:00
2013-08-17 14:48:45 +00:00
/// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will
/// be overwritten. Valid until the next call to applyQueuedMovement.
2015-05-12 01:02:15 +00:00
void queueObjectMovement ( const MWWorld : : Ptr & ptr , const osg : : Vec3f & velocity ) ;
2013-08-17 14:48:45 +00:00
2014-08-13 14:23:34 +00:00
/// Apply all queued movements, then clear the list.
2013-08-17 14:48:45 +00:00
const PtrVelocityList & applyQueuedMovement ( float dt ) ;
2014-08-13 14:23:34 +00:00
/// Clear the queued movements list without applying.
void clearQueuedMovement ( ) ;
2014-07-29 17:01:40 +00:00
/// Return true if \a actor has been standing on \a object in this frame
/// This will trigger whenever the object is directly below the actor.
/// It doesn't matter if the actor is stationary or moving.
2015-12-18 16:56:48 +00:00
bool isActorStandingOn ( const MWWorld : : Ptr & actor , const MWWorld : : ConstPtr & object ) const ;
2014-07-29 17:01:40 +00:00
/// Get the handle of all actors standing on \a object in this frame.
2015-12-18 16:56:48 +00:00
void getActorsStandingOn ( const MWWorld : : ConstPtr & object , std : : vector < MWWorld : : Ptr > & out ) const ;
2014-07-29 17:01:40 +00:00
/// Return true if \a actor has collided with \a object in this frame.
/// This will detect running into objects, but will not detect climbing stairs, stepping up a small object, etc.
2015-12-18 16:56:48 +00:00
bool isActorCollidingWith ( const MWWorld : : Ptr & actor , const MWWorld : : ConstPtr & object ) const ;
2014-07-29 17:01:40 +00:00
/// Get the handle of all actors colliding with \a object in this frame.
2015-12-18 16:56:48 +00:00
void getActorsCollidingWith ( const MWWorld : : ConstPtr & object , std : : vector < MWWorld : : Ptr > & out ) const ;
2014-07-29 17:01:40 +00:00
2015-05-02 22:39:01 +00:00
bool toggleDebugRendering ( ) ;
2015-11-20 18:22:31 +00:00
/// Mark the given object as a 'non-solid' object. A non-solid object means that
/// \a isOnSolidGround will return false for actors standing on that object.
2015-12-18 16:56:48 +00:00
void markAsNonSolid ( const MWWorld : : ConstPtr & ptr ) ;
2015-11-20 18:22:31 +00:00
bool isOnSolidGround ( const MWWorld : : Ptr & actor ) const ;
2011-08-01 13:55:36 +00:00
private :
2012-08-17 06:10:37 +00:00
2014-10-05 20:24:11 +00:00
void updateWater ( ) ;
2016-02-09 18:04:59 +00:00
osg : : ref_ptr < SceneUtil : : UnrefQueue > mUnrefQueue ;
2015-05-10 00:08:25 +00:00
btBroadphaseInterface * mBroadphase ;
btDefaultCollisionConfiguration * mCollisionConfiguration ;
btCollisionDispatcher * mDispatcher ;
2015-05-27 21:09:38 +00:00
btCollisionWorld * mCollisionWorld ;
2015-05-10 00:08:25 +00:00
2015-11-16 22:30:10 +00:00
std : : auto_ptr < Resource : : BulletShapeManager > mShapeManager ;
2016-02-06 15:57:54 +00:00
Resource : : ResourceSystem * mResourceSystem ;
2015-05-12 01:02:15 +00:00
2015-12-18 16:30:39 +00:00
typedef std : : map < MWWorld : : ConstPtr , Object * > ObjectMap ;
2015-05-12 01:02:15 +00:00
ObjectMap mObjects ;
2015-11-19 22:33:08 +00:00
std : : set < Object * > mAnimatedObjects ; // stores pointers to elements in mObjects
2015-12-18 16:30:39 +00:00
typedef std : : map < MWWorld : : ConstPtr , Actor * > ActorMap ;
2015-05-12 01:02:15 +00:00
ActorMap mActors ;
2015-05-10 00:08:25 +00:00
typedef std : : map < std : : pair < int , int > , HeightField * > HeightFieldMap ;
HeightFieldMap mHeightFields ;
2015-05-02 22:39:01 +00:00
bool mDebugDrawEnabled ;
2015-11-18 20:20:12 +00:00
// Tracks standing collisions happening during a single frame. <actor handle, collided handle>
// This will detect standing on an object, but won't detect running e.g. against a wall.
2015-05-29 23:32:00 +00:00
typedef std : : map < MWWorld : : Ptr , MWWorld : : Ptr > CollisionMap ;
CollisionMap mStandingCollisions ;
2014-07-29 17:01:40 +00:00
2015-05-29 23:32:00 +00:00
// replaces all occurences of 'old' in the map by 'updated', no matter if its a key or value
void updateCollisionMapPtr ( CollisionMap & map , const MWWorld : : Ptr & old , const MWWorld : : Ptr & updated ) ;
2014-07-29 17:01:40 +00:00
2013-08-17 14:48:45 +00:00
PtrVelocityList mMovementQueue ;
PtrVelocityList mMovementResults ;
2013-08-20 18:31:49 +00:00
float mTimeAccum ;
2014-10-05 20:24:11 +00:00
float mWaterHeight ;
float mWaterEnabled ;
std : : auto_ptr < btCollisionObject > mWaterCollisionObject ;
std : : auto_ptr < btCollisionShape > mWaterCollisionShape ;
2015-05-02 22:39:01 +00:00
std : : auto_ptr < MWRender : : DebugDrawer > mDebugDrawer ;
osg : : ref_ptr < osg : : Group > mParentNode ;
2011-08-22 19:34:51 +00:00
PhysicsSystem ( const PhysicsSystem & ) ;
PhysicsSystem & operator = ( const PhysicsSystem & ) ;
2011-08-01 13:55:36 +00:00
} ;
}
# endif