Attempt to fix player position after using coc/coe

This commit is contained in:
scrawl 2014-06-28 14:59:33 +02:00
parent 8e361bb879
commit 3b2358888b
6 changed files with 24 additions and 6 deletions

View file

@ -274,6 +274,9 @@ namespace MWBase
virtual void adjustPosition (const MWWorld::Ptr& ptr) = 0;
///< Adjust position after load to be on ground. Must be called after model load.
virtual void fixPosition (const MWWorld::Ptr& actor) = 0;
///< Attempt to fix position so that the Ptr is no longer inside collision geometry.
virtual void deleteObject (const MWWorld::Ptr& ptr) = 0;
virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0;

View file

@ -47,6 +47,7 @@ namespace MWScript
if (world->findExteriorPosition(cell, pos))
{
world->changeToExteriorCell(pos);
world->fixPosition(world->getPlayerPtr());
}
else
{
@ -79,6 +80,7 @@ namespace MWScript
pos.rot[0] = pos.rot[1] = pos.rot[2] = 0;
world->changeToExteriorCell (pos);
world->fixPosition(world->getPlayerPtr());
}
};

View file

@ -215,7 +215,7 @@ namespace MWWorld
public:
static Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr, OEngine::Physic::PhysicEngine *engine)
static Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr, OEngine::Physic::PhysicEngine *engine, float maxHeight)
{
const ESM::Position &refpos = ptr.getRefData().getPosition();
Ogre::Vector3 position(refpos.pos);
@ -224,7 +224,6 @@ namespace MWWorld
if (!physicActor)
return position;
const int maxHeight = 200.f;
OEngine::Physic::ActorTracer tracer;
tracer.findGround(physicActor, position, position-Ogre::Vector3(0,0,maxHeight), engine);
if(tracer.mFraction >= 1.0f)
@ -600,9 +599,9 @@ namespace MWWorld
return mEngine->getCollisions(ptr.getRefData().getBaseNode()->getName());
}
Ogre::Vector3 PhysicsSystem::traceDown(const MWWorld::Ptr &ptr)
Ogre::Vector3 PhysicsSystem::traceDown(const MWWorld::Ptr &ptr, float maxHeight)
{
return MovementSolver::traceDown(ptr, mEngine);
return MovementSolver::traceDown(ptr, mEngine, maxHeight);
}
void PhysicsSystem::addHeightField (float* heights,

View file

@ -56,7 +56,7 @@ namespace MWWorld
void stepSimulation(float dt);
std::vector<std::string> getCollisions(const MWWorld::Ptr &ptr); ///< get handles this object collides with
Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr);
Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr, float maxHeight);
std::pair<float, std::string> getFacedHandle(float queryDistance);
std::pair<std::string,Ogre::Vector3> getHitContact(const std::string &name,

View file

@ -1166,7 +1166,7 @@ namespace MWWorld
if (!isFlying(ptr))
{
Ogre::Vector3 traced = mPhysics->traceDown(ptr);
Ogre::Vector3 traced = mPhysics->traceDown(ptr, 200);
if (traced.z < pos.pos[2])
pos.pos[2] = traced.z;
}
@ -1174,6 +1174,17 @@ namespace MWWorld
moveObject(ptr, ptr.getCell(), pos.pos[0], pos.pos[1], pos.pos[2]);
}
void World::fixPosition(const Ptr &actor)
{
const float dist = 8000;
ESM::Position pos (actor.getRefData().getPosition());
pos.pos[2] += dist;
actor.getRefData().setPosition(pos);
Ogre::Vector3 traced = mPhysics->traceDown(actor, dist*1.1);
moveObject(actor, actor.getCell(), traced.x, traced.y, traced.z);
}
void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust)
{
rotateObjectImp(ptr, Ogre::Vector3(Ogre::Degree(x).valueRadians(),

View file

@ -263,6 +263,9 @@ namespace MWWorld
virtual void adjustPosition (const Ptr& ptr);
///< Adjust position after load to be on ground. Must be called after model load.
virtual void fixPosition (const Ptr& actor);
///< Attempt to fix position so that the Ptr is no longer inside collision geometry.
virtual void enable (const Ptr& ptr);
virtual void disable (const Ptr& ptr);