Updated computation of 'distance from start' for the

quad graph: now the distance of the node is the maximum
of all paths leading to it, which should solve the 
problems with the cube (#354).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9416 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2011-08-03 06:21:26 +00:00
parent e105a33b66
commit 48cf9e0515
5 changed files with 60 additions and 5 deletions

View File

@ -544,6 +544,17 @@ float LinearWorld::estimateFinishTimeForKart(Kart* kart)
// Finish time is the time needed for the whole race with
// the average speed computed above.
#ifdef DEBUG
if(full_distance < distance_covered)
{
printf("WARNING: full distance < distance covered for kart '%s':\n",
kart->getIdent().c_str());
printf("%f < %f\n", full_distance, distance_covered);
}
#endif
if(full_distance < distance_covered)
return getTime() + kart->getInitialPosition();
return getTime() + (full_distance - distance_covered) / average_speed;
} // estimateFinishTimeForKart

View File

@ -95,13 +95,24 @@ void GraphNode::addSuccessor(unsigned int to)
// The distance from start for the successor node
if(to!=0)
{
// Do not change an existing, already set distance on another
// node (since this would mean that we then have to change all
// other nodes following that node, too).
float distance_for_next = m_distance_from_start+distance_to_next;
// If the successor node does not have a distance from start defined,
// update its distance. Otherwise if the node already has a distance,
// it is potentially necessary to update its distance from start:
// without this the length of the track (as taken by the distance
// from start of the last node) could be smaller than some of the
// paths. This can result in incorrect results for the arrival time
// estimation of the AI karts. See trac #354 for details.
if(m_all_nodes->getNode(to).m_distance_from_start==0)
{
m_all_nodes->getNode(to).m_distance_from_start =
m_distance_from_start+distance_to_next;
m_all_nodes->getNode(to).m_distance_from_start = distance_for_next;
}
else if(m_all_nodes->getNode(to).m_distance_from_start
< distance_for_next)
{
float delta = distance_for_next
- m_all_nodes->getNode(to).getDistanceFromStart();
m_all_nodes->updateDistancesForAllSuccessors(to, delta);
}
}
} // addSuccessor

View File

@ -136,6 +136,9 @@ public:
float getDistanceFromStart() const
{ return m_distance_from_start; }
// ------------------------------------------------------------------------
/** Sets the distance from start for this node. */
void setDistanceFromStart(float d) {m_distance_from_start = d; }
// ------------------------------------------------------------------------
/** Returns the width of the part for this quad. */
float getPathWidth() const { return m_width; }
// ------------------------------------------------------------------------

View File

@ -463,6 +463,34 @@ void QuadGraph::getSuccessors(int node_number,
}
} // getSuccessors
// ----------------------------------------------------------------------------
/** Increases
*/
void QuadGraph::updateDistancesForAllSuccessors(unsigned int indx, float delta)
{
GraphNode &g=getNode(indx);
g.setDistanceFromStart(g.getDistanceFromStart()+delta);
for(unsigned int i=0; i<g.getNumberOfSuccessors(); i++)
{
GraphNode &g_next = getNode(g.getSuccessor(i));
// If we reach the beginning of the graph (usually node with index 0,
// but just in case also test for nodes with distance 0), all nodes
// are updated, so no need to recurse any further.
if(g_next.getIndex()==0 ||
g_next.getDistanceFromStart()==0)
continue;
// Only increase the distance from start of a successor node, if
// this successor has a distance from start that is smaller then
// the increased amount.
if(g.getDistanceFromStart()+g.getDistanceToSuccessor(i) >
g_next.getDistanceFromStart())
{
updateDistancesForAllSuccessors(g.getSuccessor(i), delta);
}
}
} // updateDistancesForAllSuccessors
//-----------------------------------------------------------------------------
/** This function takes absolute coordinates (coordinates in OpenGL
* space) and transforms them into coordinates based on the track. The y-axis

View File

@ -104,6 +104,8 @@ public:
const video::SColor &fill_color
=video::SColor(127, 255, 255, 255) );
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *out) const;
void updateDistancesForAllSuccessors(unsigned int indx, float delta);
/** Returns the number of nodes in the graph. */
unsigned int getNumNodes() const { return m_all_nodes.size(); }