1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-19 16:21:08 +00:00

Fix an issue uncovered by the last commit related to changing actor position without properly moving the actor

This commit is contained in:
scrawl 2017-02-10 02:43:49 +01:00
parent cf7b0098ed
commit 6ecc008813
3 changed files with 19 additions and 21 deletions

View File

@ -237,9 +237,10 @@ namespace MWPhysics
public: public:
static osg::Vec3f traceDown(const MWWorld::Ptr &ptr, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight) static osg::Vec3f traceDown(const MWWorld::Ptr &ptr, osg::Vec3f position, Actor* actor, btCollisionWorld* collisionWorld, float maxHeight)
{ {
osg::Vec3f position(actor->getCollisionObjectPosition()); osg::Vec3f offset = actor->getCollisionObjectPosition() - ptr.getRefData().getPosition().asVec3();
position += offset;
ActorTracer tracer; ActorTracer tracer;
tracer.findGround(actor, position, position-osg::Vec3f(0,0,maxHeight), collisionWorld); tracer.findGround(actor, position, position-osg::Vec3f(0,0,maxHeight), collisionWorld);
@ -1085,13 +1086,13 @@ namespace MWPhysics
return resultCallback.mResult; return resultCallback.mResult;
} }
osg::Vec3f PhysicsSystem::traceDown(const MWWorld::Ptr &ptr, float maxHeight) osg::Vec3f PhysicsSystem::traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, float maxHeight)
{ {
ActorMap::iterator found = mActors.find(ptr); ActorMap::iterator found = mActors.find(ptr);
if (found == mActors.end()) if (found == mActors.end())
return ptr.getRefData().getPosition().asVec3(); return ptr.getRefData().getPosition().asVec3();
else else
return MovementSolver::traceDown(ptr, found->second, mCollisionWorld, maxHeight); return MovementSolver::traceDown(ptr, position, found->second, mCollisionWorld, maxHeight);
} }
void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts) void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts)

View File

@ -90,7 +90,7 @@ namespace MWPhysics
void debugDraw(); void debugDraw();
std::vector<MWWorld::Ptr> getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const; ///< get handles this object collides with std::vector<MWWorld::Ptr> getCollisions(const MWWorld::ConstPtr &ptr, int collisionGroup, int collisionMask) const; ///< get handles this object collides with
osg::Vec3f traceDown(const MWWorld::Ptr &ptr, float maxHeight); osg::Vec3f traceDown(const MWWorld::Ptr &ptr, const osg::Vec3f& position, float maxHeight);
std::pair<MWWorld::Ptr, osg::Vec3f> getHitContact(const MWWorld::ConstPtr& actor, std::pair<MWWorld::Ptr, osg::Vec3f> getHitContact(const MWWorld::ConstPtr& actor,
const osg::Vec3f &origin, const osg::Vec3f &origin,

View File

@ -1296,7 +1296,7 @@ namespace MWWorld
void World::adjustPosition(const Ptr &ptr, bool force) void World::adjustPosition(const Ptr &ptr, bool force)
{ {
ESM::Position pos (ptr.getRefData().getPosition()); osg::Vec3f pos (ptr.getRefData().getPosition().asVec3());
if(!ptr.getRefData().getBaseNode()) if(!ptr.getRefData().getBaseNode())
{ {
@ -1306,34 +1306,31 @@ namespace MWWorld
float terrainHeight = -std::numeric_limits<float>::max(); float terrainHeight = -std::numeric_limits<float>::max();
if (ptr.getCell()->isExterior()) if (ptr.getCell()->isExterior())
terrainHeight = getTerrainHeightAt(pos.asVec3()); terrainHeight = getTerrainHeightAt(pos);
if (pos.pos[2] < terrainHeight) if (pos.z() < terrainHeight)
pos.pos[2] = terrainHeight; pos.z() = terrainHeight;
pos.pos[2] += 20; // place slightly above. will snap down to ground with code below pos.z() += 20; // place slightly above. will snap down to ground with code below
ptr.getRefData().setPosition(pos);
if (force || !isFlying(ptr)) if (force || !isFlying(ptr))
{ {
osg::Vec3f traced = mPhysics->traceDown(ptr, 500); osg::Vec3f traced = mPhysics->traceDown(ptr, pos, 500);
if (traced.z() < pos.pos[2]) if (traced.z() < pos.z())
pos.pos[2] = traced.z(); pos.z() = traced.z();
} }
moveObject(ptr, ptr.getCell(), pos.pos[0], pos.pos[1], pos.pos[2]); moveObject(ptr, ptr.getCell(), pos.x(), pos.y(), pos.z());
} }
void World::fixPosition(const Ptr &actor) void World::fixPosition(const Ptr &actor)
{ {
const float dist = 8000; const float dist = 8000;
ESM::Position pos (actor.getRefData().getPosition()); osg::Vec3f pos (actor.getRefData().getPosition().asVec3());
pos.pos[2] += dist; pos.z() += dist;
actor.getRefData().setPosition(pos);
osg::Vec3f traced = mPhysics->traceDown(actor, dist*1.1f); osg::Vec3f traced = mPhysics->traceDown(actor, pos, dist*1.1f);
if (traced != pos.asVec3()) if (traced != pos)
moveObject(actor, actor.getCell(), traced.x(), traced.y(), traced.z()); moveObject(actor, actor.getCell(), traced.x(), traced.y(), traced.z());
} }