2012-07-03 10:30:50 +00:00
# include "physicssystem.hpp"
2011-10-29 07:50:11 +00:00
# include <stdexcept>
2012-07-03 10:30:50 +00:00
# include <OgreRoot.h>
# include <OgreRenderWindow.h>
# include <OgreSceneManager.h>
# include <OgreViewport.h>
# include <OgreCamera.h>
# include <OgreTextureManager.h>
2011-08-01 13:55:36 +00:00
2013-02-07 05:44:58 +00:00
# include <libs/openengine/bullet/trace.h>
# include <libs/openengine/bullet/physic.hpp>
2012-07-03 10:30:50 +00:00
# include <components/nifbullet/bullet_nif_loader.hpp>
2011-08-01 13:55:36 +00:00
2012-08-13 22:36:18 +00:00
//#include "../mwbase/world.hpp" // FIXME
2012-11-05 18:40:02 +00:00
# include "../mwbase/environment.hpp"
2011-08-01 13:55:36 +00:00
2012-07-03 10:30:50 +00:00
# include "ptr.hpp"
2012-07-24 14:52:08 +00:00
# include "class.hpp"
2012-03-20 00:03:48 +00:00
2011-10-20 22:15:30 +00:00
using namespace Ogre ;
2011-08-01 13:55:36 +00:00
namespace MWWorld
{
2013-02-05 23:07:48 +00:00
static const float sMaxSlope = 60.0f ;
2013-02-05 20:45:10 +00:00
class MovementSolver
{
private :
static bool stepMove ( Ogre : : Vector3 & position , const Ogre : : Vector3 & velocity , float remainingTime ,
float verticalRotation , const Ogre : : Vector3 & halfExtents , bool isInterior ,
OEngine : : Physic : : PhysicEngine * engine )
{
traceResults trace ; // no initialization needed
newtrace ( & trace , position + Ogre : : Vector3 ( 0.0f , 0.0f , STEPSIZE ) ,
position + Ogre : : Vector3 ( 0.0f , 0.0f , STEPSIZE ) + velocity * remainingTime ,
halfExtents , verticalRotation , isInterior , engine ) ;
if ( trace . fraction = = 0.0f | | ( trace . fraction ! = 1.0f & & getSlope ( trace . planenormal ) > sMaxSlope ) )
return false ;
newtrace ( & trace , trace . endpos , trace . endpos - Ogre : : Vector3 ( 0 , 0 , STEPSIZE ) , halfExtents , verticalRotation , isInterior , engine ) ;
if ( getSlope ( trace . planenormal ) < sMaxSlope )
{
// only step down onto semi-horizontal surfaces. don't step down onto the side of a house or a wall.
position = trace . endpos ;
return true ;
}
return false ;
}
static void clipVelocity ( const Ogre : : Vector3 & in , const Ogre : : Vector3 & normal , Ogre : : Vector3 & out ,
const float overbounce )
{
//Math stuff. Basically just project the velocity vector onto the plane represented by the normal.
//More specifically, it projects velocity onto the normal, takes that result, multiplies it by overbounce and then subtracts it from velocity.
float backoff ;
backoff = in . dotProduct ( normal ) ;
if ( backoff < 0.0f )
backoff * = overbounce ;
else
backoff / = overbounce ;
out = in - ( normal * backoff ) ;
}
static void projectVelocity ( Ogre : : Vector3 & velocity , const Ogre : : Vector3 & direction )
{
Ogre : : Vector3 normalizedDirection ( direction ) ;
normalizedDirection . normalise ( ) ;
// no divide by normalizedDirection.length necessary because it's normalized
velocity = normalizedDirection * velocity . dotProduct ( normalizedDirection ) ;
}
static float getSlope ( const Ogre : : Vector3 & normal )
{
return normal . angleBetween ( Ogre : : Vector3 ( 0.0f , 0.0f , 1.0f ) ) . valueDegrees ( ) ;
}
public :
2013-02-05 22:02:14 +00:00
static Ogre : : Vector3 move ( const MWWorld : : Ptr & ptr , Ogre : : Vector3 movement , float time ,
2013-02-06 03:45:51 +00:00
bool gravity , OEngine : : Physic : : PhysicEngine * engine )
2013-02-05 20:45:10 +00:00
{
2013-02-05 22:02:14 +00:00
const ESM : : Position & refpos = ptr . getRefData ( ) . getPosition ( ) ;
Ogre : : Vector3 position ( refpos . pos ) ;
2013-02-05 20:45:10 +00:00
/* Anything to collide with? */
OEngine : : Physic : : PhysicActor * physicActor = engine - > getCharacter ( ptr . getRefData ( ) . getHandle ( ) ) ;
if ( ! physicActor | | ! physicActor - > getCollisionMode ( ) )
2013-02-06 20:39:26 +00:00
{
// FIXME: This works, but it's inconcsistent with how the rotations are applied elsewhere. Why?
return position + ( Ogre : : Quaternion ( Ogre : : Radian ( - refpos . rot [ 2 ] ) , Ogre : : Vector3 : : UNIT_Z ) *
Ogre : : Quaternion ( Ogre : : Radian ( refpos . rot [ 1 ] ) , Ogre : : Vector3 : : UNIT_Y ) *
Ogre : : Quaternion ( Ogre : : Radian ( refpos . rot [ 0 ] ) , Ogre : : Vector3 : : UNIT_X ) ) *
movement ;
}
2013-02-05 20:45:10 +00:00
traceResults trace ; //no initialization needed
int iterations = 0 , maxIterations = 50 ; //arbitrary number. To prevent infinite loops. They shouldn't happen but it's good to be prepared.
2013-02-06 20:39:26 +00:00
if ( ! gravity )
{
movement = ( Ogre : : Quaternion ( Ogre : : Radian ( - refpos . rot [ 2 ] ) , Ogre : : Vector3 : : UNIT_Z ) *
Ogre : : Quaternion ( Ogre : : Radian ( refpos . rot [ 1 ] ) , Ogre : : Vector3 : : UNIT_Y ) *
Ogre : : Quaternion ( Ogre : : Radian ( refpos . rot [ 0 ] ) , Ogre : : Vector3 : : UNIT_X ) ) *
movement ;
}
else
{
movement = Ogre : : Quaternion ( Ogre : : Radian ( - refpos . rot [ 2 ] ) , Ogre : : Vector3 : : UNIT_Z ) *
movement ;
}
2013-02-05 20:45:10 +00:00
Ogre : : Vector3 horizontalVelocity = movement / time ;
2013-02-06 03:45:51 +00:00
float verticalVelocity = ( gravity ? physicActor - > getVerticalForce ( ) :
horizontalVelocity . z ) ;
2013-02-05 20:45:10 +00:00
Ogre : : Vector3 velocity ( horizontalVelocity . x , horizontalVelocity . y , verticalVelocity ) ; // we need a copy of the velocity before we start clipping it for steps
Ogre : : Vector3 clippedVelocity ( horizontalVelocity . x , horizontalVelocity . y , verticalVelocity ) ;
float remainingTime = time ;
bool isInterior = ! ptr . getCell ( ) - > isExterior ( ) ;
float verticalRotation = physicActor - > getRotation ( ) . getYaw ( ) . valueDegrees ( ) ;
Ogre : : Vector3 halfExtents = physicActor - > getHalfExtents ( ) ;
Ogre : : Vector3 lastNormal ( 0.0f ) ;
Ogre : : Vector3 currentNormal ( 0.0f ) ;
Ogre : : Vector3 up ( 0.0f , 0.0f , 1.0f ) ;
Ogre : : Vector3 newPosition = position ;
2013-02-07 05:44:58 +00:00
bool onground = false ;
2013-02-06 03:45:51 +00:00
if ( gravity )
2013-02-05 20:45:10 +00:00
{
2013-02-06 03:45:51 +00:00
newtrace ( & trace , position , position + Ogre : : Vector3 ( 0 , 0 , - 10 ) , halfExtents , verticalRotation , isInterior , engine ) ;
if ( trace . fraction < 1.0f )
2013-02-05 20:45:10 +00:00
{
2013-02-06 03:45:51 +00:00
if ( getSlope ( trace . planenormal ) > sMaxSlope )
{
// if we're on a really steep slope, don't listen to user input
clippedVelocity . x = clippedVelocity . y = 0.0f ;
}
else
{
// if we're within 10 units of the ground, force velocity to track the ground
clipVelocity ( clippedVelocity , trace . planenormal , clippedVelocity , 1.0f ) ;
}
2013-02-05 20:45:10 +00:00
}
}
do {
// trace to where character would go if there were no obstructions
newtrace ( & trace , newPosition , newPosition + clippedVelocity * remainingTime , halfExtents , verticalRotation , isInterior , engine ) ;
newPosition = trace . endpos ;
currentNormal = trace . planenormal ;
remainingTime = remainingTime * ( 1.0f - trace . fraction ) ;
// check for obstructions
2013-02-07 05:44:58 +00:00
if ( trace . fraction < 1.0f )
2013-02-05 20:45:10 +00:00
{
//std::cout<<"angle: "<<getSlope(trace.planenormal)<<"\n";
2013-02-07 05:44:58 +00:00
onground = getSlope ( currentNormal ) < = sMaxSlope ;
if ( ! onground | | currentNormal = = lastNormal )
2013-02-05 20:45:10 +00:00
{
2013-02-05 23:51:26 +00:00
if ( ! stepMove ( newPosition , velocity , remainingTime , verticalRotation , halfExtents , isInterior , engine ) )
2013-02-05 20:45:10 +00:00
{
Ogre : : Vector3 resultantDirection = currentNormal . crossProduct ( up ) ;
resultantDirection . normalise ( ) ;
clippedVelocity = velocity ;
projectVelocity ( clippedVelocity , resultantDirection ) ;
// just this isn't enough sometimes. It's the same problem that causes steps to be necessary on even uphill terrain.
clippedVelocity + = currentNormal * clippedVelocity . length ( ) / 50.0f ;
2013-02-05 23:51:26 +00:00
//std::cout<< "clipped velocity: "<<clippedVelocity <<std::endl;
2013-02-05 20:45:10 +00:00
}
2013-02-05 23:51:26 +00:00
//else
// std::cout<< "stepped" <<std::endl;
2013-02-05 20:45:10 +00:00
}
else
clipVelocity ( clippedVelocity , currentNormal , clippedVelocity , 1.0f ) ;
}
lastNormal = currentNormal ;
iterations + + ;
} while ( iterations < maxIterations & & remainingTime ! = 0.0f ) ;
verticalVelocity = clippedVelocity . z ;
2013-02-07 05:44:58 +00:00
physicActor - > setVerticalForce ( verticalVelocity - time * 400.0f ) ;
physicActor - > setOnGround ( onground ) ;
2013-02-05 20:45:10 +00:00
return newPosition ;
}
} ;
2012-01-29 15:31:18 +00:00
PhysicsSystem : : PhysicsSystem ( OEngine : : Render : : OgreRenderer & _rend ) :
mRender ( _rend ) , mEngine ( 0 ) , mFreeFly ( true )
2011-08-01 13:55:36 +00:00
{
2012-04-30 21:55:22 +00:00
2012-04-17 22:12:05 +00:00
playerphysics = new playerMove ;
2012-01-29 15:31:18 +00:00
// Create physics. shapeLoader is deleted by the physic engine
NifBullet : : ManualBulletShapeLoader * shapeLoader = new NifBullet : : ManualBulletShapeLoader ( ) ;
mEngine = new OEngine : : Physic : : PhysicEngine ( shapeLoader ) ;
2012-04-17 22:12:05 +00:00
playerphysics - > mEngine = mEngine ;
2011-08-01 13:55:36 +00:00
}
2011-08-22 19:34:51 +00:00
2011-08-01 13:55:36 +00:00
PhysicsSystem : : ~ PhysicsSystem ( )
{
2012-01-29 15:31:18 +00:00
delete mEngine ;
2012-06-06 18:29:30 +00:00
delete playerphysics ;
2012-04-30 21:55:22 +00:00
2012-01-29 15:31:18 +00:00
}
OEngine : : Physic : : PhysicEngine * PhysicsSystem : : getEngine ( )
{
return mEngine ;
2011-08-01 13:55:36 +00:00
}
2012-04-30 21:55:22 +00:00
2013-01-08 07:00:00 +00:00
std : : pair < float , std : : string > PhysicsSystem : : getFacedHandle ( MWWorld : : World & world , float queryDistance )
2012-08-17 06:10:37 +00:00
{
2012-08-17 11:07:12 +00:00
btVector3 dir ( 0 , 1 , 0 ) ;
dir = dir . rotate ( btVector3 ( 1 , 0 , 0 ) , mPlayerData . pitch ) ;
dir = dir . rotate ( btVector3 ( 0 , 0 , 1 ) , mPlayerData . yaw ) ;
dir . setX ( - dir . x ( ) ) ;
btVector3 origin (
mPlayerData . eyepos . x ,
mPlayerData . eyepos . y ,
mPlayerData . eyepos . z ) ;
origin + = dir * 5 ;
2013-01-08 07:00:00 +00:00
btVector3 dest = origin + dir * queryDistance ;
std : : pair < std : : string , float > result ;
/*auto*/ result = mEngine - > rayTest ( origin , dest ) ;
result . second * = queryDistance ;
return std : : make_pair ( result . second , result . first ) ;
2011-10-20 22:15:30 +00:00
}
2012-03-25 18:52:56 +00:00
2013-01-08 07:00:00 +00:00
std : : vector < std : : pair < float , std : : string > > PhysicsSystem : : getFacedHandles ( float queryDistance )
2012-03-25 18:52:56 +00:00
{
2012-08-17 11:07:12 +00:00
btVector3 dir ( 0 , 1 , 0 ) ;
dir = dir . rotate ( btVector3 ( 1 , 0 , 0 ) , mPlayerData . pitch ) ;
dir = dir . rotate ( btVector3 ( 0 , 0 , 1 ) , mPlayerData . yaw ) ;
dir . setX ( - dir . x ( ) ) ;
btVector3 origin (
mPlayerData . eyepos . x ,
mPlayerData . eyepos . y ,
mPlayerData . eyepos . z ) ;
origin + = dir * 5 ;
2013-01-08 07:00:00 +00:00
btVector3 dest = origin + dir * queryDistance ;
std : : vector < std : : pair < float , std : : string > > results ;
/* auto */ results = mEngine - > rayTest2 ( origin , dest ) ;
std : : vector < std : : pair < float , std : : string > > : : iterator i ;
for ( /* auto */ i = results . begin ( ) ; i ! = results . end ( ) ; + + i )
i - > first * = queryDistance ;
return results ;
2012-03-25 18:52:56 +00:00
}
2012-06-02 10:25:24 +00:00
2013-01-08 07:00:00 +00:00
std : : vector < std : : pair < float , std : : string > > PhysicsSystem : : getFacedHandles ( float mouseX , float mouseY , float queryDistance )
2012-06-02 10:25:24 +00:00
{
Ray ray = mRender . getCamera ( ) - > getCameraToViewportRay ( mouseX , mouseY ) ;
Ogre : : Vector3 from = ray . getOrigin ( ) ;
2013-01-08 07:00:00 +00:00
Ogre : : Vector3 to = ray . getPoint ( queryDistance ) ;
2012-06-02 10:25:24 +00:00
btVector3 _from , _to ;
// OGRE to MW coordinates
_from = btVector3 ( from . x , - from . z , from . y ) ;
_to = btVector3 ( to . x , - to . z , to . y ) ;
2013-01-08 07:00:00 +00:00
std : : vector < std : : pair < float , std : : string > > results ;
/* auto */ results = mEngine - > rayTest2 ( _from , _to ) ;
std : : vector < std : : pair < float , std : : string > > : : iterator i ;
for ( /* auto */ i = results . begin ( ) ; i ! = results . end ( ) ; + + i )
i - > first * = queryDistance ;
return results ;
2012-06-02 10:25:24 +00:00
}
void PhysicsSystem : : setCurrentWater ( bool hasWater , int waterHeight )
{
2012-04-18 04:13:38 +00:00
playerphysics - > hasWater = hasWater ;
if ( hasWater ) {
playerphysics - > waterHeight = waterHeight ;
}
2012-09-16 02:48:24 +00:00
for ( std : : map < std : : string , OEngine : : Physic : : PhysicActor * > : : iterator it = mEngine - > PhysicActorMap . begin ( ) ; it ! = mEngine - > PhysicActorMap . end ( ) ; it + + )
{
it - > second - > setCurrentWater ( hasWater , waterHeight ) ;
}
2012-04-30 21:55:22 +00:00
2012-04-18 04:13:38 +00:00
}
2012-03-25 18:52:56 +00:00
btVector3 PhysicsSystem : : getRayPoint ( float extent )
{
//get a ray pointing to the center of the viewport
Ray centerRay = mRender . getCamera ( ) - > getCameraToViewportRay (
mRender . getViewport ( ) - > getWidth ( ) / 2 ,
mRender . getViewport ( ) - > getHeight ( ) / 2 ) ;
2013-01-08 07:00:00 +00:00
btVector3 result ( centerRay . getPoint ( extent ) . x , - centerRay . getPoint ( extent ) . z , centerRay . getPoint ( extent ) . y ) ;
2012-03-27 20:36:02 +00:00
return result ;
2012-03-25 18:52:56 +00:00
}
2012-04-30 21:55:22 +00:00
2012-06-02 10:25:24 +00:00
btVector3 PhysicsSystem : : getRayPoint ( float extent , float mouseX , float mouseY )
{
//get a ray pointing to the center of the viewport
Ray centerRay = mRender . getCamera ( ) - > getCameraToViewportRay ( mouseX , mouseY ) ;
2013-01-08 07:00:00 +00:00
btVector3 result ( centerRay . getPoint ( extent ) . x , - centerRay . getPoint ( extent ) . z , centerRay . getPoint ( extent ) . y ) ;
2012-06-02 10:25:24 +00:00
return result ;
}
2012-02-24 15:12:43 +00:00
bool PhysicsSystem : : castRay ( const Vector3 & from , const Vector3 & to )
{
btVector3 _from , _to ;
_from = btVector3 ( from . x , from . y , from . z ) ;
_to = btVector3 ( to . x , to . y , to . z ) ;
2012-04-30 21:55:22 +00:00
2012-02-24 15:12:43 +00:00
std : : pair < std : : string , float > result = mEngine - > rayTest ( _from , _to ) ;
2012-04-30 21:55:22 +00:00
2012-02-24 15:12:43 +00:00
return ! ( result . first = = " " ) ;
}
2011-10-20 22:15:30 +00:00
2012-07-25 16:25:53 +00:00
std : : pair < bool , Ogre : : Vector3 >
PhysicsSystem : : castRay ( const Ogre : : Vector3 & orig , const Ogre : : Vector3 & dir , float len )
{
Ogre : : Ray ray = Ogre : : Ray ( orig , dir ) ;
Ogre : : Vector3 to = ray . getPoint ( len ) ;
btVector3 btFrom = btVector3 ( orig . x , orig . y , orig . z ) ;
btVector3 btTo = btVector3 ( to . x , to . y , to . z ) ;
std : : pair < std : : string , float > test = mEngine - > rayTest ( btFrom , btTo ) ;
if ( test . first = = " " ) {
return std : : make_pair ( false , Ogre : : Vector3 ( ) ) ;
}
return std : : make_pair ( true , ray . getPoint ( len * test . second ) ) ;
}
2012-05-15 14:47:23 +00:00
std : : pair < bool , Ogre : : Vector3 > PhysicsSystem : : castRay ( float mouseX , float mouseY )
{
Ogre : : Ray ray = mRender . getCamera ( ) - > getCameraToViewportRay (
mouseX ,
mouseY ) ;
Ogre : : Vector3 from = ray . getOrigin ( ) ;
Ogre : : Vector3 to = ray . getPoint ( 200 ) ; /// \todo make this distance (ray length) configurable
btVector3 _from , _to ;
// OGRE to MW coordinates
_from = btVector3 ( from . x , - from . z , from . y ) ;
_to = btVector3 ( to . x , - to . z , to . y ) ;
std : : pair < std : : string , float > result = mEngine - > rayTest ( _from , _to ) ;
if ( result . first = = " " )
return std : : make_pair ( false , Ogre : : Vector3 ( ) ) ;
else
{
return std : : make_pair ( true , ray . getPoint ( 200 * result . second ) ) ; /// \todo make this distance (ray length) configurable
}
}
2013-02-06 03:45:51 +00:00
Ogre : : Vector3 PhysicsSystem : : move ( const MWWorld : : Ptr & ptr , const Ogre : : Vector3 & movement , float time , bool gravity )
2013-02-05 20:45:10 +00:00
{
2013-02-06 03:45:51 +00:00
return MovementSolver : : move ( ptr , movement , time , gravity , mEngine ) ;
2013-02-05 20:45:10 +00:00
}
2011-08-01 13:55:36 +00:00
2012-03-13 16:09:50 +00:00
void PhysicsSystem : : addHeightField ( float * heights ,
int x , int y , float yoffset ,
float triSize , float sqrtVerts )
{
mEngine - > addHeightField ( heights , x , y , yoffset , triSize , sqrtVerts ) ;
}
void PhysicsSystem : : removeHeightField ( int x , int y )
{
mEngine - > removeHeightField ( x , y ) ;
}
2012-11-05 18:40:02 +00:00
void PhysicsSystem : : addObject ( const Ptr & ptr )
2011-08-01 13:55:36 +00:00
{
2012-11-05 18:40:02 +00:00
std : : string mesh = MWWorld : : Class : : get ( ptr ) . getModel ( ptr ) ;
Ogre : : SceneNode * node = ptr . getRefData ( ) . getBaseNode ( ) ;
handleToMesh [ node - > getName ( ) ] = mesh ;
OEngine : : Physic : : RigidBody * body = mEngine - > createAndAdjustRigidBody ( mesh , node - > getName ( ) , node - > getScale ( ) . x , node - > getPosition ( ) , node - > getOrientation ( ) ) ;
2011-08-01 13:55:36 +00:00
mEngine - > addRigidBody ( body ) ;
}
2012-11-05 18:40:02 +00:00
void PhysicsSystem : : addActor ( const Ptr & ptr )
2011-08-01 13:55:36 +00:00
{
2012-11-05 18:40:02 +00:00
std : : string mesh = MWWorld : : Class : : get ( ptr ) . getModel ( ptr ) ;
Ogre : : SceneNode * node = ptr . getRefData ( ) . getBaseNode ( ) ;
2011-08-01 13:55:36 +00:00
//TODO:optimize this. Searching the std::map isn't very efficient i think.
2012-11-05 18:40:02 +00:00
mEngine - > addCharacter ( node - > getName ( ) , mesh , node - > getPosition ( ) , node - > getScale ( ) . x , node - > getOrientation ( ) ) ;
2011-08-01 13:55:36 +00:00
}
void PhysicsSystem : : removeObject ( const std : : string & handle )
{
//TODO:check if actor???
2012-11-05 18:40:02 +00:00
2011-08-01 13:55:36 +00:00
mEngine - > removeCharacter ( handle ) ;
mEngine - > removeRigidBody ( handle ) ;
mEngine - > deleteRigidBody ( handle ) ;
}
2012-11-05 18:40:02 +00:00
void PhysicsSystem : : moveObject ( const Ptr & ptr )
2011-08-01 13:55:36 +00:00
{
2012-11-05 18:40:02 +00:00
Ogre : : SceneNode * node = ptr . getRefData ( ) . getBaseNode ( ) ;
std : : string handle = node - > getName ( ) ;
2012-09-04 00:32:20 +00:00
Ogre : : Vector3 position = node - > getPosition ( ) ;
2011-09-04 07:48:50 +00:00
if ( OEngine : : Physic : : RigidBody * body = mEngine - > getRigidBody ( handle ) )
2011-08-01 13:55:36 +00:00
{
2011-09-04 07:48:50 +00:00
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
// start positions others than 0, 0, 0
2012-09-04 00:32:20 +00:00
2012-08-15 00:29:48 +00:00
if ( dynamic_cast < btBoxShape * > ( body - > getCollisionShape ( ) ) = = NULL ) {
btTransform tr = body - > getWorldTransform ( ) ;
tr . setOrigin ( btVector3 ( position . x , position . y , position . z ) ) ;
body - > setWorldTransform ( tr ) ;
}
2012-09-15 20:45:50 +00:00
else {
//For objects that contain a box shape.
//Do any such objects exist? Perhaps animated objects?
2012-08-15 00:29:48 +00:00
mEngine - > boxAdjustExternal ( handleToMesh [ handle ] , body , node - > getScale ( ) . x , position , node - > getOrientation ( ) ) ;
2012-09-15 20:45:50 +00:00
}
2011-09-04 07:48:50 +00:00
}
if ( OEngine : : Physic : : PhysicActor * act = mEngine - > getCharacter ( handle ) )
{
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
// start positions others than 0, 0, 0
2012-04-30 21:55:22 +00:00
if ( handle = = " player " )
{
playerphysics - > ps . origin = position ;
}
else
{
2012-09-15 20:45:50 +00:00
act - > setPosition ( position ) ;
2012-04-30 21:55:22 +00:00
}
2011-08-01 13:55:36 +00:00
}
}
2012-11-05 18:40:02 +00:00
void PhysicsSystem : : rotateObject ( const Ptr & ptr )
2011-08-01 13:55:36 +00:00
{
2012-11-05 18:40:02 +00:00
Ogre : : SceneNode * node = ptr . getRefData ( ) . getBaseNode ( ) ;
std : : string handle = node - > getName ( ) ;
2012-09-04 00:32:20 +00:00
Ogre : : Quaternion rotation = node - > getOrientation ( ) ;
2012-07-10 10:10:50 +00:00
if ( OEngine : : Physic : : PhysicActor * act = mEngine - > getCharacter ( handle ) )
2012-01-05 00:47:06 +00:00
{
2012-09-04 00:32:20 +00:00
//Needs to be changed
2012-09-15 17:23:49 +00:00
act - > setRotation ( rotation ) ;
2012-01-05 00:47:06 +00:00
}
2012-07-10 10:10:50 +00:00
if ( OEngine : : Physic : : RigidBody * body = mEngine - > getRigidBody ( handle ) )
{
2012-08-15 00:29:48 +00:00
if ( dynamic_cast < btBoxShape * > ( body - > getCollisionShape ( ) ) = = NULL )
body - > getWorldTransform ( ) . setRotation ( btQuaternion ( rotation . x , rotation . y , rotation . z , rotation . w ) ) ;
else
mEngine - > boxAdjustExternal ( handleToMesh [ handle ] , body , node - > getScale ( ) . x , node - > getPosition ( ) , rotation ) ;
2012-07-10 10:10:50 +00:00
}
2011-08-01 13:55:36 +00:00
}
2012-11-05 18:40:02 +00:00
void PhysicsSystem : : scaleObject ( const Ptr & ptr )
2011-08-01 13:55:36 +00:00
{
2012-11-05 18:40:02 +00:00
Ogre : : SceneNode * node = ptr . getRefData ( ) . getBaseNode ( ) ;
std : : string handle = node - > getName ( ) ;
2012-06-18 17:03:00 +00:00
if ( handleToMesh . find ( handle ) ! = handleToMesh . end ( ) )
{
removeObject ( handle ) ;
2012-11-05 18:40:02 +00:00
addObject ( ptr ) ;
2012-06-20 17:14:27 +00:00
}
2012-09-12 22:30:32 +00:00
if ( OEngine : : Physic : : PhysicActor * act = mEngine - > getCharacter ( handle ) )
2012-11-05 18:40:02 +00:00
act - > setScale ( node - > getScale ( ) . x ) ;
2011-08-01 13:55:36 +00:00
}
bool PhysicsSystem : : toggleCollisionMode ( )
{
2012-11-02 20:43:07 +00:00
playerphysics - > ps . move_type = ( playerphysics - > ps . move_type = = PM_NOCLIP ? PM_NORMAL : PM_NOCLIP ) ;
2011-08-01 13:55:36 +00:00
for ( std : : map < std : : string , OEngine : : Physic : : PhysicActor * > : : iterator it = mEngine - > PhysicActorMap . begin ( ) ; it ! = mEngine - > PhysicActorMap . end ( ) ; it + + )
{
2011-10-29 07:50:11 +00:00
if ( it - > first = = " player " )
2011-08-01 13:55:36 +00:00
{
2011-10-29 07:50:11 +00:00
OEngine : : Physic : : PhysicActor * act = it - > second ;
bool cmode = act - > getCollisionMode ( ) ;
if ( cmode )
{
act - > enableCollisions ( false ) ;
mFreeFly = true ;
return false ;
}
else
{
mFreeFly = false ;
act - > enableCollisions ( true ) ;
return true ;
}
2011-08-01 13:55:36 +00:00
}
}
2011-10-29 07:50:11 +00:00
throw std : : logic_error ( " can't find player " ) ;
2011-08-01 13:55:36 +00:00
}
2012-07-26 12:14:11 +00:00
bool PhysicsSystem : : getObjectAABB ( const MWWorld : : Ptr & ptr , Ogre : : Vector3 & min , Ogre : : Vector3 & max )
2012-07-24 18:08:23 +00:00
{
2012-07-24 16:22:11 +00:00
std : : string model = MWWorld : : Class : : get ( ptr ) . getModel ( ptr ) ;
2012-07-24 14:52:08 +00:00
if ( model . empty ( ) ) {
2012-07-25 14:58:55 +00:00
return false ;
2012-07-24 14:52:08 +00:00
}
2012-07-26 12:14:11 +00:00
btVector3 btMin , btMax ;
2012-09-17 07:37:50 +00:00
float scale = ptr . getCellRef ( ) . mScale ;
2012-07-26 12:14:11 +00:00
mEngine - > getObjectAABB ( model , scale , btMin , btMax ) ;
min . x = btMin . x ( ) ;
min . y = btMin . y ( ) ;
min . z = btMin . z ( ) ;
max . x = btMax . x ( ) ;
max . y = btMax . y ( ) ;
max . z = btMax . z ( ) ;
2012-07-25 14:58:55 +00:00
return true ;
2012-07-24 18:08:23 +00:00
}
2012-08-17 06:10:37 +00:00
void PhysicsSystem : : updatePlayerData ( Ogre : : Vector3 & eyepos , float pitch , float yaw )
{
mPlayerData . eyepos = eyepos ;
mPlayerData . pitch = pitch ;
mPlayerData . yaw = yaw ;
}
2011-08-01 13:55:36 +00:00
}