pMove in a seperate loop with fixed timestep to prevent frame-dependent movement

This commit is contained in:
scrawl 2012-04-30 23:55:22 +02:00
parent 4655ec94f0
commit 86b6184f43
5 changed files with 102 additions and 74 deletions

View file

@ -27,9 +27,6 @@ namespace MWWorld
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
playerphysics->mEngine = mEngine;
}
PhysicsSystem::~PhysicsSystem()
@ -98,14 +95,11 @@ namespace MWWorld
return !(result.first == "");
}
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysics (float duration,
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
void PhysicsSystem::doPhysics(float dt, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
{
//set the DebugRenderingMode. To disable it,set it to 0
//eng->setDebugRenderingMode(1);
//set the walkdirection to 0 (no movement) for every actor)
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
{
@ -118,7 +112,6 @@ namespace MWWorld
pm_ref.forwardmove = 0;
pm_ref.upmove = 0;
//playerphysics->ps.move_type = PM_NOCLIP;
for (std::vector<std::pair<std::string, Ogre::Vector3> >::const_iterator iter (actors.begin());
iter!=actors.end(); ++iter)
@ -142,12 +135,8 @@ namespace MWWorld
playerphysics->ps.viewangles.z = 0;
playerphysics->ps.viewangles.y = yawQuat.getYaw().valueDegrees() *-1 + 90;
if(mFreeFly)
{
Ogre::Vector3 dir1(iter->second.x,iter->second.z,-iter->second.y);
pm_ref.rightmove = -dir1.x;
@ -155,7 +144,6 @@ namespace MWWorld
pm_ref.upmove = dir1.y;
//std::cout << "Current angle" << yawQuat.getYaw().valueDegrees() - 90<< "\n";
//playerphysics->ps.viewangles.x = pitchQuat.getPitch().valueDegrees();
//std::cout << "Pitch: " << yawQuat.getPitch() << "Yaw:" << yawQuat.getYaw() << "Roll: " << yawQuat.getRoll() << "\n";
@ -180,9 +168,13 @@ namespace MWWorld
//set the walk direction
act->setWalkDirection(btVector3(dir.x,-dir.z,dir.y));
}
mEngine->stepSimulation(duration);
Pmove(playerphysics);
mEngine->stepSimulation(dt);
}
std::vector< std::pair<std::string, Ogre::Vector3> > PhysicsSystem::doPhysicsFixed (
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
{
Pmove(playerphysics);
std::vector< std::pair<std::string, Ogre::Vector3> > response;
for(std::map<std::string,OEngine::Physic::PhysicActor*>::iterator it = mEngine->PhysicActorMap.begin(); it != mEngine->PhysicActorMap.end();it++)
@ -260,9 +252,16 @@ namespace MWWorld
{
// TODO very dirty hack to avoid crash during setup -> needs cleaning up to allow
// start positions others than 0, 0, 0
if (handle == "player")
{
playerphysics->ps.origin = position;
}
else
{
act->setPosition(btVector3(position.x,position.y,position.z));
}
}
}
void PhysicsSystem::rotateObject (const std::string& handle, const Ogre::Quaternion& rotation)
{

View file

@ -16,8 +16,11 @@ namespace MWWorld
PhysicsSystem (OEngine::Render::OgreRenderer &_rend);
~PhysicsSystem ();
std::vector< std::pair<std::string, Ogre::Vector3> > doPhysics (float duration,
const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
void doPhysics(float duration, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
///< do physics with dt - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed
std::vector< std::pair<std::string, Ogre::Vector3> > doPhysicsFixed (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors);
///< do physics with fixed timestep - Usage: first call doPhysics with frame dt, then call doPhysicsFixed as often as time steps have passed
void addObject (const std::string& handle, const std::string& mesh,
const Ogre::Quaternion& rotation, float scale, const Ogre::Vector3& position);
@ -64,7 +67,6 @@ namespace MWWorld
bool mFreeFly;
playerMove* playerphysics;
PhysicsSystem (const PhysicsSystem&);
PhysicsSystem& operator= (const PhysicsSystem&);
};

View file

@ -215,6 +215,7 @@ namespace MWWorld
setFallbackValues(fallbackMap);
lastTick = mTimer.getMilliseconds();
}
@ -559,8 +560,9 @@ namespace MWWorld
}
}
void World::moveObjectImp (Ptr ptr, float x, float y, float z)
bool World::moveObjectImp (Ptr ptr, float x, float y, float z)
{
bool ret = false;
ptr.getRefData().getPosition().pos[0] = x;
ptr.getRefData().getPosition().pos[1] = y;
ptr.getRefData().getPosition().pos[2] = z;
@ -582,6 +584,7 @@ namespace MWWorld
if (currentCell->cell->data.gridX!=cellX || currentCell->cell->data.gridY!=cellY)
{
mWorldScene->changeCell (cellX, cellY, mPlayer->getPlayer().getRefData().getPosition(), false);
ret = true;
}
}
@ -591,6 +594,8 @@ namespace MWWorld
/// \todo cell change for non-player ref
mRendering->moveObject (ptr, Ogre::Vector3 (x, y, z));
return ret;
}
void World::moveObject (Ptr ptr, float x, float y, float z)
@ -632,7 +637,19 @@ namespace MWWorld
void World::doPhysics (const std::vector<std::pair<std::string, Ogre::Vector3> >& actors,
float duration)
{
std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysics (duration, actors);
mPhysics->doPhysics(duration, actors);
const int tick = 16; // 16 ms ^= 60 Hz
// Game clock part of the loop, contains everything that has to be executed in a fixed timestep
long long dt = mTimer.getMilliseconds() - lastTick;
if (dt >= 100) dt = 100; // throw away wall clock time if necessary to keep the framerate above the minimum of 10 fps
while (dt >= tick)
{
dt -= tick;
lastTick += tick;
std::vector< std::pair<std::string, Ogre::Vector3> > vectors = mPhysics->doPhysicsFixed (actors);
std::vector< std::pair<std::string, Ogre::Vector3> >::iterator player = vectors.end();
@ -653,8 +670,12 @@ namespace MWWorld
// Make sure player is moved last (otherwise the cell might change in the middle of an update
// loop)
if (player!=vectors.end())
moveObjectImp (getPtrViaHandle (player->first),
player->second.x, player->second.y, player->second.z);
{
if (moveObjectImp (getPtrViaHandle (player->first),
player->second.x, player->second.y, player->second.z) == true)
return; // abort the current loop if the cell has changed
}
}
}
bool World::toggleCollisionMode()

View file

@ -22,6 +22,8 @@
#include <openengine/bullet/physic.hpp>
#include <openengine/ogre/fader.hpp>
#include <OgreTimer.h>
namespace Ogre
{
class Vector3;
@ -100,9 +102,13 @@ namespace MWWorld
int mNumFacing;
std::map<std::string,std::string> mFallback;
unsigned long lastTick;
Ogre::Timer mTimer;
int getDaysPerMonth (int month) const;
void moveObjectImp (Ptr ptr, float x, float y, float z);
bool moveObjectImp (Ptr ptr, float x, float y, float z);
///< @return true if the active cell (cell player is in) changed
public:

View file

@ -393,7 +393,7 @@ namespace Physic
void PhysicEngine::stepSimulation(double deltaT)
{
dynamicsWorld->stepSimulation(deltaT,10);
dynamicsWorld->stepSimulation(deltaT,10, 1/60.0);
if(isDebugCreated)
{
mDebugDrawer->step();