From 19ad7d7f0cd77984ed4628ac539cce9a0c502039 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sat, 13 Mar 2021 15:24:45 +0100 Subject: [PATCH 1/7] Resolve #5895 by setting the initial mOnGround state to false; we do this because the movement solver runs one frame behind so when we run through the loop the first time we assume we are on the ground even though we may be 400 units in the air. --- apps/openmw/mwphysics/actor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 06abe72403..87698ef37c 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -72,6 +72,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic updatePosition(); addCollisionMask(getCollisionMask()); updateCollisionObjectPosition(); + mOnGround.store(false, std::memory_order_release); } Actor::~Actor() From 1479f987934240075ba76ddf0836857c3d209edf Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 14 Mar 2021 01:02:44 +0100 Subject: [PATCH 2/7] hacky solution with debug; seems that player is added before cell so tracing down will not find anything --- apps/openmw/mwphysics/actor.cpp | 1 - apps/openmw/mwphysics/physicssystem.cpp | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 87698ef37c..06abe72403 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -72,7 +72,6 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic updatePosition(); addCollisionMask(getCollisionMask()); updateCollisionObjectPosition(); - mOnGround.store(false, std::memory_order_release); } Actor::~Actor() diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index dc9ab629a1..e24aa3500c 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -680,7 +681,24 @@ namespace MWPhysics return; auto actor = std::make_shared(ptr, shape, mTaskScheduler.get()); + + if (ptr == MWMechanics::getPlayer()) + { + osg::Vec3f offset = actor->getCollisionObjectPosition() - ptr.getRefData().getPosition().asVec3(); + std::cout << "DEBUG Player position: " << actor->getPosition() << std::endl; + auto terrainHeight = std::max(0.f, MWBase::Environment::get().getWorld()->getTerrainHeightAt(actor->getPosition())); + std::cout << "DEBUG terrain height " << terrainHeight << std::endl; + ActorTracer tracer; + tracer.findGround(actor.get(), actor->getPosition() + offset, actor->getPosition() + offset - osg::Vec3f(0, 0, 100.f), mCollisionWorld.get()); + std::cout << "DEBUG mFraction " << tracer.mFraction << std::endl; // it seems that player is loaded before the cell so we can't find the ground. + + std::cout << "DEBUG calculation :: " << actor->getPosition().z() - terrainHeight << std::endl; + if (actor->getPosition().z() - terrainHeight > 300.f) + actor->setOnGround(false); + } + mActors.emplace(ptr, std::move(actor)); + } int PhysicsSystem::addProjectile (const MWWorld::Ptr& caster, const osg::Vec3f& position, const std::string& mesh, bool computeRadius, bool canTraverseWater) From c067782814d39f274c9f25451ebb7b9769dbac6d Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 14 Mar 2021 02:39:18 +0100 Subject: [PATCH 3/7] proper fix that traces down the player when a cell is loaded; we also only run once if the current cell being loaded is the one that the player is in. --- apps/openmw/mwphysics/physicssystem.cpp | 16 ---------------- apps/openmw/mwworld/scene.cpp | 5 ++++- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index e24aa3500c..fcb85900b3 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include #include @@ -682,21 +681,6 @@ namespace MWPhysics auto actor = std::make_shared(ptr, shape, mTaskScheduler.get()); - if (ptr == MWMechanics::getPlayer()) - { - osg::Vec3f offset = actor->getCollisionObjectPosition() - ptr.getRefData().getPosition().asVec3(); - std::cout << "DEBUG Player position: " << actor->getPosition() << std::endl; - auto terrainHeight = std::max(0.f, MWBase::Environment::get().getWorld()->getTerrainHeightAt(actor->getPosition())); - std::cout << "DEBUG terrain height " << terrainHeight << std::endl; - ActorTracer tracer; - tracer.findGround(actor.get(), actor->getPosition() + offset, actor->getPosition() + offset - osg::Vec3f(0, 0, 100.f), mCollisionWorld.get()); - std::cout << "DEBUG mFraction " << tracer.mFraction << std::endl; // it seems that player is loaded before the cell so we can't find the ground. - - std::cout << "DEBUG calculation :: " << actor->getPosition().z() - terrainHeight << std::endl; - if (actor->getPosition().z() - terrainHeight > 300.f) - actor->setOnGround(false); - } - mActors.emplace(ptr, std::move(actor)); } diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 427ee3aa8b..ac01c8893b 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -447,11 +447,14 @@ namespace MWWorld mPhysics->disableWater(); const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); + if (player.getCell() == cell) { + mPhysics->traceDown(player, player.getRefData().getPosition().asVec3(), 10.f); + } + navigator->update(player.getRefData().getPosition().asVec3()); if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx)) { - mRendering.configureAmbient(cell->getCell()); } } From fff1df9ee46bce05cc1a68e163e137d6fdc19c88 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 14 Mar 2021 02:40:32 +0100 Subject: [PATCH 4/7] revert some blank lines --- apps/openmw/mwphysics/physicssystem.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index fcb85900b3..dc9ab629a1 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -680,9 +680,7 @@ namespace MWPhysics return; auto actor = std::make_shared(ptr, shape, mTaskScheduler.get()); - mActors.emplace(ptr, std::move(actor)); - } int PhysicsSystem::addProjectile (const MWWorld::Ptr& caster, const osg::Vec3f& position, const std::string& mesh, bool computeRadius, bool canTraverseWater) From 49545e6d299a706e6adcce6246b40441aa433c6a Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 14 Mar 2021 13:40:48 +0100 Subject: [PATCH 5/7] add comments as to why we need to check that the player is grounded or not; only run once during initial cell loading --- apps/openmw/mwworld/scene.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index ac01c8893b..31d83dce3d 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -447,7 +447,9 @@ namespace MWWorld mPhysics->disableWater(); const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); - if (player.getCell() == cell) { + + // By default the player is grounded, with the scene fully loaded, we validate and correct this. + if (player.getCell() == cell) { // Only run once, during initial cell load. mPhysics->traceDown(player, player.getRefData().getPosition().asVec3(), 10.f); } From 9fc0649fb6a03aec0f3b725373046cb8f325434b Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 14 Mar 2021 18:08:52 +0100 Subject: [PATCH 6/7] a better check to avoid the mCell assertion, so compariing nullptr to current cell will refurn false anyway --- apps/openmw/mwworld/scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 31d83dce3d..140d69e6b4 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -449,7 +449,7 @@ namespace MWWorld const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); // By default the player is grounded, with the scene fully loaded, we validate and correct this. - if (player.getCell() == cell) { // Only run once, during initial cell load. + if (player.mCell == cell) { // Only run once, during initial cell load. mPhysics->traceDown(player, player.getRefData().getPosition().asVec3(), 10.f); } From 40c989d732635633406de1b6d13d16156cb2052d Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Sun, 14 Mar 2021 22:11:18 +0100 Subject: [PATCH 7/7] allman style --- apps/openmw/mwworld/scene.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 140d69e6b4..3f050ba366 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -449,7 +449,8 @@ namespace MWWorld const auto player = MWBase::Environment::get().getWorld()->getPlayerPtr(); // By default the player is grounded, with the scene fully loaded, we validate and correct this. - if (player.mCell == cell) { // Only run once, during initial cell load. + if (player.mCell == cell) // Only run once, during initial cell load. + { mPhysics->traceDown(player, player.getRefData().getPosition().asVec3(), 10.f); }