* 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 // make sure initialization was called properly
assert( m_BufferFrame.getNumberObjectsUsed() == m_BufferKartState.getNumberArraysUsed() ); assert( m_BufferFrame.getNumberObjectsUsed() == m_BufferKartState.getNumberArraysUsed() );
if( !isHealthy() ) return false; if( !isHealthy() ) return NULL;
ReplayFrame* frame = m_BufferFrame.getNewObject(); ReplayFrame* frame = m_BufferFrame.getNewObject();
if( !frame ) return NULL; if( !frame ) return NULL;

View File

@ -95,13 +95,13 @@ bool ReplayPlayer::loadReplayHumanReadable( FILE *fd )
if( !m_ReplayBuffers.loadReplayHumanReadable( fd, number_karts ) ) return false; if( !m_ReplayBuffers.loadReplayHumanReadable( fd, number_karts ) ) return false;
m_current_frame_index = 0; m_current_frame_index = 0;
updateObjects();
return true; return true;
} }
void ReplayPlayer::showReplayAt( float abs_time ) void ReplayPlayer::showReplayAt( float abs_time )
{ {
assert( m_ReplayBuffers.getNumberFrames() );
assert( m_current_frame_index > -1 ); assert( m_current_frame_index > -1 );
assert( (size_t)m_current_frame_index < m_ReplayBuffers.getNumberFrames() ); assert( (size_t)m_current_frame_index < m_ReplayBuffers.getNumberFrames() );
@ -120,18 +120,50 @@ void ReplayPlayer::showReplayAt( float abs_time )
++m_current_frame_index; ++m_current_frame_index;
} }
updateObjects(); frame = m_ReplayBuffers.getFrameAt( m_current_frame_index );
}
void ReplayPlayer::updateObjects() // interpolate, if we are not at the end
if( (m_current_frame_index + 1) < (int)m_ReplayBuffers.getNumberFrames() )
{ {
ReplayFrame const* frame = m_ReplayBuffers.getFrameAt( m_current_frame_index ); 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 ) for( size_t k = 0; k < m_Karts.size(); ++k )
{ {
m_Karts[ k ].setPosition( frame->p_kart_states[ k ].position ); m_Karts[ k ].setPosition( frame->p_kart_states[ k ].position );
} }
} }
}
#endif // HAVE_GHOST_REPLAY #endif // HAVE_GHOST_REPLAY

View File

@ -70,10 +70,10 @@ public:
bool loadReplayHumanReadable( FILE *fd ); bool loadReplayHumanReadable( FILE *fd );
// calc state of replay-objects at given time
void showReplayAt( float abs_time ); void showReplayAt( float abs_time );
private: void reset() { m_current_frame_index = 0; }
void updateObjects();
private: private:
typedef std::vector<ReplayKart> ReplayKarts; 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; delete m_p_replay_player;
m_p_replay_player = NULL; 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 #endif
} }
@ -419,7 +419,7 @@ void World::update(float delta)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void World::pushReplayFrameData() void World::pushReplayFrameData()
{ {
// we dpnt record the startphase .. // we dont record the startphase ..
assert( m_phase != START_PHASE ); assert( m_phase != START_PHASE );
ReplayFrame *pFrame = m_replay_recorder.getNewFrame(); ReplayFrame *pFrame = m_replay_recorder.getNewFrame();
@ -890,6 +890,17 @@ void World::restartRace()
herring_manager->reset(); herring_manager->reset();
projectile_manager->cleanup(); projectile_manager->cleanup();
race_manager->reset(); 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
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------