Snap to the ground after moving

Depends on two factors:
* End up close enough above to a walkable plane (it's within sMaxStep units
  down and is angled sMaxSlope or less)
* Started out on the ground without any upward movement

This also reduces the distance needed to be to the ground to 4 (from 10), and
ensures the actor is 2 units above the ground when on it. Downward force is
also removed when starting on the ground.
actorid
Chris Robinson 12 years ago
parent da5f11700f
commit a729b1b12a

@ -102,6 +102,7 @@ namespace MWWorld
}
traceResults trace; //no initialization needed
bool onground = false;
float remainingTime = time;
bool isInterior = !ptr.getCell()->isExterior();
float verticalRotation = physicActor->getRotation().getYaw().valueDegrees();
@ -117,22 +118,24 @@ namespace MWWorld
}
else
{
if(!(movement.z > 0.0f))
{
newtrace(&trace, position, position-Ogre::Vector3(0,0,4), halfExtents, verticalRotation, isInterior, engine);
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
onground = true;
}
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z) *
movement / time;
velocity.z = physicActor->getVerticalForce();
velocity.z += physicActor->getVerticalForce();
}
// we need a copy of the velocity before we start clipping it for steps
Ogre::Vector3 clippedVelocity(velocity);
if(gravity)
if(onground)
{
newtrace(&trace, position, position+Ogre::Vector3(0,0,-10), halfExtents, verticalRotation, isInterior, engine);
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
{
// if we're within 10 units of the ground, force velocity to track the ground
clipVelocity(clippedVelocity, trace.planenormal, 1.0f);
}
// if we're on the ground, force velocity to track it
clippedVelocity.z = velocity.z = std::max(0.0f, velocity.z);
clipVelocity(clippedVelocity, trace.planenormal, 1.0f);
}
Ogre::Vector3 lastNormal(0.0f);
@ -176,6 +179,14 @@ namespace MWWorld
iterations++;
} while(iterations < sMaxIterations && remainingTime > 0.0f);
if(onground)
{
newtrace(&trace, newPosition, newPosition-Ogre::Vector3(0,0,sStepSize+4.0f), halfExtents, verticalRotation, isInterior, engine);
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
newPosition.z = trace.endpos.z + 2.0f;
else
onground = false;
}
physicActor->setVerticalForce(clippedVelocity.z - time*400.0f);
return newPosition;

Loading…
Cancel
Save