2012-03-19 23:38:44 +00:00
# include "trace.h"
# include <map>
2013-02-08 21:12:34 +00:00
# include <btBulletDynamicsCommon.h>
# include <btBulletCollisionCommon.h>
2013-02-07 05:47:09 +00:00
# include "physic.hpp"
2012-03-19 23:38:44 +00:00
2013-04-30 18:26:59 +00:00
void newtrace ( traceResults * results , const Ogre : : Quaternion & orient , const Ogre : : Vector3 & start , const Ogre : : Vector3 & end , const Ogre : : Vector3 & BBHalfExtents , bool isInterior , OEngine : : Physic : : PhysicEngine * enginePass ) //Traceobj was a Aedra Object
2012-03-19 23:38:44 +00:00
{
2013-02-08 21:12:34 +00:00
const btVector3 btstart ( start . x , start . y , start . z + BBHalfExtents . z ) ;
const btVector3 btend ( end . x , end . y , end . z + BBHalfExtents . z ) ;
2013-04-30 18:26:59 +00:00
const btQuaternion btorient ( orient . x , orient . y , orient . z , orient . w ) ;
2012-03-19 23:38:44 +00:00
2012-08-14 22:04:58 +00:00
const btBoxShape newshape ( btVector3 ( BBHalfExtents . x , BBHalfExtents . y , BBHalfExtents . z ) ) ;
2013-02-08 21:12:34 +00:00
//const btCapsuleShapeZ newshape(BBHalfExtents.x, BBHalfExtents.z * 2 - BBHalfExtents.x * 2);
2013-04-30 18:26:59 +00:00
const btTransform from ( btorient , btstart ) ;
const btTransform to ( btorient , btend ) ;
2013-02-08 21:12:34 +00:00
btCollisionWorld : : ClosestConvexResultCallback newTraceCallback ( btstart , btend ) ;
2013-05-09 10:12:55 +00:00
newTraceCallback . m_collisionFilterMask = OEngine : : Physic : : CollisionType_World | OEngine : : Physic : : CollisionType_HeightMap | OEngine : : Physic : : CollisionType_Actor ;
2013-02-08 21:12:34 +00:00
enginePass - > dynamicsWorld - > convexSweepTest ( & newshape , from , to , newTraceCallback ) ;
// Copy the hit data over to our trace results struct:
2013-02-20 12:14:52 +00:00
if ( newTraceCallback . hasHit ( ) )
2013-02-08 21:12:34 +00:00
{
2013-02-20 12:14:52 +00:00
const btVector3 & tracehitnormal = newTraceCallback . m_hitNormalWorld ;
results - > fraction = newTraceCallback . m_closestHitFraction ;
results - > planenormal = Ogre : : Vector3 ( tracehitnormal . x ( ) , tracehitnormal . y ( ) , tracehitnormal . z ( ) ) ;
results - > endpos = ( end - start ) * results - > fraction + start ;
2013-02-08 21:12:34 +00:00
}
else
{
2013-02-20 12:14:52 +00:00
results - > endpos = end ;
results - > planenormal = Ogre : : Vector3 ( 0.0f , 0.0f , 1.0f ) ;
results - > fraction = 1.0f ;
2013-02-08 21:12:34 +00:00
}
2012-03-19 23:38:44 +00:00
}
2013-08-17 09:51:19 +00:00
class ClosestNotMeConvexResultCallback : public btCollisionWorld : : ClosestConvexResultCallback
{
public :
ClosestNotMeConvexResultCallback ( btCollisionObject * me , const btVector3 & up , btScalar minSlopeDot )
: btCollisionWorld : : ClosestConvexResultCallback ( btVector3 ( 0.0 , 0.0 , 0.0 ) , btVector3 ( 0.0 , 0.0 , 0.0 ) ) ,
mMe ( me ) , mUp ( up ) , mMinSlopeDot ( minSlopeDot )
{
}
virtual btScalar addSingleResult ( btCollisionWorld : : LocalConvexResult & convexResult , bool normalInWorldSpace )
{
if ( convexResult . m_hitCollisionObject = = mMe )
return btScalar ( 1 ) ;
btVector3 hitNormalWorld ;
if ( normalInWorldSpace )
hitNormalWorld = convexResult . m_hitNormalLocal ;
else
{
///need to transform normal into worldspace
hitNormalWorld = m_hitCollisionObject - > getWorldTransform ( ) . getBasis ( ) * convexResult . m_hitNormalLocal ;
}
// NOTE : m_hitNormalLocal is not always vertical on the ground with a capsule or a box...
btScalar dotUp = mUp . dot ( hitNormalWorld ) ;
if ( dotUp < mMinSlopeDot )
return btScalar ( 1 ) ;
return ClosestConvexResultCallback : : addSingleResult ( convexResult , normalInWorldSpace ) ;
}
protected :
btCollisionObject * mMe ;
const btVector3 mUp ;
const btScalar mMinSlopeDot ;
} ;
void actortrace ( traceResults * results , btCollisionObject * actor , const Ogre : : Vector3 & start , const Ogre : : Vector3 & end , OEngine : : Physic : : PhysicEngine * enginePass )
{
const btVector3 btstart ( start . x , start . y , start . z ) ;
const btVector3 btend ( end . x , end . y , end . z ) ;
const btTransform & trans = actor - > getWorldTransform ( ) ;
btTransform from ( trans ) ;
btTransform to ( trans ) ;
from . setOrigin ( btstart ) ;
to . setOrigin ( btend ) ;
ClosestNotMeConvexResultCallback newTraceCallback ( actor , btstart - btend , btScalar ( 0.0 ) ) ;
newTraceCallback . m_collisionFilterMask = OEngine : : Physic : : CollisionType_World |
OEngine : : Physic : : CollisionType_HeightMap |
OEngine : : Physic : : CollisionType_Actor ;
btCollisionShape * shape = actor - > getCollisionShape ( ) ;
assert ( shape - > isConvex ( ) ) ;
enginePass - > dynamicsWorld - > convexSweepTest ( static_cast < btConvexShape * > ( shape ) ,
from , to , newTraceCallback ) ;
// Copy the hit data over to our trace results struct:
if ( newTraceCallback . hasHit ( ) )
{
const btVector3 & tracehitnormal = newTraceCallback . m_hitNormalWorld ;
results - > fraction = newTraceCallback . m_closestHitFraction ;
results - > planenormal = Ogre : : Vector3 ( tracehitnormal . x ( ) , tracehitnormal . y ( ) , tracehitnormal . z ( ) ) ;
results - > endpos = ( end - start ) * results - > fraction + start ;
}
else
{
results - > endpos = end ;
results - > planenormal = Ogre : : Vector3 ( 0.0f , 0.0f , 1.0f ) ;
results - > fraction = 1.0f ;
}
}