* interpolation between sampled frames
* restart game works with replay

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@1254 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
ikework 2007-09-21 19:17:48 +00:00
parent 0a44bf57d5
commit 2860414a0c
4 changed files with 57 additions and 14 deletions

View File

@ -43,7 +43,7 @@ ReplayBuffers::getNewFrame()
// make sure initialization was called properly
assert( m_BufferFrame.getNumberObjectsUsed() == m_BufferKartState.getNumberArraysUsed() );
if( !isHealthy() ) return false;
if( !isHealthy() ) return NULL;
ReplayFrame* frame = m_BufferFrame.getNewObject();
if( !frame ) return NULL;

View File

@ -95,13 +95,13 @@ bool ReplayPlayer::loadReplayHumanReadable( FILE *fd )
if( !m_ReplayBuffers.loadReplayHumanReadable( fd, number_karts ) ) return false;
m_current_frame_index = 0;
updateObjects();
return true;
}
void ReplayPlayer::showReplayAt( float abs_time )
{
assert( m_ReplayBuffers.getNumberFrames() );
assert( m_current_frame_index > -1 );
assert( (size_t)m_current_frame_index < m_ReplayBuffers.getNumberFrames() );
@ -120,17 +120,49 @@ void ReplayPlayer::showReplayAt( float abs_time )
++m_current_frame_index;
}
updateObjects();
}
frame = m_ReplayBuffers.getFrameAt( m_current_frame_index );
void ReplayPlayer::updateObjects()
{
ReplayFrame const* frame = m_ReplayBuffers.getFrameAt( m_current_frame_index );
for( size_t k = 0; k < m_Karts.size(); ++k )
// interpolate, if we are not at the end
if( (m_current_frame_index + 1) < (int)m_ReplayBuffers.getNumberFrames() )
{
m_Karts[ k ].setPosition( frame->p_kart_states[ k ].position );
ReplayFrame const* frame_next = m_ReplayBuffers.getFrameAt( m_current_frame_index+1 );
sgVec3 tmp_v3;
float scale;
sgCoord pos;
// calc interpolations for all objects
for( size_t k = 0; k < m_Karts.size(); ++k )
{
// calc distance between next and current frame-position
sgCopyVec3( pos.xyz, frame->p_kart_states[k].position.xyz ) ;
sgCopyVec3( tmp_v3, frame_next->p_kart_states[k].position.xyz ) ;
sgSubVec3( tmp_v3, pos.xyz );
// calc scale factor based on time between frames
assert( frame_next->time > frame->time );
assert( frame_next->time != frame->time );
scale = (abs_time - frame->time) / (frame_next->time - frame->time);
sgScaleVec3( tmp_v3, scale );
// add interpolated vector
sgAddVec3( pos.xyz, tmp_v3 );
// no orientation-interpolation for starters
sgCopyVec3( pos.hpr, frame->p_kart_states[k].position.hpr );
m_Karts[ k ].setPosition( pos );
}
}
else
{
// replay finished, leave them at last known position
for( size_t k = 0; k < m_Karts.size(); ++k )
{
m_Karts[ k ].setPosition( frame->p_kart_states[ k ].position );
}
}
}

View File

@ -70,10 +70,10 @@ public:
bool loadReplayHumanReadable( FILE *fd );
// calc state of replay-objects at given time
void showReplayAt( float abs_time );
private:
void updateObjects();
void reset() { m_current_frame_index = 0; }
private:
typedef std::vector<ReplayKart> ReplayKarts;

View File

@ -213,7 +213,7 @@ World::World(const RaceSetup& raceSetup_) : m_race_setup(raceSetup_)
delete m_p_replay_player;
m_p_replay_player = NULL;
}
if( m_p_replay_player ) m_p_replay_player->showReplayAt( m_clock );
if( m_p_replay_player ) m_p_replay_player->showReplayAt( 0.0 );
#endif
}
@ -419,7 +419,7 @@ void World::update(float delta)
//-----------------------------------------------------------------------------
void World::pushReplayFrameData()
{
// we dpnt record the startphase ..
// we dont record the startphase ..
assert( m_phase != START_PHASE );
ReplayFrame *pFrame = m_replay_recorder.getNewFrame();
@ -890,6 +890,17 @@ void World::restartRace()
herring_manager->reset();
projectile_manager->cleanup();
race_manager->reset();
#ifdef HAVE_GHOST_REPLAY
m_replay_recorder.destroy();
m_replay_recorder.initRecorder( m_race_setup.getNumKarts() );
if( m_p_replay_player )
{
m_p_replay_player->reset();
m_p_replay_player->showReplayAt( 0.0 );
}
#endif
}
//-----------------------------------------------------------------------------