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 */
|
/** Returns the most recent different previous position */
|
||||||
virtual const Vec3& getRecentPreviousXYZ() const = 0;
|
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 */
|
/** Returns the height of the terrain. we're currently above */
|
||||||
virtual float getHoT() const = 0;
|
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++)
|
for (int i=0;i<m_xyz_history_size;i++)
|
||||||
{
|
{
|
||||||
m_previous_xyz.push_back(initial_position);
|
m_previous_xyz.push_back(initial_position);
|
||||||
|
m_previous_xyz_times.push_back(0.0f);
|
||||||
}
|
}
|
||||||
m_time_previous_counter = 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++)
|
for (int i=0;i<m_xyz_history_size;i++)
|
||||||
{
|
{
|
||||||
m_previous_xyz[i] = getXYZ();
|
m_previous_xyz[i] = getXYZ();
|
||||||
|
m_previous_xyz_times[i] = 0.0f;
|
||||||
}
|
}
|
||||||
m_time_previous_counter = 0.0f;
|
m_time_previous_counter = 0.0f;
|
||||||
|
|
||||||
@ -927,7 +929,9 @@ void Kart::finishedRace(float time, bool from_server)
|
|||||||
} // !from_server
|
} // !from_server
|
||||||
|
|
||||||
m_finished_race = true;
|
m_finished_race = true;
|
||||||
|
|
||||||
m_finish_time = time;
|
m_finish_time = time;
|
||||||
|
|
||||||
m_controller->finishedRace(time);
|
m_controller->finishedRace(time);
|
||||||
m_kart_model->finishedRace();
|
m_kart_model->finishedRace();
|
||||||
race_manager->kartFinishedRace(this, time);
|
race_manager->kartFinishedRace(this, time);
|
||||||
@ -1317,9 +1321,11 @@ void Kart::update(int ticks)
|
|||||||
while (m_time_previous_counter > stk_config->ticks2Time(1))
|
while (m_time_previous_counter > stk_config->ticks2Time(1))
|
||||||
{
|
{
|
||||||
m_previous_xyz[0] = getXYZ();
|
m_previous_xyz[0] = getXYZ();
|
||||||
|
m_previous_xyz_times[0] = World::getWorld()->getTime();
|
||||||
for (int i=m_xyz_history_size-1;i>0;i--)
|
for (int i=m_xyz_history_size-1;i>0;i--)
|
||||||
{
|
{
|
||||||
m_previous_xyz[i] = m_previous_xyz[i-1];
|
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);
|
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];
|
return m_previous_xyz[m_xyz_history_size/5];
|
||||||
} // getRecentPreviousXYZ
|
} // 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)
|
void Kart::playSound(SFXBuffer* buffer)
|
||||||
{
|
{
|
||||||
|
@ -84,6 +84,10 @@ protected:
|
|||||||
/** The coordinates of the XYZ_HISTORY_SIZE previous positions */
|
/** The coordinates of the XYZ_HISTORY_SIZE previous positions */
|
||||||
std::vector<Vec3> m_previous_xyz;
|
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;
|
float m_time_previous_counter;
|
||||||
|
|
||||||
/** Is time flying activated */
|
/** Is time flying activated */
|
||||||
@ -519,6 +523,9 @@ public:
|
|||||||
/** Returns a more recent different previous position */
|
/** Returns a more recent different previous position */
|
||||||
virtual const Vec3& getRecentPreviousXYZ() const OVERRIDE;
|
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. */
|
/** For debugging only: check if a kart is flying. */
|
||||||
bool isFlying() const { return m_flying; }
|
bool isFlying() const { return m_flying; }
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -157,10 +157,6 @@ void LinearWorld::reset()
|
|||||||
*/
|
*/
|
||||||
void LinearWorld::update(int ticks)
|
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();
|
const unsigned int kart_amount = getNumKarts();
|
||||||
|
|
||||||
// Do stuff specific to this subtype of race.
|
// Do stuff specific to this subtype of race.
|
||||||
@ -189,6 +185,11 @@ void LinearWorld::update(int ticks)
|
|||||||
+ getDistanceDownTrackForKart(kart->getWorldKartId(), true);
|
+ getDistanceDownTrackForKart(kart->getWorldKartId(), true);
|
||||||
} // for n
|
} // 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
|
// Update all positions. This must be done after _all_ karts have
|
||||||
// updated their position and laps etc, otherwise inconsistencies
|
// updated their position and laps etc, otherwise inconsistencies
|
||||||
// (like two karts at same position) can occur.
|
// (like two karts at same position) can occur.
|
||||||
@ -409,9 +410,37 @@ void LinearWorld::newLap(unsigned int kart_index)
|
|||||||
updateRacePosition();
|
updateRacePosition();
|
||||||
|
|
||||||
// Race finished
|
// 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())
|
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;
|
int ticks_per_lap;
|
||||||
if (kart_info.m_finished_laps == 1) // just completed first lap
|
if (kart_info.m_finished_laps == 1) // just completed first lap
|
||||||
@ -626,7 +655,10 @@ float LinearWorld::estimateFinishTimeForKart(AbstractKart* kart)
|
|||||||
if (kart->isGhostKart())
|
if (kart->isGhostKart())
|
||||||
{
|
{
|
||||||
GhostKart* gk = dynamic_cast<GhostKart*>(kart);
|
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)
|
if(full_distance == 0)
|
||||||
@ -660,22 +692,22 @@ float LinearWorld::estimateFinishTimeForKart(AbstractKart* kart)
|
|||||||
// Avoid NAN or invalid results when average_speed is very low
|
// Avoid NAN or invalid results when average_speed is very low
|
||||||
// or negative (which can happen if a kart drives backwards and
|
// or negative (which can happen if a kart drives backwards and
|
||||||
// m_overall distance becomes smaller than -m_distance_increase).
|
// 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
|
// position (to spread arrival times for all karts that arrive
|
||||||
// even later). This works for up to 60 karts (otherwise the
|
// 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)
|
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)
|
float est_time = getTime() + (full_distance - kart_info.m_overall_distance)
|
||||||
/ average_speed;
|
/ 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
|
// arrival time so that each kart has a unique value. The pre-condition
|
||||||
// guarantees that this works correctly (higher position -> less distance
|
// guarantees that this works correctly (higher position -> less distance
|
||||||
// covered -> later arrival time).
|
// covered -> later arrival time).
|
||||||
if(est_time>99*60.0f)
|
if(est_time>59*60.0f)
|
||||||
return 99*60.0f + kart->getPosition();
|
return 59*60.0f + kart->getPosition();
|
||||||
|
|
||||||
return est_time;
|
return est_time;
|
||||||
} // estimateFinishTimeForKart
|
} // estimateFinishTimeForKart
|
||||||
|
Loading…
Reference in New Issue
Block a user