Fix kart animation in networking

This commit is contained in:
Benau
2018-06-21 01:14:26 +08:00
parent cfbdc30c6b
commit 4d680c27f4
6 changed files with 82 additions and 21 deletions

View File

@@ -22,6 +22,9 @@
#include "karts/abstract_kart.hpp"
#include "karts/kart_model.hpp"
#include "karts/skidding.hpp"
#include "modes/world.hpp"
#include "network/network_config.hpp"
#include "network/rewind_manager.hpp"
#include "physics/physics.hpp"
/** Constructor. Note that kart can be NULL in case that the animation is
@@ -81,6 +84,49 @@ AbstractKartAnimation::~AbstractKartAnimation()
{
m_kart->getBody()->setAngularVelocity(btVector3(0,0,0));
Physics::getInstance()->addKart(m_kart);
if (NetworkConfig::get()->isNetworking() &&
NetworkConfig::get()->isClient() &&
!RewindManager::get()->isRewinding())
{
// ================================================================
class AnimationEvent : public RewindInfo
{
private:
AbstractKart* m_kart;
Vec3 m_linear_velocity, m_angular_velocity;
btTransform m_transform;
public:
AnimationEvent(AbstractKart* kart)
: RewindInfo(World::getWorld()->getTimeTicks(),
true/*is_confirmed*/)
{
m_kart = kart;
m_linear_velocity = m_kart->getBody()->getLinearVelocity();
m_angular_velocity =
m_kart->getBody()->getAngularVelocity();
m_transform = m_kart->getBody()->getWorldTransform();
}
// ------------------------------------------------------------
virtual void restore() {}
// ------------------------------------------------------------
virtual bool isEvent() const { return true; }
// ------------------------------------------------------------
virtual void undo()
{ Physics::getInstance()->removeKart(m_kart); }
// ------------------------------------------------------------
virtual void replay()
{
Physics::getInstance()->addKart(m_kart);
m_kart->getBody()->setLinearVelocity(m_linear_velocity);
m_kart->getBody()->setAngularVelocity(m_angular_velocity);
m_kart->getBody()->proceedToTransform(m_transform);
m_kart->setTrans(m_transform);
}
};
RewindManager::get()->getRewindQueue().insertRewindInfo
(new AnimationEvent(m_kart));
}
}
} // ~AbstractKartAnimation

View File

@@ -1310,7 +1310,7 @@ void Kart::update(int ticks)
// Moveable::update() ), otherwise 'stuttering' can happen (caused by
// graphical and physical position not being the same).
float dt = stk_config->ticks2Time(ticks);
if (has_animation_before)
if (has_animation_before && !RewindManager::get()->isRewinding())
{
m_kart_animation->update(dt);
}

View File

@@ -59,13 +59,15 @@ void KartRewinder::reset()
*/
void KartRewinder::saveTransform()
{
Moveable::prepareSmoothing();
if (!getKartAnimation())
Moveable::prepareSmoothing();
} // saveTransform
// ----------------------------------------------------------------------------
void KartRewinder::computeError()
{
Moveable::checkSmoothing();
if (!getKartAnimation())
Moveable::checkSmoothing();
} // computeError
// ----------------------------------------------------------------------------
@@ -133,15 +135,22 @@ void KartRewinder::restoreState(BareNetworkString *buffer, int count)
t.setOrigin(buffer->getVec3());
t.setRotation(buffer->getQuat());
btRigidBody *body = getBody();
body->setLinearVelocity(buffer->getVec3());
body->setAngularVelocity(buffer->getVec3());
Vec3 lv = buffer->getVec3();
Vec3 av = buffer->getVec3();
// Don't restore to phyics position if showing kart animation
if (!getKartAnimation())
{
body->setLinearVelocity(lv);
body->setAngularVelocity(av);
// This function also reads the velocity, so it must be called
// after the velocities are set
body->proceedToTransform(t);
// Update kart transform in case that there are access to its value
// before Moveable::update() is called (which updates the transform)
setTrans(t);
}
// This function also reads the velocity, so it must be called
// after the velocities are set
body->proceedToTransform(t);
// Update kart transform in case that there are access to its value
// before Moveable::update() is called (which updates the transform)
setTrans(t);
m_has_started = buffer->getUInt8()!=0; // necessary for startup speed boost
m_vehicle->setMinSpeed(buffer->getFloat());
float time_rot = buffer->getFloat();

View File

@@ -169,7 +169,8 @@ public:
{
return m_not_rewound_ticks.load(std::memory_order_relaxed);
} // getNotRewoundWorldTicks
// ------------------------------------------------------------------------
RewindQueue& getRewindQueue() { return m_rewind_queue; }
// ------------------------------------------------------------------------
/** Returns the time of the latest confirmed state. */
int getLatestConfirmedState() const

View File

@@ -57,7 +57,6 @@ private:
int m_latest_confirmed_state_time;
void insertRewindInfo(RewindInfo *ri);
void cleanupOldRewindInfo(int ticks);
public:
@@ -78,6 +77,7 @@ public:
bool isEmpty() const;
bool hasMoreRewindInfo() const;
int undoUntil(int undo_ticks);
void insertRewindInfo(RewindInfo *ri);
// ------------------------------------------------------------------------
/** Returns the time of the latest confirmed state. */

View File

@@ -32,7 +32,7 @@
#include "karts/skidding.hpp"
#include "modes/profile_world.hpp"
#include "modes/world.hpp"
#include "network/rewind_manager.hpp"
/** Constructor for a check cannon.
* \param node XML node containing the parameters for this checkline.
@@ -167,11 +167,13 @@ void CheckCannon::update(float dt)
if(!triggered) continue;
// Cross the checkline - add the cannon animation
CannonAnimation *animation =
new CannonAnimation(m_all_flyables[i], m_curve->clone(),
getLeftPoint(), getRightPoint(),
m_target_left, m_target_right);
m_all_flyables[i]->setAnimation(animation);
if (!RewindManager::get()->isRewinding())
{
CannonAnimation* animation = new CannonAnimation(m_all_flyables[i],
m_curve->clone(), getLeftPoint(), getRightPoint(),
m_target_left, m_target_right);
m_all_flyables[i]->setAnimation(animation);
}
} // for i in all flyables
} // update
// ----------------------------------------------------------------------------
@@ -191,6 +193,9 @@ void CheckCannon::trigger(unsigned int kart_index)
// order to smooth rotate the kart, we need to keep the current visual
// rotation and pass it to the CannonAnimation.
float skid_rot = kart->getSkidding()->getVisualSkidRotation();
new CannonAnimation(kart, m_curve->clone(), getLeftPoint(), getRightPoint(),
m_target_left, m_target_right, skid_rot);
if (!RewindManager::get()->isRewinding())
{
new CannonAnimation(kart, m_curve->clone(), getLeftPoint(),
getRightPoint(), m_target_left, m_target_right, skid_rot);
}
} // CheckCannon