forked from teamnwah/openmw-tes3coop
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.
This commit is contained in:
parent
da5f11700f
commit
a729b1b12a
1 changed files with 21 additions and 10 deletions
|
@ -102,6 +102,7 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
|
|
||||||
traceResults trace; //no initialization needed
|
traceResults trace; //no initialization needed
|
||||||
|
bool onground = false;
|
||||||
float remainingTime = time;
|
float remainingTime = time;
|
||||||
bool isInterior = !ptr.getCell()->isExterior();
|
bool isInterior = !ptr.getCell()->isExterior();
|
||||||
float verticalRotation = physicActor->getRotation().getYaw().valueDegrees();
|
float verticalRotation = physicActor->getRotation().getYaw().valueDegrees();
|
||||||
|
@ -117,22 +118,24 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
else
|
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) *
|
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z) *
|
||||||
movement / time;
|
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);
|
Ogre::Vector3 clippedVelocity(velocity);
|
||||||
|
if(onground)
|
||||||
if(gravity)
|
|
||||||
{
|
{
|
||||||
newtrace(&trace, position, position+Ogre::Vector3(0,0,-10), halfExtents, verticalRotation, isInterior, engine);
|
// if we're on the ground, force velocity to track it
|
||||||
if(trace.fraction < 1.0f && getSlope(trace.planenormal) <= sMaxSlope)
|
clippedVelocity.z = velocity.z = std::max(0.0f, velocity.z);
|
||||||
{
|
clipVelocity(clippedVelocity, trace.planenormal, 1.0f);
|
||||||
// if we're within 10 units of the ground, force velocity to track the ground
|
|
||||||
clipVelocity(clippedVelocity, trace.planenormal, 1.0f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ogre::Vector3 lastNormal(0.0f);
|
Ogre::Vector3 lastNormal(0.0f);
|
||||||
|
@ -176,6 +179,14 @@ namespace MWWorld
|
||||||
iterations++;
|
iterations++;
|
||||||
} while(iterations < sMaxIterations && remainingTime > 0.0f);
|
} 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);
|
physicActor->setVerticalForce(clippedVelocity.z - time*400.0f);
|
||||||
|
|
||||||
return newPosition;
|
return newPosition;
|
||||||
|
|
Loading…
Reference in a new issue