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:
parent
cb46fad124
commit
891df54f3a
@ -52,8 +52,9 @@
|
|||||||
#include "karts/max_speed.hpp"
|
#include "karts/max_speed.hpp"
|
||||||
#include "karts/skidding.hpp"
|
#include "karts/skidding.hpp"
|
||||||
#include "modes/linear_world.hpp"
|
#include "modes/linear_world.hpp"
|
||||||
#include "network/race_state.hpp"
|
|
||||||
#include "network/network_manager.hpp"
|
#include "network/network_manager.hpp"
|
||||||
|
#include "network/rewind_manager.hpp"
|
||||||
|
#include "network/race_state.hpp"
|
||||||
#include "physics/btKart.hpp"
|
#include "physics/btKart.hpp"
|
||||||
#include "physics/btKartRaycast.hpp"
|
#include "physics/btKartRaycast.hpp"
|
||||||
#include "physics/btUprightConstraint.hpp"
|
#include "physics/btUprightConstraint.hpp"
|
||||||
@ -530,7 +531,7 @@ void Kart::blockViewWithPlunger()
|
|||||||
if(isShielded())
|
if(isShielded())
|
||||||
{
|
{
|
||||||
decreaseShieldTime(0.0f); //decrease the default amount of time
|
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
|
} // blockViewWithPlunger
|
||||||
|
|
||||||
@ -1088,7 +1089,7 @@ void Kart::update(float dt)
|
|||||||
// Update the position and other data taken from the physics
|
// Update the position and other data taken from the physics
|
||||||
Moveable::update(dt);
|
Moveable::update(dt);
|
||||||
|
|
||||||
if(!history->replayHistory())
|
if(!history->replayHistory() && !RewindManager::get()->isRewinding())
|
||||||
m_controller->update(dt);
|
m_controller->update(dt);
|
||||||
|
|
||||||
// if its view is blocked by plunger, decrease remaining time
|
// if its view is blocked by plunger, decrease remaining time
|
||||||
@ -1362,7 +1363,7 @@ void Kart::setSquash(float time, float slowdown)
|
|||||||
if (isShielded())
|
if (isShielded())
|
||||||
{
|
{
|
||||||
decreaseShieldTime(stk_config->m_bubblegum_shield_time/2.0f);
|
decreaseShieldTime(stk_config->m_bubblegum_shield_time/2.0f);
|
||||||
Log::verbose("Kart", "Decreasing shield \n");
|
Log::verbose("Kart", "Decreasing shield");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2043,7 +2044,7 @@ void Kart::updatePhysics(float dt)
|
|||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // updatePhysics
|
} // updatephysics
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/** Adjust the engine sound effect depending on the speed of the kart.
|
/** Adjust the engine sound effect depending on the speed of the kart.
|
||||||
|
@ -93,7 +93,7 @@ void KartRewinder::update()
|
|||||||
m_previous_control.copyToMemory(buffer);
|
m_previous_control.copyToMemory(buffer);
|
||||||
|
|
||||||
// The rewind manager will free the memory once it's not needed anymore
|
// 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
|
} // update
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -827,11 +827,12 @@ void World::update(float dt)
|
|||||||
if(ReplayRecorder::get()) ReplayRecorder::get()->update(dt);
|
if(ReplayRecorder::get()) ReplayRecorder::get()->update(dt);
|
||||||
if(ReplayPlay::get()) ReplayPlay::get()->update(dt);
|
if(ReplayPlay::get()) ReplayPlay::get()->update(dt);
|
||||||
if(history->replayHistory()) dt=history->getNextDelta();
|
if(history->replayHistory()) dt=history->getNextDelta();
|
||||||
WorldStatus::update(dt);
|
|
||||||
// Clear race state so that new information can be stored
|
// Clear race state so that new information can be stored
|
||||||
race_state->clear();
|
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 &&
|
if(network_manager->getMode()!=NetworkManager::NW_CLIENT &&
|
||||||
|
@ -49,12 +49,12 @@ void RewindManager::destroy()
|
|||||||
* for all state info.
|
* for all state info.
|
||||||
* \param size Necessary buffer size for a state.
|
* \param size Necessary buffer size for a state.
|
||||||
*/
|
*/
|
||||||
RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, float time,
|
RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, char *buffer,
|
||||||
char *buffer, bool is_event,
|
bool is_event, bool is_confirmed)
|
||||||
bool is_confirmed)
|
|
||||||
{
|
{
|
||||||
m_rewinder = rewinder;
|
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_local_physics_time = World::getWorld()->getPhysics()->getPhysicsWorld()->getLocalTime();
|
||||||
m_buffer = buffer;
|
m_buffer = buffer;
|
||||||
m_type = is_event ? RIT_EVENT : RIT_STATE;
|
m_type = is_event ? RIT_EVENT : RIT_STATE;
|
||||||
@ -62,10 +62,11 @@ RewindManager::RewindInfo::RewindInfo(Rewinder *rewinder, float time,
|
|||||||
} // RewindInfo
|
} // RewindInfo
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
RewindManager::RewindInfo::RewindInfo(float time)
|
RewindManager::RewindInfo::RewindInfo()
|
||||||
{
|
{
|
||||||
m_rewinder = NULL;
|
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_local_physics_time = World::getWorld()->getPhysics()->getPhysicsWorld()->getLocalTime();
|
||||||
m_buffer = NULL;
|
m_buffer = NULL;
|
||||||
m_type = RIT_TIME;
|
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 time Time at which the event was recorded.
|
||||||
* \param buffer Pointer to the event data.
|
* \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;
|
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);
|
/*is_confirmed*/true);
|
||||||
insertRewindInfo(ri);
|
insertRewindInfo(ri);
|
||||||
} // addEvent
|
} // addEvent
|
||||||
@ -233,7 +234,7 @@ void RewindManager::addEvent(Rewinder *rewinder, float time, char *buffer)
|
|||||||
* rewinder to do so.
|
* rewinder to do so.
|
||||||
* \param dt Time step size.
|
* \param dt Time step size.
|
||||||
*/
|
*/
|
||||||
void RewindManager::saveStates(float dt)
|
void RewindManager::saveStates()
|
||||||
{
|
{
|
||||||
if(!m_enable_rewind_manager ||
|
if(!m_enable_rewind_manager ||
|
||||||
m_all_rewinder.size()==0 ||
|
m_all_rewinder.size()==0 ||
|
||||||
@ -242,7 +243,7 @@ void RewindManager::saveStates(float dt)
|
|||||||
float time = World::getWorld()->getTime();
|
float time = World::getWorld()->getTime();
|
||||||
if(time - m_last_saved_state < m_state_frequency)
|
if(time - m_last_saved_state < m_state_frequency)
|
||||||
{
|
{
|
||||||
RewindInfo *ri = new RewindInfo(World::getWorld()->getTime());
|
RewindInfo *ri = new RewindInfo();
|
||||||
insertRewindInfo(ri);
|
insertRewindInfo(ri);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -255,7 +256,7 @@ void RewindManager::saveStates(float dt)
|
|||||||
if(size>=0)
|
if(size>=0)
|
||||||
{
|
{
|
||||||
m_overall_state_size += size;
|
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_event*/false,
|
||||||
/*is_confirmed*/true);
|
/*is_confirmed*/true);
|
||||||
assert(ri);
|
assert(ri);
|
||||||
@ -324,11 +325,6 @@ void RewindManager::rewindTo(float rewind_time)
|
|||||||
// current time.
|
// current time.
|
||||||
// TODO: this assumes atm that all rewinder have a initial state
|
// TODO: this assumes atm that all rewinder have a initial state
|
||||||
// for 'current_time'!!!
|
// 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
|
// Store the time to which we have to replay to
|
||||||
float current_time = World::getWorld()->getTime();
|
float current_time = World::getWorld()->getTime();
|
||||||
@ -337,27 +333,15 @@ void RewindManager::rewindTo(float rewind_time)
|
|||||||
|
|
||||||
// Now go forward through the saved states, and
|
// Now go forward through the saved states, and
|
||||||
// replay taking the events into account.
|
// replay taking the events into account.
|
||||||
while(World::getWorld()->getTime() < current_time &&
|
while( World::getWorld()->getTime() < current_time &&
|
||||||
state < (int)m_rewind_info.size())
|
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 dt = determineTimeStepSize(state, current_time);
|
||||||
float next_time = World::getWorld()->getTime() + dt;
|
|
||||||
// Now set all events and confirmed states
|
// Now set all events and confirmed states
|
||||||
while(state < (int)m_rewind_info.size() &&
|
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() ||
|
if(m_rewind_info[state]->isEvent() ||
|
||||||
m_rewind_info[state]->isConfirmed() )
|
m_rewind_info[state]->isConfirmed() )
|
||||||
@ -388,6 +372,8 @@ void RewindManager::rewindTo(float rewind_time)
|
|||||||
*/
|
*/
|
||||||
float RewindManager::determineTimeStepSize(int next_state, float end_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();
|
return m_rewind_info[next_state]->getTime()-World::getWorld()->getTime();
|
||||||
|
|
||||||
float dt = 1.0f/60.0f;
|
float dt = 1.0f/60.0f;
|
||||||
|
@ -108,6 +108,9 @@ private:
|
|||||||
/** Time when this state was taken. */
|
/** Time when this state was taken. */
|
||||||
float m_time;
|
float m_time;
|
||||||
|
|
||||||
|
/** Time step size. */
|
||||||
|
float m_time_step;
|
||||||
|
|
||||||
/** The 'left over' time from the physics. */
|
/** The 'left over' time from the physics. */
|
||||||
float m_local_physics_time;
|
float m_local_physics_time;
|
||||||
|
|
||||||
@ -122,10 +125,10 @@ private:
|
|||||||
/** The Rewinder instance for which this data is. */
|
/** The Rewinder instance for which this data is. */
|
||||||
Rewinder *m_rewinder;
|
Rewinder *m_rewinder;
|
||||||
public:
|
public:
|
||||||
RewindInfo(Rewinder *rewinder, float time, char *buffer,
|
RewindInfo(Rewinder *rewinder, char *buffer,
|
||||||
bool is_event, bool is_confirmed);
|
bool is_event, bool is_confirmed);
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
RewindInfo(float time);
|
RewindInfo();
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
~RewindInfo()
|
~RewindInfo()
|
||||||
{
|
{
|
||||||
@ -138,6 +141,9 @@ private:
|
|||||||
/** Returns the time at which this rewind state was saved. */
|
/** Returns the time at which this rewind state was saved. */
|
||||||
float getTime() const { return m_time; }
|
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 isEvent() const { return m_type==RIT_EVENT; }
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
bool isTime() const { return m_type==RIT_TIME; }
|
bool isTime() const { return m_type==RIT_TIME; }
|
||||||
@ -203,6 +209,15 @@ private:
|
|||||||
/** Time at which the last state was saved. */
|
/** Time at which the last state was saved. */
|
||||||
float m_last_saved_state;
|
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
|
#define REWIND_SEARCH_STATS
|
||||||
|
|
||||||
#ifdef REWIND_SEARCH_STATS
|
#ifdef REWIND_SEARCH_STATS
|
||||||
@ -223,6 +238,24 @@ public:
|
|||||||
static RewindManager *create();
|
static RewindManager *create();
|
||||||
static void destroy();
|
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. */
|
/** En- or disables rewinding. */
|
||||||
static void setEnable(bool m) { m_enable_rewind_manager = m;}
|
static void setEnable(bool m) { m_enable_rewind_manager = m;}
|
||||||
|
|
||||||
@ -242,7 +275,9 @@ public:
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
void reset();
|
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.
|
/** Adds a Rewinder to the list of all rewinders.
|
||||||
* \return true If rewinding is enabled, false otherwise.
|
* \return true If rewinding is enabled, false otherwise.
|
||||||
@ -254,9 +289,8 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
} // addRewinder
|
} // addRewinder
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
void rewindTo(float target_time);
|
/** Returns true if currently a rewind is happening. */
|
||||||
// ------------------------------------------------------------------------
|
bool isRewinding() const { return m_is_rewinding; }
|
||||||
void addEvent(Rewinder *rewinder, float time, char *buffer);
|
|
||||||
}; // RewindManager
|
}; // RewindManager
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user