1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-06 15:45:32 +00:00

Clean up the trace struct

This commit is contained in:
Chris Robinson 2013-08-17 04:42:35 -07:00
parent 62c7b3698d
commit 8bcce0fb55
3 changed files with 59 additions and 49 deletions

View file

@ -45,21 +45,22 @@ namespace MWWorld
const Ogre::Vector3 &velocity, float &remainingTime, const Ogre::Vector3 &velocity, float &remainingTime,
OEngine::Physic::PhysicEngine *engine) OEngine::Physic::PhysicEngine *engine)
{ {
traceResults trace; OEngine::Physic::ActorTracer tracer;
actortrace(&trace, colobj, position, position+Ogre::Vector3(0.0f,0.0f,sStepSize), engine); tracer.doTrace(colobj, position, position+Ogre::Vector3(0.0f,0.0f,sStepSize), engine);
if(trace.fraction == 0.0f) if(tracer.mFraction == 0.0f)
return false; return false;
actortrace(&trace, colobj, trace.endpos, trace.endpos + velocity*remainingTime, engine); tracer.doTrace(colobj, tracer.mEndPos, tracer.mEndPos + velocity*remainingTime, engine);
if(trace.fraction == 0.0f || (trace.fraction != 1.0f && getSlope(trace.planenormal) > sMaxSlope)) if(tracer.mFraction < std::numeric_limits<float>::epsilon() ||
(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) > sMaxSlope))
return false; return false;
float movefrac = trace.fraction; float movefrac = tracer.mFraction;
actortrace(&trace, colobj, trace.endpos, trace.endpos-Ogre::Vector3(0.0f,0.0f,sStepSize), engine); tracer.doTrace(colobj, tracer.mEndPos, tracer.mEndPos-Ogre::Vector3(0.0f,0.0f,sStepSize), engine);
if(getSlope(trace.planenormal) <= sMaxSlope) if(getSlope(tracer.mPlaneNormal) <= sMaxSlope)
{ {
// only step down onto semi-horizontal surfaces. don't step down onto the side of a house or a wall. // only step down onto semi-horizontal surfaces. don't step down onto the side of a house or a wall.
position = trace.endpos; position = tracer.mEndPos;
remainingTime *= (1.0f-movefrac); remainingTime *= (1.0f-movefrac);
return true; return true;
} }
@ -94,16 +95,16 @@ namespace MWWorld
const int maxHeight = 64.f; const int maxHeight = 64.f;
Ogre::Vector3 newPosition = position+Ogre::Vector3(0.0f, 0.0f, 4.0f); Ogre::Vector3 newPosition = position+Ogre::Vector3(0.0f, 0.0f, 4.0f);
traceResults trace; OEngine::Physic::ActorTracer tracer;
actortrace(&trace, physicActor->getCollisionBody(), newPosition, newPosition-Ogre::Vector3(0,0,maxHeight), engine); tracer.doTrace(physicActor->getCollisionBody(), newPosition, newPosition-Ogre::Vector3(0,0,maxHeight), engine);
if(trace.fraction >= 1.0f) if(tracer.mFraction >= 1.0f)
return position; return position;
physicActor->setOnGround(getSlope(trace.planenormal) <= sMaxSlope); physicActor->setOnGround(getSlope(tracer.mPlaneNormal) <= sMaxSlope);
newPosition = trace.endpos; newPosition = tracer.mEndPos;
newPosition.z -= physicActor->getHalfExtents().z; newPosition.z -= physicActor->getHalfExtents().z;
newPosition.z += 4.0f; newPosition.z += 2.0f;
return newPosition; return newPosition;
} }
@ -129,7 +130,7 @@ namespace MWWorld
Ogre::Vector3 halfExtents = physicActor->getHalfExtents(); Ogre::Vector3 halfExtents = physicActor->getHalfExtents();
position.z += halfExtents.z; position.z += halfExtents.z;
traceResults trace; OEngine::Physic::ActorTracer tracer;
bool onground = false; bool onground = false;
const Ogre::Quaternion orient; // Don't rotate actor collision boxes const Ogre::Quaternion orient; // Don't rotate actor collision boxes
Ogre::Vector3 velocity; Ogre::Vector3 velocity;
@ -144,8 +145,8 @@ namespace MWWorld
{ {
if(!(movement.z > 0.0f)) if(!(movement.z > 0.0f))
{ {
actortrace(&trace, colobj, position, position-Ogre::Vector3(0,0,4), engine); tracer.doTrace(colobj, position, position-Ogre::Vector3(0,0,4), engine);
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope) if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
onground = true; onground = true;
} }
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*movement / time; velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*movement / time;
@ -164,13 +165,13 @@ namespace MWWorld
for(int iterations = 0;iterations < sMaxIterations && remainingTime > 0.01f;++iterations) for(int iterations = 0;iterations < sMaxIterations && remainingTime > 0.01f;++iterations)
{ {
// trace to where character would go if there were no obstructions // trace to where character would go if there were no obstructions
actortrace(&trace, colobj, newPosition, newPosition+velocity*remainingTime, engine); tracer.doTrace(colobj, newPosition, newPosition+velocity*remainingTime, engine);
// check for obstructions // check for obstructions
if(trace.fraction >= 1.0f) if(tracer.mFraction >= 1.0f)
{ {
newPosition = trace.endpos; newPosition = tracer.mEndPos;
remainingTime *= (1.0f-trace.fraction); remainingTime *= (1.0f-tracer.mFraction);
break; break;
} }
@ -182,9 +183,9 @@ namespace MWWorld
{ {
// Can't move this way, try to find another spot along the plane // Can't move this way, try to find another spot along the plane
Ogre::Real movelen = velocity.normalise(); Ogre::Real movelen = velocity.normalise();
Ogre::Vector3 reflectdir = velocity.reflect(trace.planenormal); Ogre::Vector3 reflectdir = velocity.reflect(tracer.mPlaneNormal);
reflectdir.normalise(); reflectdir.normalise();
velocity = slide(reflectdir, trace.planenormal)*movelen; velocity = slide(reflectdir, tracer.mPlaneNormal)*movelen;
// Do not allow sliding upward if there is gravity. Stepping will have taken // Do not allow sliding upward if there is gravity. Stepping will have taken
// care of that. // care of that.
@ -195,9 +196,9 @@ namespace MWWorld
if(onground) if(onground)
{ {
actortrace(&trace, colobj, newPosition, newPosition-Ogre::Vector3(0,0,sStepSize+4.0f), engine); tracer.doTrace(colobj, newPosition, newPosition-Ogre::Vector3(0,0,sStepSize+4.0f), engine);
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope) if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
newPosition.z = trace.endpos.z + 2.0f; newPosition.z = tracer.mEndPos.z + 2.0f;
else else
onground = false; onground = false;
} }

View file

@ -9,6 +9,11 @@
#include "physic.hpp" #include "physic.hpp"
namespace OEngine
{
namespace Physic
{
class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback class ClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
{ {
public: public:
@ -47,7 +52,8 @@ protected:
const btScalar mMinSlopeDot; const btScalar mMinSlopeDot;
}; };
void actortrace(traceResults *results, btCollisionObject *actor, const Ogre::Vector3 &start, const Ogre::Vector3 &end, OEngine::Physic::PhysicEngine *enginePass)
void ActorTracer::doTrace(btCollisionObject *actor, const Ogre::Vector3 &start, const Ogre::Vector3 &end, const PhysicEngine *enginePass)
{ {
const btVector3 btstart(start.x, start.y, start.z); const btVector3 btstart(start.x, start.y, start.z);
const btVector3 btend(end.x, end.y, end.z); const btVector3 btend(end.x, end.y, end.z);
@ -72,14 +78,17 @@ void actortrace(traceResults *results, btCollisionObject *actor, const Ogre::Vec
if(newTraceCallback.hasHit()) if(newTraceCallback.hasHit())
{ {
const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld; const btVector3& tracehitnormal = newTraceCallback.m_hitNormalWorld;
results->fraction = newTraceCallback.m_closestHitFraction; mFraction = newTraceCallback.m_closestHitFraction;
results->planenormal = Ogre::Vector3(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z()); mPlaneNormal = Ogre::Vector3(tracehitnormal.x(), tracehitnormal.y(), tracehitnormal.z());
results->endpos = (end-start)*results->fraction + start; mEndPos = (end-start)*mFraction + start;
} }
else else
{ {
results->endpos = end; mEndPos = end;
results->planenormal = Ogre::Vector3(0.0f, 0.0f, 1.0f); mPlaneNormal = Ogre::Vector3(0.0f, 0.0f, 1.0f);
results->fraction = 1.0f; mFraction = 1.0f;
} }
} }
}
}

View file

@ -4,26 +4,26 @@
#include <OgreVector3.h> #include <OgreVector3.h>
namespace OEngine
{
namespace Physic
{
class PhysicEngine;
}
}
class btCollisionObject; class btCollisionObject;
struct traceResults namespace OEngine
{ {
Ogre::Vector3 endpos; namespace Physic
Ogre::Vector3 planenormal; {
class PhysicEngine;
float fraction; struct ActorTracer
}; {
Ogre::Vector3 mEndPos;
Ogre::Vector3 mPlaneNormal;
void actortrace(traceResults *results, btCollisionObject *actor, const Ogre::Vector3& start, const Ogre::Vector3& end, OEngine::Physic::PhysicEngine *enginePass); float mFraction;
void doTrace(btCollisionObject *actor, const Ogre::Vector3 &start, const Ogre::Vector3 &end,
const PhysicEngine *enginePass);
};
}
}
#endif #endif