Improvements to finish time accuracy (#3273)
* Add time info for recent positions * More accurate finish time * Rebase changes on the version with overrides
This commit is contained in:
parent
6444405479
commit
670a40cb05
@ -489,6 +489,9 @@ public:
|
||||
/** Returns the most recent different previous position */
|
||||
virtual const Vec3& getRecentPreviousXYZ() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time at which the recent previous position occured */
|
||||
virtual const float getRecentPreviousXYZTime() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the height of the terrain. we're currently above */
|
||||
virtual float getHoT() const = 0;
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -152,6 +152,7 @@ Kart::Kart (const std::string& ident, unsigned int world_kart_id,
|
||||
for (int i=0;i<m_xyz_history_size;i++)
|
||||
{
|
||||
m_previous_xyz.push_back(initial_position);
|
||||
m_previous_xyz_times.push_back(0.0f);
|
||||
}
|
||||
m_time_previous_counter = 0.0f;
|
||||
|
||||
@ -381,6 +382,7 @@ void Kart::reset()
|
||||
for (int i=0;i<m_xyz_history_size;i++)
|
||||
{
|
||||
m_previous_xyz[i] = getXYZ();
|
||||
m_previous_xyz_times[i] = 0.0f;
|
||||
}
|
||||
m_time_previous_counter = 0.0f;
|
||||
|
||||
@ -927,7 +929,9 @@ void Kart::finishedRace(float time, bool from_server)
|
||||
} // !from_server
|
||||
|
||||
m_finished_race = true;
|
||||
|
||||
m_finish_time = time;
|
||||
|
||||
m_controller->finishedRace(time);
|
||||
m_kart_model->finishedRace();
|
||||
race_manager->kartFinishedRace(this, time);
|
||||
@ -1317,9 +1321,11 @@ void Kart::update(int ticks)
|
||||
while (m_time_previous_counter > stk_config->ticks2Time(1))
|
||||
{
|
||||
m_previous_xyz[0] = getXYZ();
|
||||
m_previous_xyz_times[0] = World::getWorld()->getTime();
|
||||
for (int i=m_xyz_history_size-1;i>0;i--)
|
||||
{
|
||||
m_previous_xyz[i] = m_previous_xyz[i-1];
|
||||
m_previous_xyz_times[i] = m_previous_xyz_times[i-1];
|
||||
}
|
||||
m_time_previous_counter -= stk_config->ticks2Time(1);
|
||||
}
|
||||
@ -3132,6 +3138,13 @@ const Vec3& Kart::getRecentPreviousXYZ() const
|
||||
return m_previous_xyz[m_xyz_history_size/5];
|
||||
} // getRecentPreviousXYZ
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time at which the recent previoux position occured */
|
||||
const float Kart::getRecentPreviousXYZTime() const
|
||||
{
|
||||
return m_previous_xyz_times[m_xyz_history_size/5];
|
||||
} // getRecentPreviousXYZTime
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void Kart::playSound(SFXBuffer* buffer)
|
||||
{
|
||||
|
@ -84,6 +84,10 @@ protected:
|
||||
/** The coordinates of the XYZ_HISTORY_SIZE previous positions */
|
||||
std::vector<Vec3> m_previous_xyz;
|
||||
|
||||
/** The times at which the previous positions occured.
|
||||
Currently used for finish time computation */
|
||||
std::vector<float> m_previous_xyz_times;
|
||||
|
||||
float m_time_previous_counter;
|
||||
|
||||
/** Is time flying activated */
|
||||
@ -519,6 +523,9 @@ public:
|
||||
/** Returns a more recent different previous position */
|
||||
virtual const Vec3& getRecentPreviousXYZ() const OVERRIDE;
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the time at which the recent previous position occured */
|
||||
virtual const float getRecentPreviousXYZTime() const;
|
||||
// ------------------------------------------------------------------------
|
||||
/** For debugging only: check if a kart is flying. */
|
||||
bool isFlying() const { return m_flying; }
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -157,10 +157,6 @@ void LinearWorld::reset()
|
||||
*/
|
||||
void LinearWorld::update(int ticks)
|
||||
{
|
||||
// run generic parent stuff that applies to all modes. It
|
||||
// especially updates the kart positions.
|
||||
WorldWithRank::update(ticks);
|
||||
|
||||
const unsigned int kart_amount = getNumKarts();
|
||||
|
||||
// Do stuff specific to this subtype of race.
|
||||
@ -189,6 +185,11 @@ void LinearWorld::update(int ticks)
|
||||
+ getDistanceDownTrackForKart(kart->getWorldKartId(), true);
|
||||
} // for n
|
||||
|
||||
// Run generic parent stuff that applies to all modes.
|
||||
// It especially updates the kart positions.
|
||||
// It MUST be done after the update of the distances
|
||||
WorldWithRank::update(ticks);
|
||||
|
||||
// Update all positions. This must be done after _all_ karts have
|
||||
// updated their position and laps etc, otherwise inconsistencies
|
||||
// (like two karts at same position) can occur.
|
||||
@ -409,9 +410,37 @@ void LinearWorld::newLap(unsigned int kart_index)
|
||||
updateRacePosition();
|
||||
|
||||
// Race finished
|
||||
// We compute the exact moment the kart crossed the line
|
||||
// This way, even with poor framerate, we get a time significant to the ms
|
||||
if(kart_info.m_finished_laps >= race_manager->getNumLaps() && raceHasLaps())
|
||||
{
|
||||
kart->finishedRace(getTime());
|
||||
if (kart->isGhostKart())
|
||||
{
|
||||
GhostKart* gk = dynamic_cast<GhostKart*>(kart);
|
||||
// Old replays don't store distance, so don't use the ghost method
|
||||
// Ghosts also don't store the previous positions, so the method
|
||||
// for normal karts can't be used.
|
||||
if (gk->getGhostFinishTime() > 0.0f)
|
||||
kart->finishedRace(gk->getGhostFinishTime());
|
||||
else
|
||||
kart->finishedRace(getTime());
|
||||
}
|
||||
else
|
||||
{
|
||||
float curr_distance_after_line = getDistanceDownTrackForKart(kart->getWorldKartId(),false);
|
||||
|
||||
TrackSector prev_sector;
|
||||
prev_sector.update(kart->getRecentPreviousXYZ());
|
||||
float prev_distance_before_line = Track::getCurrentTrack()->getTrackLength()
|
||||
- prev_sector.getDistanceFromStart(false);
|
||||
|
||||
float finish_proportion = curr_distance_after_line
|
||||
/ (prev_distance_before_line + curr_distance_after_line);
|
||||
|
||||
float prev_time = kart->getRecentPreviousXYZTime();
|
||||
float finish_time = prev_time*finish_proportion + getTime()*(1.0f-finish_proportion);
|
||||
kart->finishedRace(finish_time);
|
||||
}
|
||||
}
|
||||
int ticks_per_lap;
|
||||
if (kart_info.m_finished_laps == 1) // just completed first lap
|
||||
@ -626,7 +655,10 @@ float LinearWorld::estimateFinishTimeForKart(AbstractKart* kart)
|
||||
if (kart->isGhostKart())
|
||||
{
|
||||
GhostKart* gk = dynamic_cast<GhostKart*>(kart);
|
||||
return gk->getGhostFinishTime();
|
||||
// Old replays don't store distance, so don't use the ghost method
|
||||
// They'll return a negative time here
|
||||
if (gk->getGhostFinishTime() > 0.0f)
|
||||
return gk->getGhostFinishTime();
|
||||
}
|
||||
|
||||
if(full_distance == 0)
|
||||
@ -660,22 +692,22 @@ float LinearWorld::estimateFinishTimeForKart(AbstractKart* kart)
|
||||
// Avoid NAN or invalid results when average_speed is very low
|
||||
// or negative (which can happen if a kart drives backwards and
|
||||
// m_overall distance becomes smaller than -m_distance_increase).
|
||||
// In this case set the time to 99 minutes, offset by kart
|
||||
// In this case set the time to 59 minutes, offset by kart
|
||||
// position (to spread arrival times for all karts that arrive
|
||||
// even later). This works for up to 60 karts (otherwise the
|
||||
// time displayed would become too long: 100:xx:yy).
|
||||
// time displayed would overflow to 00:yy).
|
||||
if(average_speed<0.01f)
|
||||
return 99*60.0f + kart->getPosition();
|
||||
return 59*60.0f + kart->getPosition();
|
||||
|
||||
float est_time = getTime() + (full_distance - kart_info.m_overall_distance)
|
||||
/ average_speed;
|
||||
|
||||
// Avoid times > 99:00 - in this case use kart position to spread
|
||||
// Avoid times > 59:00 - in this case use kart position to spread
|
||||
// arrival time so that each kart has a unique value. The pre-condition
|
||||
// guarantees that this works correctly (higher position -> less distance
|
||||
// covered -> later arrival time).
|
||||
if(est_time>99*60.0f)
|
||||
return 99*60.0f + kart->getPosition();
|
||||
if(est_time>59*60.0f)
|
||||
return 59*60.0f + kart->getPosition();
|
||||
|
||||
return est_time;
|
||||
} // estimateFinishTimeForKart
|
||||
|
Loading…
Reference in New Issue
Block a user