Fixed rewind (events had a time stamp after increasing world clock,

while states had a time stamp before world clock was updated).
Still all work in progress ;)


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/rewind@14138 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2013-09-23 06:57:32 +00:00
parent cb46fad124
commit 891df54f3a
5 changed files with 68 additions and 46 deletions

View File

@ -52,8 +52,9 @@
#include "karts/max_speed.hpp"
#include "karts/skidding.hpp"
#include "modes/linear_world.hpp"
#include "network/race_state.hpp"
#include "network/network_manager.hpp"
#include "network/rewind_manager.hpp"
#include "network/race_state.hpp"
#include "physics/btKart.hpp"
#include "physics/btKartRaycast.hpp"
#include "physics/btUprightConstraint.hpp"
@ -530,7 +531,7 @@ void Kart::blockViewWithPlunger()
if(isShielded())
{
decreaseShieldTime(0.0f); //decrease the default amount of time
Log::verbose("Kart", "Decreasing shield, because of removing the plunger. \n");
Log::verbose("Kart", "Decreasing shield, because of removing the plunger.");
}
} // blockViewWithPlunger
@ -1088,7 +1089,7 @@ void Kart::update(float dt)
// Update the position and other data taken from the physics
Moveable::update(dt);
if(!history->replayHistory())
if(!history->replayHistory() && !RewindManager::get()->isRewinding())
m_controller->update(dt);
// if its view is blocked by plunger, decrease remaining time
@ -1362,7 +1363,7 @@ void Kart::setSquash(float time, float slowdown)
if (isShielded())
{
decreaseShieldTime(stk_config->m_bubblegum_shield_time/2.0f);
Log::verbose("Kart", "Decreasing shield \n");
Log::verbose("Kart", "Decreasing shield");
return;
}
@ -2043,7 +2044,7 @@ void Kart::updatePhysics(float dt)
);
#endif
} // updatePhysics
} // updatephysics
//-----------------------------------------------------------------------------
/** Adjust the engine sound effect depending on the speed of the kart.

View File

@ -93,7 +93,7 @@ void KartRewinder::update()
m_previous_control.copyToMemory(buffer);
// The rewind manager will free the memory once it's not needed anymore
RewindManager::get()->addEvent(this, World::getWorld()->getTime(), buffer);
RewindManager::get()->addEvent(this, buffer);
} // update
// ----------------------------------------------------------------------------

View File

@ -827,11 +827,12 @@ void World::update(float dt)
if(ReplayRecorder::get()) ReplayRecorder::get()->update(dt);
if(ReplayPlay::get()) ReplayPlay::get()->update(dt);
if(history->replayHistory()) dt=history->getNextDelta();
WorldStatus::update(dt);
// Clear race state so that new information can be stored
race_state->clear();
RewindManager::get()->saveStates(dt);
RewindManager::get()->setCurrentTime(World::getWorld()->getTime(), dt);
RewindManager::get()->saveStates();
WorldStatus::update(dt);
if(network_manager->getMode()!=NetworkManager::NW_CLIENT &&

View File

@ -49,12 +49,12 @@ void RewindManager::destroy()
* for all state info.
* \param size Necessary buffer size for a state.
*/
RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, float time,
char *buffer, bool is_event,
bool is_confirmed)
RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, char *buffer,
bool is_event, bool is_confirmed)
{
m_rewinder = rewinder;
m_time = time;
m_time = RewindManager::get()->getCurrentTime();;
m_time_step = RewindManager::get()->getCurrentTimeStep();
m_local_physics_time = World::getWorld()->getPhysics()->getPhysicsWorld()->getLocalTime();
m_buffer = buffer;
m_type = is_event ? RIT_EVENT : RIT_STATE;
@ -62,10 +62,11 @@ RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, float time,
} // RewindInfo
// ----------------------------------------------------------------------------
RewindManager::RewindInfo::RewindInfo(float time)
RewindManager::RewindInfo::RewindInfo()
{
m_rewinder = NULL;
m_time = time;
m_time = RewindManager::get()->getCurrentTime();
m_time_step = RewindManager::get()->getCurrentTimeStep();
m_local_physics_time = World::getWorld()->getPhysics()->getPhysicsWorld()->getLocalTime();
m_buffer = NULL;
m_type = RIT_TIME;
@ -220,10 +221,10 @@ unsigned int RewindManager::findFirstIndex(float target_time) const
* \param time Time at which the event was recorded.
* \param buffer Pointer to the event data.
*/
void RewindManager::addEvent(Rewinder *rewinder, float time, char *buffer)
void RewindManager::addEvent(Rewinder *rewinder, char *buffer)
{
if(m_is_rewinding) return;
RewindInfo *ri = new RewindInfo(rewinder, time, buffer, /*is_event*/true,
RewindInfo *ri = new RewindInfo(rewinder, buffer, /*is_event*/true,
/*is_confirmed*/true);
insertRewindInfo(ri);
} // addEvent
@ -233,7 +234,7 @@ void RewindManager::addEvent(Rewinder *rewinder, float time, char *buffer)
* rewinder to do so.
* \param dt Time step size.
*/
void RewindManager::saveStates(float dt)
void RewindManager::saveStates()
{
if(!m_enable_rewind_manager ||
m_all_rewinder.size()==0 ||
@ -242,7 +243,7 @@ void RewindManager::saveStates(float dt)
float time = World::getWorld()->getTime();
if(time - m_last_saved_state < m_state_frequency)
{
RewindInfo *ri = new RewindInfo(World::getWorld()->getTime());
RewindInfo *ri = new RewindInfo();
insertRewindInfo(ri);
return;
}
@ -255,7 +256,7 @@ void RewindManager::saveStates(float dt)
if(size>=0)
{
m_overall_state_size += size;
RewindInfo *ri = new RewindInfo(m_all_rewinder[i], time, p,
RewindInfo *ri = new RewindInfo(m_all_rewinder[i], p,
/*is_event*/false,
/*is_confirmed*/true);
assert(ri);
@ -324,11 +325,6 @@ void RewindManager::rewindTo(float rewind_time)
// current time.
// TODO: this assumes atm that all rewinder have a initial state
// for 'current_time'!!!
while(m_rewind_info[state]->getTime()==exact_rewind_time)
{
m_rewind_info[state]->rewind();
state ++;
} // while rewind info at time current_time
// Store the time to which we have to replay to
float current_time = World::getWorld()->getTime();
@ -337,27 +333,15 @@ void RewindManager::rewindTo(float rewind_time)
// Now go forward through the saved states, and
// replay taking the events into account.
while(World::getWorld()->getTime() < current_time &&
state < (int)m_rewind_info.size())
while( World::getWorld()->getTime() < current_time &&
state < (int)m_rewind_info.size() )
{
// Find the next RewindInfo which needs to be taken into account
// All other states can be deleted
// TODO ... for now
int next_important_state = state;
while(next_important_state < (int)m_rewind_info.size() &&
m_rewind_info[next_important_state]->isState() &&
!m_rewind_info[next_important_state]->isConfirmed() )
{
// TODO discard/replace state
next_important_state ++;
}
float dt = determineTimeStepSize(state, current_time);
float next_time = World::getWorld()->getTime() + dt;
// Now set all events and confirmed states
while(state < (int)m_rewind_info.size() &&
m_rewind_info[state]->getTime() <= next_time)
m_rewind_info[state]->getTime()<=World::getWorld()->getTime()+0.001f)
{
if(m_rewind_info[state]->isEvent() ||
m_rewind_info[state]->isConfirmed() )
@ -388,6 +372,8 @@ void RewindManager::rewindTo(float rewind_time)
*/
float RewindManager::determineTimeStepSize(int next_state, float end_time)
{
return m_rewind_info[next_state]->getTimeStep();
return m_rewind_info[next_state]->getTime()-World::getWorld()->getTime();
float dt = 1.0f/60.0f;

View File

@ -108,6 +108,9 @@ private:
/** Time when this state was taken. */
float m_time;
/** Time step size. */
float m_time_step;
/** The 'left over' time from the physics. */
float m_local_physics_time;
@ -122,10 +125,10 @@ private:
/** The Rewinder instance for which this data is. */
Rewinder *m_rewinder;
public:
RewindInfo(Rewinder *rewinder, float time, char *buffer,
RewindInfo(Rewinder *rewinder, char *buffer,
bool is_event, bool is_confirmed);
// --------------------------------------------------------------------
RewindInfo(float time);
RewindInfo();
// --------------------------------------------------------------------
~RewindInfo()
{
@ -138,6 +141,9 @@ private:
/** Returns the time at which this rewind state was saved. */
float getTime() const { return m_time; }
// --------------------------------------------------------------------
/** Time step size. */
float getTimeStep() const { return m_time_step; }
// --------------------------------------------------------------------
bool isEvent() const { return m_type==RIT_EVENT; }
// --------------------------------------------------------------------
bool isTime() const { return m_type==RIT_TIME; }
@ -203,6 +209,15 @@ private:
/** Time at which the last state was saved. */
float m_last_saved_state;
/** The current time to be used in all states/events. This is used to
* give all states and events during one frame the same time, even
* if e.g. states are saved before world time is increased, other
* events later. */
float m_current_time;
/** The current time step size. */
float m_time_step;
#define REWIND_SEARCH_STATS
#ifdef REWIND_SEARCH_STATS
@ -223,6 +238,24 @@ public:
static RewindManager *create();
static void destroy();
// ------------------------------------------------------------------------
/** Sets the time that is to be used for all further states or events,
* and the time step size. This is necessary so that states/events before
* and after World::m_time is increased have the same time stamp.
* \param t Time.
* \param dt Time step size.
*/
void setCurrentTime(float t, float dt)
{
m_current_time = t;
m_time_step = dt;
} // setCurrentTime
// ------------------------------------------------------------------------
/** Returns the current time. */
float getCurrentTime() const { return m_current_time; }
// ------------------------------------------------------------------------
float getCurrentTimeStep() const { return m_time_step; }
// ------------------------------------------------------------------------
/** En- or disables rewinding. */
static void setEnable(bool m) { m_enable_rewind_manager = m;}
@ -242,7 +275,9 @@ public:
// ------------------------------------------------------------------------
void reset();
void saveStates(float dt);
void saveStates();
void rewindTo(float target_time);
void addEvent(Rewinder *rewinder, char *buffer);
// ------------------------------------------------------------------------
/** Adds a Rewinder to the list of all rewinders.
* \return true If rewinding is enabled, false otherwise.
@ -254,9 +289,8 @@ public:
return true;
} // addRewinder
// ------------------------------------------------------------------------
void rewindTo(float target_time);
// ------------------------------------------------------------------------
void addEvent(Rewinder *rewinder, float time, char *buffer);
/** Returns true if currently a rewind is happening. */
bool isRewinding() const { return m_is_rewinding; }
}; // RewindManager