mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-22 04:23:53 +00:00
Instead of hacking character.cpp, provide a more reliable check for world->isOnGround(mPtr).
This commit is contained in:
parent
e9be6d3f42
commit
3e6e325e5b
2 changed files with 29 additions and 9 deletions
|
@ -1090,14 +1090,7 @@ void CharacterController::update(float duration)
|
||||||
if (inwater || flying)
|
if (inwater || flying)
|
||||||
cls.getCreatureStats(mPtr).land();
|
cls.getCreatureStats(mPtr).land();
|
||||||
|
|
||||||
if(!onground && !flying && !inwater
|
if(!onground && !flying && !inwater)
|
||||||
// FIXME: The check for vec.z is a hack, but onground is not a reliable
|
|
||||||
// indicator of whether the actor is on the ground (defaults to false, which
|
|
||||||
// means this code block will always execute at least once for most actors,
|
|
||||||
// and collisions can move z position slightly off zero). A very small value
|
|
||||||
// of 0.1 is used here, but something larger like 10 may be more suitable.
|
|
||||||
// Should resolve Bug#1271.
|
|
||||||
&& (mJumpState == JumpState_Falling || vec.z > 0.1f))
|
|
||||||
{
|
{
|
||||||
// In the air (either getting up —ascending part of jump— or falling).
|
// In the air (either getting up —ascending part of jump— or falling).
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <OgreSceneNode.h>
|
#include <OgreSceneNode.h>
|
||||||
|
|
||||||
|
#include <libs/openengine/bullet/trace.h>
|
||||||
#include <libs/openengine/bullet/physic.hpp>
|
#include <libs/openengine/bullet/physic.hpp>
|
||||||
|
|
||||||
#include <components/bsa/bsa_archive.hpp>
|
#include <components/bsa/bsa_archive.hpp>
|
||||||
|
@ -1711,11 +1712,37 @@ namespace MWWorld
|
||||||
return pos.z < cell->getWaterLevel();
|
return pos.z < cell->getWaterLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// physactor->getOnGround() is not a reliable indicator of whether the actor
|
||||||
|
// is on the ground (defaults to false, which means code blocks such as
|
||||||
|
// CharacterController::update() may falsely detect "falling").
|
||||||
|
//
|
||||||
|
// Also, collisions can move z position slightly off zero, giving a false
|
||||||
|
// indication. In order to reduce false detection of jumping, small distance
|
||||||
|
// below the actor is detected and ignored. A value of 1.5 is used here, but
|
||||||
|
// something larger may be more suitable. This change should resolve Bug#1271.
|
||||||
|
//
|
||||||
|
// FIXME: Collision detection each time may have a performance impact.
|
||||||
|
// There might be better places to update PhysicActor::mOnGround.
|
||||||
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
bool World::isOnGround(const MWWorld::Ptr &ptr) const
|
||||||
{
|
{
|
||||||
RefData &refdata = ptr.getRefData();
|
RefData &refdata = ptr.getRefData();
|
||||||
const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
const OEngine::Physic::PhysicActor *physactor = mPhysEngine->getCharacter(refdata.getHandle());
|
||||||
return physactor && physactor->getOnGround();
|
if(physactor)
|
||||||
|
{
|
||||||
|
Ogre::Vector3 pos(ptr.getRefData().getPosition().pos);
|
||||||
|
OEngine::Physic::ActorTracer tracer;
|
||||||
|
// a small distance above collision object is considered "on ground"
|
||||||
|
tracer.findGround(physactor->getCollisionBody(),
|
||||||
|
pos,
|
||||||
|
pos - Ogre::Vector3(0, 0, 1.5f), // trace a small amount down
|
||||||
|
mPhysEngine);
|
||||||
|
if(tracer.mFraction < 1.0f) // collision, must be close to something below
|
||||||
|
return true; // TODO: should update physactor
|
||||||
|
else
|
||||||
|
return physactor->getOnGround();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::vanityRotateCamera(float * rot)
|
bool World::vanityRotateCamera(float * rot)
|
||||||
|
|
Loading…
Reference in a new issue