mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-07-21 06:14:05 +00:00
Improve movement inertia
Handles all 3 axis. Incoming velocity is only added to inertia when leaving the ground, and does not continually add to it.
This commit is contained in:
parent
9d56e2d86d
commit
8c3564326e
3 changed files with 48 additions and 39 deletions
|
@ -132,8 +132,10 @@ namespace MWWorld
|
||||||
position.z += halfExtents.z;
|
position.z += halfExtents.z;
|
||||||
|
|
||||||
OEngine::Physic::ActorTracer tracer;
|
OEngine::Physic::ActorTracer tracer;
|
||||||
bool onground = false;
|
bool wasOnGround = false;
|
||||||
|
bool isOnGround = false;
|
||||||
const Ogre::Quaternion orient; // Don't rotate actor collision boxes
|
const Ogre::Quaternion orient; // Don't rotate actor collision boxes
|
||||||
|
Ogre::Vector3 inertia(0.0f);
|
||||||
Ogre::Vector3 velocity;
|
Ogre::Vector3 velocity;
|
||||||
if(!gravity)
|
if(!gravity)
|
||||||
{
|
{
|
||||||
|
@ -143,18 +145,20 @@ namespace MWWorld
|
||||||
movement;
|
movement;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if(!(movement.z > 0.0f))
|
|
||||||
{
|
{
|
||||||
tracer.doTrace(colobj, position, position-Ogre::Vector3(0,0,4), engine);
|
tracer.doTrace(colobj, position, position-Ogre::Vector3(0,0,4), engine);
|
||||||
if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
|
if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
|
||||||
onground = true;
|
{
|
||||||
|
wasOnGround = true;
|
||||||
|
if(!(movement.z > 0.0f))
|
||||||
|
isOnGround = true;
|
||||||
}
|
}
|
||||||
|
inertia = physicActor->getInertialForce();
|
||||||
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z) * movement;
|
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z) * movement;
|
||||||
velocity.z += physicActor->getVerticalForce();
|
velocity += inertia;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(onground)
|
if(isOnGround)
|
||||||
{
|
{
|
||||||
// if we're on the ground, don't try to fall
|
// if we're on the ground, don't try to fall
|
||||||
velocity.z = std::max(0.0f, velocity.z);
|
velocity.z = std::max(0.0f, velocity.z);
|
||||||
|
@ -179,7 +183,7 @@ namespace MWWorld
|
||||||
//std::cout<<"angle: "<<getSlope(trace.planenormal)<<"\n";
|
//std::cout<<"angle: "<<getSlope(trace.planenormal)<<"\n";
|
||||||
// We hit something. Try to step up onto it.
|
// We hit something. Try to step up onto it.
|
||||||
if(stepMove(colobj, newPosition, velocity, remainingTime, engine))
|
if(stepMove(colobj, newPosition, velocity, remainingTime, engine))
|
||||||
onground = gravity;
|
isOnGround = gravity;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 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
|
||||||
|
@ -195,17 +199,25 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(onground)
|
if(isOnGround)
|
||||||
{
|
{
|
||||||
tracer.doTrace(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(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
|
if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
|
||||||
newPosition.z = tracer.mEndPos.z + 2.0f;
|
newPosition.z = tracer.mEndPos.z + 2.0f;
|
||||||
else
|
else
|
||||||
onground = false;
|
isOnGround = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
physicActor->setOnGround(onground);
|
physicActor->setOnGround(isOnGround);
|
||||||
physicActor->setVerticalForce(!onground ? velocity.z - time*627.2f : 0.0f);
|
if(isOnGround)
|
||||||
|
physicActor->setInertialForce(Ogre::Vector3(0.0f));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(wasOnGround)
|
||||||
|
inertia = velocity;
|
||||||
|
inertia.z -= time*627.2f;
|
||||||
|
physicActor->setInertialForce(inertia);
|
||||||
|
}
|
||||||
|
|
||||||
newPosition.z -= halfExtents.z;
|
newPosition.z -= halfExtents.z;
|
||||||
return newPosition;
|
return newPosition;
|
||||||
|
|
|
@ -19,7 +19,8 @@ namespace Physic
|
||||||
|
|
||||||
PhysicActor::PhysicActor(const std::string &name, const std::string &mesh, PhysicEngine *engine, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, float scale)
|
PhysicActor::PhysicActor(const std::string &name, const std::string &mesh, PhysicEngine *engine, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, float scale)
|
||||||
: mName(name), mEngine(engine), mMesh(mesh), mBoxScaledTranslation(0,0,0), mBoxRotationInverse(0,0,0,0)
|
: mName(name), mEngine(engine), mMesh(mesh), mBoxScaledTranslation(0,0,0), mBoxRotationInverse(0,0,0,0)
|
||||||
, mBody(0), mRaycastingBody(0), onGround(false), collisionMode(true), mBoxRotation(0,0,0,0), verticalForce(0.0f)
|
, mBody(0), mRaycastingBody(0), mOnGround(false), mCollisionMode(true), mBoxRotation(0,0,0,0)
|
||||||
|
, mForce(0.0f)
|
||||||
{
|
{
|
||||||
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation);
|
mBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation);
|
||||||
mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, true);
|
mRaycastingBody = mEngine->createAndAdjustRigidBody(mMesh, mName, scale, position, rotation, &mBoxScaledTranslation, &mBoxRotation, true);
|
||||||
|
@ -45,9 +46,9 @@ namespace Physic
|
||||||
void PhysicActor::enableCollisions(bool collision)
|
void PhysicActor::enableCollisions(bool collision)
|
||||||
{
|
{
|
||||||
assert(mBody);
|
assert(mBody);
|
||||||
if(collision && !collisionMode) enableCollisionBody();
|
if(collision && !mCollisionMode) enableCollisionBody();
|
||||||
if(!collision && collisionMode) disableCollisionBody();
|
if(!collision && mCollisionMode) disableCollisionBody();
|
||||||
collisionMode = collision;
|
mCollisionMode = collision;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,24 +124,14 @@ namespace Physic
|
||||||
return Ogre::Vector3(0.0f);
|
return Ogre::Vector3(0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::setVerticalForce(float force)
|
void PhysicActor::setInertialForce(const Ogre::Vector3 &force)
|
||||||
{
|
{
|
||||||
verticalForce = force;
|
mForce = force;
|
||||||
}
|
|
||||||
|
|
||||||
float PhysicActor::getVerticalForce() const
|
|
||||||
{
|
|
||||||
return verticalForce;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::setOnGround(bool grounded)
|
void PhysicActor::setOnGround(bool grounded)
|
||||||
{
|
{
|
||||||
onGround = grounded;
|
mOnGround = grounded;
|
||||||
}
|
|
||||||
|
|
||||||
bool PhysicActor::getOnGround() const
|
|
||||||
{
|
|
||||||
return collisionMode && onGround;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicActor::disableCollisionBody()
|
void PhysicActor::disableCollisionBody()
|
||||||
|
|
|
@ -104,7 +104,7 @@ namespace Physic
|
||||||
|
|
||||||
bool getCollisionMode() const
|
bool getCollisionMode() const
|
||||||
{
|
{
|
||||||
return collisionMode;
|
return mCollisionMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,18 +130,24 @@ namespace Physic
|
||||||
Ogre::Vector3 getHalfExtents() const;
|
Ogre::Vector3 getHalfExtents() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current amount of vertical force (gravity) affecting this physic actor
|
* Sets the current amount of inertial force (incl. gravity) affecting this physic actor
|
||||||
*/
|
*/
|
||||||
void setVerticalForce(float force);
|
void setInertialForce(const Ogre::Vector3 &force);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current amount of vertical force (gravity) affecting this physic actor
|
* Gets the current amount of inertial force (incl. gravity) affecting this physic actor
|
||||||
*/
|
*/
|
||||||
float getVerticalForce() const;
|
const Ogre::Vector3 &getInertialForce() const
|
||||||
|
{
|
||||||
|
return mForce;
|
||||||
|
}
|
||||||
|
|
||||||
void setOnGround(bool grounded);
|
void setOnGround(bool grounded);
|
||||||
|
|
||||||
bool getOnGround() const;
|
bool getOnGround() const
|
||||||
|
{
|
||||||
|
return mCollisionMode && mOnGround;
|
||||||
|
}
|
||||||
|
|
||||||
btCollisionObject *getCollisionBody() const
|
btCollisionObject *getCollisionBody() const
|
||||||
{
|
{
|
||||||
|
@ -169,9 +175,9 @@ public:
|
||||||
Ogre::Quaternion mBoxRotation;
|
Ogre::Quaternion mBoxRotation;
|
||||||
btQuaternion mBoxRotationInverse;
|
btQuaternion mBoxRotationInverse;
|
||||||
|
|
||||||
float verticalForce;
|
Ogre::Vector3 mForce;
|
||||||
bool onGround;
|
bool mOnGround;
|
||||||
bool collisionMode;
|
bool mCollisionMode;
|
||||||
|
|
||||||
std::string mMesh;
|
std::string mMesh;
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
Loading…
Reference in a new issue