From 2860414a0cad57673093401d2f1dcbb564c72707 Mon Sep 17 00:00:00 2001 From: ikework Date: Fri, 21 Sep 2007 19:17:48 +0000 Subject: [PATCH] replay: * 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 --- src/replay_buffers.cpp | 2 +- src/replay_player.cpp | 50 ++++++++++++++++++++++++++++++++++-------- src/replay_player.hpp | 4 ++-- src/world.cpp | 15 +++++++++++-- 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/replay_buffers.cpp b/src/replay_buffers.cpp index f714123c0..e58f981b1 100644 --- a/src/replay_buffers.cpp +++ b/src/replay_buffers.cpp @@ -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; diff --git a/src/replay_player.cpp b/src/replay_player.cpp index 1b94bee5a..a325f4e29 100644 --- a/src/replay_player.cpp +++ b/src/replay_player.cpp @@ -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 ); + } + } + } diff --git a/src/replay_player.hpp b/src/replay_player.hpp index e753e04eb..1586ec728 100644 --- a/src/replay_player.hpp +++ b/src/replay_player.hpp @@ -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 ReplayKarts; diff --git a/src/world.cpp b/src/world.cpp index 8afc449e0..3e1617366 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -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 } //-----------------------------------------------------------------------------