mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:53:51 +00:00
Apply movement by queueing it to do later
This commit is contained in:
parent
96bab88da6
commit
9d56e2d86d
9 changed files with 52 additions and 68 deletions
|
@ -250,8 +250,9 @@ namespace MWBase
|
|||
virtual void positionToIndex (float x, float y, int &cellX, int &cellY) const = 0;
|
||||
///< Convert position to cell numbers
|
||||
|
||||
virtual void doPhysics (const MWWorld::PtrMovementList &actors, float duration) = 0;
|
||||
///< Run physics simulation and modify \a world accordingly.
|
||||
virtual void queueMovement(const MWWorld::Ptr &ptr, const Ogre::Vector3 &velocity) = 0;
|
||||
///< Queues movement for \a ptr (in local space), to be applied in the next call to
|
||||
/// doPhysics.
|
||||
|
||||
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2) = 0;
|
||||
///< cast a Ray and return true if there is an object in the ray path.
|
||||
|
|
|
@ -300,17 +300,8 @@ namespace MWMechanics
|
|||
|
||||
if(!paused)
|
||||
{
|
||||
mMovement.reserve(mActors.size());
|
||||
|
||||
for(PtrControllerMap::iterator iter(mActors.begin());iter != mActors.end();++iter)
|
||||
{
|
||||
Movement movement;
|
||||
iter->second->update(duration, movement);
|
||||
mMovement.push_back(std::make_pair(iter->first, movement));
|
||||
}
|
||||
MWBase::Environment::get().getWorld()->doPhysics(mMovement, duration);
|
||||
|
||||
mMovement.clear();
|
||||
iter->second->update(duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,6 @@ namespace MWMechanics
|
|||
typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap;
|
||||
PtrControllerMap mActors;
|
||||
|
||||
MWWorld::PtrMovementList mMovement;
|
||||
|
||||
std::map<std::string, int> mDeathCount;
|
||||
|
||||
float mDuration;
|
||||
|
|
|
@ -663,9 +663,11 @@ bool CharacterController::updateNpcState(bool onground, bool inwater, bool isrun
|
|||
return forcestateupdate;
|
||||
}
|
||||
|
||||
void CharacterController::update(float duration, Movement &movement)
|
||||
void CharacterController::update(float duration)
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
const MWWorld::Class &cls = MWWorld::Class::get(mPtr);
|
||||
Ogre::Vector3 movement(0.0f);
|
||||
|
||||
if(!cls.isActor())
|
||||
{
|
||||
|
@ -684,8 +686,6 @@ void CharacterController::update(float duration, Movement &movement)
|
|||
}
|
||||
else if(!cls.getCreatureStats(mPtr).isDead())
|
||||
{
|
||||
MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
|
||||
bool onground = world->isOnGround(mPtr);
|
||||
bool inwater = world->isSwimming(mPtr);
|
||||
bool isrunning = cls.getStance(mPtr, MWWorld::Class::Run);
|
||||
|
@ -796,45 +796,41 @@ void CharacterController::update(float duration, Movement &movement)
|
|||
}
|
||||
}
|
||||
|
||||
vec *= duration;
|
||||
movement.mPosition[0] += vec.x;
|
||||
movement.mPosition[1] += vec.y;
|
||||
movement.mPosition[2] += vec.z;
|
||||
rot *= duration;
|
||||
movement.mRotation[0] += rot.x;
|
||||
movement.mRotation[1] += rot.y;
|
||||
movement.mRotation[2] += rot.z;
|
||||
|
||||
if(cls.isNpc())
|
||||
forcestateupdate = updateNpcState(onground, inwater, isrunning, sneak);
|
||||
|
||||
refreshCurrentAnims(idlestate, movestate, forcestateupdate);
|
||||
|
||||
rot *= duration * Ogre::Math::RadiansToDegrees(1.0f);
|
||||
world->rotateObject(mPtr, rot.x, rot.y, rot.z, true);
|
||||
|
||||
world->queueMovement(mPtr, vec);
|
||||
movement = vec;
|
||||
}
|
||||
else if(cls.getCreatureStats(mPtr).isDead())
|
||||
{
|
||||
MWBase::Environment::get().getWorld()->enableActorCollision(mPtr, false);
|
||||
world->queueMovement(mPtr, Ogre::Vector3(0.0f));
|
||||
}
|
||||
|
||||
if(mAnimation && !mSkipAnim)
|
||||
{
|
||||
Ogre::Vector3 moved = mAnimation->runAnimation(duration);
|
||||
Ogre::Vector3 moved = mAnimation->runAnimation(duration) / duration;
|
||||
// Ensure we're moving in generally the right direction
|
||||
if(mMovementSpeed > 0.f)
|
||||
{
|
||||
if((movement.mPosition[0] < 0.0f && movement.mPosition[0] < moved.x*2.0f) ||
|
||||
(movement.mPosition[0] > 0.0f && movement.mPosition[0] > moved.x*2.0f))
|
||||
moved.x = movement.mPosition[0];
|
||||
if((movement.mPosition[1] < 0.0f && movement.mPosition[1] < moved.y*2.0f) ||
|
||||
(movement.mPosition[1] > 0.0f && movement.mPosition[1] > moved.y*2.0f))
|
||||
moved.y = movement.mPosition[1];
|
||||
if((movement.mPosition[2] < 0.0f && movement.mPosition[2] < moved.z*2.0f) ||
|
||||
(movement.mPosition[2] > 0.0f && movement.mPosition[2] > moved.z*2.0f))
|
||||
moved.z = movement.mPosition[2];
|
||||
if((movement.x < 0.0f && movement.x < moved.x*2.0f) ||
|
||||
(movement.x > 0.0f && movement.x > moved.x*2.0f))
|
||||
moved.x = movement.x;
|
||||
if((movement.y < 0.0f && movement.y < moved.y*2.0f) ||
|
||||
(movement.y > 0.0f && movement.y > moved.y*2.0f))
|
||||
moved.y = movement.y;
|
||||
if((movement.z < 0.0f && movement.z < moved.z*2.0f) ||
|
||||
(movement.z > 0.0f && movement.z > moved.z*2.0f))
|
||||
moved.z = movement.z;
|
||||
}
|
||||
|
||||
movement.mPosition[0] = moved.x;
|
||||
movement.mPosition[1] = moved.y;
|
||||
movement.mPosition[2] = moved.z;
|
||||
if(moved.squaredLength() > 1.0f)
|
||||
world->queueMovement(mPtr, moved);
|
||||
}
|
||||
mSkipAnim = false;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ public:
|
|||
|
||||
void updatePtr(const MWWorld::Ptr &ptr);
|
||||
|
||||
void update(float duration, Movement &movement);
|
||||
void update(float duration);
|
||||
|
||||
void playGroup(const std::string &groupname, int mode, int count);
|
||||
void skipAnim();
|
||||
|
|
|
@ -65,10 +65,7 @@ void Objects::update(float duration, bool paused)
|
|||
if(!paused)
|
||||
{
|
||||
for(PtrControllerMap::iterator iter(mObjects.begin());iter != mObjects.end();++iter)
|
||||
{
|
||||
Movement movement;
|
||||
iter->second->update(duration, movement);
|
||||
}
|
||||
iter->second->update(duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ namespace MWWorld
|
|||
return position + (Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
|
||||
Ogre::Quaternion(Ogre::Radian(-refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
|
||||
Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
|
||||
movement;
|
||||
movement * time;
|
||||
}
|
||||
|
||||
btCollisionObject *colobj = physicActor->getCollisionBody();
|
||||
|
@ -140,7 +140,7 @@ namespace MWWorld
|
|||
velocity = (Ogre::Quaternion(Ogre::Radian( -refpos.rot[2]), Ogre::Vector3::UNIT_Z)*
|
||||
Ogre::Quaternion(Ogre::Radian( -refpos.rot[1]), Ogre::Vector3::UNIT_Y)*
|
||||
Ogre::Quaternion(Ogre::Radian( refpos.rot[0]), Ogre::Vector3::UNIT_X)) *
|
||||
movement / time;
|
||||
movement;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -150,7 +150,7 @@ namespace MWWorld
|
|||
if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope)
|
||||
onground = true;
|
||||
}
|
||||
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z)*movement / time;
|
||||
velocity = Ogre::Quaternion(Ogre::Radian(-refpos.rot[2]), Ogre::Vector3::UNIT_Z) * movement;
|
||||
velocity.z += physicActor->getVerticalForce();
|
||||
}
|
||||
|
||||
|
|
|
@ -1083,7 +1083,12 @@ namespace MWWorld
|
|||
--cellY;
|
||||
}
|
||||
|
||||
void World::doPhysics(const PtrMovementList &actors, float duration)
|
||||
void World::queueMovement(const Ptr &ptr, const Vector3 &velocity)
|
||||
{
|
||||
mPhysics->queueObjectMovement(ptr, velocity);
|
||||
}
|
||||
|
||||
void World::doPhysics(float duration)
|
||||
{
|
||||
/* No duration? Shouldn't be any movement, then. */
|
||||
if(duration <= 0.0f)
|
||||
|
@ -1091,8 +1096,9 @@ namespace MWWorld
|
|||
|
||||
processDoors(duration);
|
||||
|
||||
PtrMovementList::const_iterator player(actors.end());
|
||||
for(PtrMovementList::const_iterator iter(actors.begin());iter != actors.end();iter++)
|
||||
const PtrVelocityList &results = mPhysics->applyQueuedMovement(duration);
|
||||
PtrVelocityList::const_iterator player(results.end());
|
||||
for(PtrVelocityList::const_iterator iter(results.begin());iter != results.end();iter++)
|
||||
{
|
||||
if(iter->first.getRefData().getHandle() == "player")
|
||||
{
|
||||
|
@ -1100,23 +1106,12 @@ namespace MWWorld
|
|||
player = iter;
|
||||
continue;
|
||||
}
|
||||
|
||||
rotateObjectImp(iter->first, Ogre::Vector3(iter->second.mRotation), true);
|
||||
|
||||
Ogre::Vector3 vec = mPhysics->move(iter->first, Ogre::Vector3(iter->second.mPosition), duration,
|
||||
!isSwimming(iter->first) && !isFlying(iter->first));
|
||||
moveObjectImp(iter->first, vec.x, vec.y, vec.z);
|
||||
moveObjectImp(iter->first, iter->second.x, iter->second.y, iter->second.z);
|
||||
}
|
||||
if(player != actors.end())
|
||||
{
|
||||
rotateObjectImp(player->first, Ogre::Vector3(player->second.mRotation), true);
|
||||
if(player != results.end())
|
||||
moveObjectImp(player->first, player->second.x, player->second.y, player->second.z);
|
||||
|
||||
Ogre::Vector3 vec = mPhysics->move(player->first, Ogre::Vector3(player->second.mPosition), duration,
|
||||
!isSwimming(player->first) && !isFlying(player->first));
|
||||
moveObjectImp(player->first, vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
mPhysEngine->stepSimulation (duration);
|
||||
mPhysEngine->stepSimulation(duration);
|
||||
}
|
||||
|
||||
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
|
||||
|
@ -1261,6 +1256,8 @@ namespace MWWorld
|
|||
|
||||
mWorldScene->update (duration, paused);
|
||||
|
||||
doPhysics (duration);
|
||||
|
||||
performUpdateSceneQueries ();
|
||||
|
||||
updateWindowManager ();
|
||||
|
|
|
@ -106,6 +106,9 @@ namespace MWWorld
|
|||
void processDoors(float duration);
|
||||
///< Run physics simulation and modify \a world accordingly.
|
||||
|
||||
void doPhysics(float duration);
|
||||
///< Run physics simulation and modify \a world accordingly.
|
||||
|
||||
void ensureNeededRecords();
|
||||
|
||||
int mPlayIntro;
|
||||
|
@ -276,8 +279,9 @@ namespace MWWorld
|
|||
virtual void positionToIndex (float x, float y, int &cellX, int &cellY) const;
|
||||
///< Convert position to cell numbers
|
||||
|
||||
virtual void doPhysics(const PtrMovementList &actors, float duration);
|
||||
///< Run physics simulation and modify \a world accordingly.
|
||||
virtual void queueMovement(const Ptr &ptr, const Ogre::Vector3 &velocity);
|
||||
///< Queues movement for \a ptr (in local space), to be applied in the next call to
|
||||
/// doPhysics.
|
||||
|
||||
virtual bool castRay (float x1, float y1, float z1, float x2, float y2, float z2);
|
||||
///< cast a Ray and return true if there is an object in the ray path.
|
||||
|
|
Loading…
Reference in a new issue