From 1a9672e31bcc29642690eccafe0f79e1aaf6d83c Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Tue, 20 Aug 2013 11:31:49 -0700 Subject: [PATCH] Don't update player physics more than 60 times a second Bullet and/or our collision handling code doesn't like timesteps much smaller than that. Ideally we should do physics in 60fps (or even 30fps) steps and use prediction and interpolation to get more, but that's not straight forward and needs a fixed timestep loop to lock physics and logic together. --- apps/openmw/mwworld/physicssystem.cpp | 29 ++++++++++++++------------- apps/openmw/mwworld/physicssystem.hpp | 5 +++-- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 558d3f037f..c865629acd 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -225,7 +225,7 @@ namespace MWWorld PhysicsSystem::PhysicsSystem(OEngine::Render::OgreRenderer &_rend) : - mRender(_rend), mEngine(0) + mRender(_rend), mEngine(0), mTimeAccum(0.0f) { // Create physics. shapeLoader is deleted by the physic engine NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader(); @@ -394,11 +394,6 @@ namespace MWWorld return mEngine->getCollisions(ptr.getRefData().getBaseNode()->getName()); } - Ogre::Vector3 PhysicsSystem::move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time, bool gravity) - { - return MovementSolver::move(ptr, movement, time, gravity, mEngine); - } - Ogre::Vector3 PhysicsSystem::traceDown(const MWWorld::Ptr &ptr) { return MovementSolver::traceDown(ptr, mEngine); @@ -570,16 +565,22 @@ namespace MWWorld { mMovementResults.clear(); - const MWBase::World *world = MWBase::Environment::get().getWorld(); - PtrVelocityList::iterator iter = mMovementQueue.begin(); - for(;iter != mMovementQueue.end();iter++) + mTimeAccum += dt; + if(mTimeAccum >= 1.0f/60.0f) { - Ogre::Vector3 newpos; - newpos = move(iter->first, iter->second, dt, - !world->isSwimming(iter->first) && !world->isFlying(iter->first)); - mMovementResults.push_back(std::make_pair(iter->first, newpos)); - } + const MWBase::World *world = MWBase::Environment::get().getWorld(); + PtrVelocityList::iterator iter = mMovementQueue.begin(); + for(;iter != mMovementQueue.end();iter++) + { + Ogre::Vector3 newpos; + newpos = MovementSolver::move(iter->first, iter->second, mTimeAccum, + !world->isSwimming(iter->first) && + !world->isFlying(iter->first), mEngine); + mMovementResults.push_back(std::make_pair(iter->first, newpos)); + } + mTimeAccum = 0.0f; + } mMovementQueue.clear(); return mMovementResults; diff --git a/apps/openmw/mwworld/physicssystem.hpp b/apps/openmw/mwworld/physicssystem.hpp index 438e2ada65..bbee2d5daf 100644 --- a/apps/openmw/mwworld/physicssystem.hpp +++ b/apps/openmw/mwworld/physicssystem.hpp @@ -52,8 +52,7 @@ namespace MWWorld void scaleObject (const MWWorld::Ptr& ptr); bool toggleCollisionMode(); - - Ogre::Vector3 move(const MWWorld::Ptr &ptr, const Ogre::Vector3 &movement, float time, bool gravity); + std::vector getCollisions(const MWWorld::Ptr &ptr); ///< get handles this object collides with Ogre::Vector3 traceDown(const MWWorld::Ptr &ptr); @@ -98,6 +97,8 @@ namespace MWWorld PtrVelocityList mMovementQueue; PtrVelocityList mMovementResults; + float mTimeAccum; + PhysicsSystem (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&); };