Added support for storing a predecessor for each node in the

quad graph (needed for rescueing). 


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@9165 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2011-07-05 01:35:45 +00:00
parent ce827038de
commit b24f53a3eb
4 changed files with 53 additions and 23 deletions

View File

@@ -39,12 +39,14 @@ QuadGraph *GraphNode::m_all_nodes=NULL;
/** Constructor. Saves the quad index which belongs to this graph node.
* \param index Index of the quad to use for this node (in m_all_quads).
*/
GraphNode::GraphNode(unsigned int index)
GraphNode::GraphNode(unsigned int quad_index, unsigned int node_index)
{
assert(index<m_all_quads->getNumberOfQuads());
m_index = index;
assert(quad_index<m_all_quads->getNumberOfQuads());
m_quad_index = quad_index;
m_node_index = node_index;
m_predecessor = -1;
m_distance_from_start = 0;
const Quad &quad = m_all_quads->getQuad(m_index);
const Quad &quad = m_all_quads->getQuad(m_quad_index);
// FIXME: the following values should depend on the actual orientation
// of the quad. ATM we always assume that indices 0,1 are the lower end,
// and 2,3 are the upper end.
@@ -64,15 +66,20 @@ GraphNode::GraphNode(unsigned int index)
/** Adds a successor to a node. This function will also pre-compute certain
* values (like distance from this node to the successor, angle (in world)
* between this node and the successor.
* \param to The index of the successor.
* \param to The index of the graph node of the successor.
*/
void GraphNode::addSuccessor(unsigned int to)
{
m_vertices.push_back(to);
// m_index is the quad index, so we use m_all_quads
const Quad &this_quad = m_all_quads->getQuad(m_index);
m_successor_node.push_back(to);
// m_quad_index is the quad index, so we use m_all_quads
const Quad &this_quad = m_all_quads->getQuad(m_quad_index);
// to is the graph node, so we have to use m_all_nodes to get the right quad
GraphNode &gn = m_all_nodes->getNode(to);
const Quad &next_quad = m_all_nodes->getQuad(to);
// Keep the first predecessor, which is usually the most 'natural' one.
if(gn.m_predecessor==-1)
gn.m_predecessor = m_node_index;
core::vector2df d2 = m_lower_center_2d
- m_all_nodes->getNode(to).m_lower_center_2d;

View File

@@ -41,11 +41,22 @@ class GraphNode
/** Index of this node in the set of quads. Several graph nodes can use
* the same quad, meaning it is possible to use a quad more than once,
* e.g. a figure 8 like track. */
unsigned int m_index;
/** The list of successors. */
std::vector<int> m_vertices;
unsigned int m_quad_index;
/** Index of this graph node. */
unsigned int m_node_index;
/** The list of successor graph nodes. */
std::vector<int> m_successor_node;
/** The first predecessor. This is used in moving karts after a rescue.
* For this a node on the main driveline will be used (i.e. the first
* reported node which has this node as a successor). */
int m_predecessor;
/** The distance to each of the successors. */
std::vector<float> m_distance_to_next;
/** The angle of the line from this node to each neighbour. */
std::vector<float> m_angle_to_next;
@@ -76,6 +87,7 @@ class GraphNode
* saves computation, and it is only needed to determine the distance
* from the center of the drivelines anyway. */
core::line2df m_line;
public:
/** Keep a shared pointer so that some asserts and tests can be
* done without adding additional parameters. */
@@ -84,32 +96,32 @@ public:
* has access to the actual quad to which a node points. */
static QuadGraph *m_all_nodes;
GraphNode(unsigned int index);
GraphNode(unsigned int quad_index, unsigned int node_index);
void addSuccessor (unsigned int to);
void getDistances(const Vec3 &xyz, Vec3 *result);
float getDistance2FromPoint(const Vec3 &xyz);
/** Returns the i-th successor. */
/** Returns the i-th successor node. */
unsigned int getSuccessor(unsigned int i) const
{ return m_vertices[i]; }
{ return m_successor_node[i]; }
// ------------------------------------------------------------------------
/** Returns the number of successors. */
unsigned int getNumberOfSuccessors() const
{ return (unsigned int)m_vertices.size(); }
{ return (unsigned int)m_successor_node.size(); }
// ------------------------------------------------------------------------
/** Returns the index in the quad_set of this node. */
int getIndex() const { return m_index; }
/** Returns the quad_index in the quad_set of this node. */
int getIndex() const { return m_quad_index; }
// ------------------------------------------------------------------------
/** Returns the quad of this graph node. */
const Quad& getQuad() const {return m_all_quads->getQuad(m_index);}
const Quad& getQuad() const {return m_all_quads->getQuad(m_quad_index);}
// ------------------------------------------------------------------------
/** Returns the i-th. point of a quad. ATM this just returns the vertices
* from the quads, but if necessary this method will also consider
* rotated quads. So index 0 will always be lower left point, then
* counterclockwise. */
const Vec3& operator[](int i) const
{return m_all_quads->getQuad(m_index)[i];}
{return m_all_quads->getQuad(m_quad_index)[i];}
// ------------------------------------------------------------------------
/** Returns the distance to the j-th. successor. */
float getDistanceToSuccessor(unsigned int j) const
@@ -142,8 +154,12 @@ public:
* \param index Index of the successor. */
bool ignoreSuccessorForAI(unsigned int i) const
{
return m_all_quads->getQuad(m_vertices[i]).letAIIgnore();
return m_all_quads->getQuad(m_successor_node[i]).letAIIgnore();
};
// ------------------------------------------------------------------------
/** Returns a predecessor for this node. */
unsigned int getPredecessor() const {return m_predecessor; }
// ------------------------------------------------------------------------
}; // GraphNode
#endif

View File

@@ -78,7 +78,7 @@ void QuadGraph::load(const std::string &filename)
// i.e. each quad is part of the graph exactly once.
// First create an empty graph node for each quad:
for(unsigned int i=0; i<m_all_quads->getNumberOfQuads(); i++)
m_all_nodes.push_back(new GraphNode(i));
m_all_nodes.push_back(new GraphNode(i, m_all_nodes.size()));
// Then set the default loop:
setDefaultSuccessors();
@@ -111,7 +111,7 @@ void QuadGraph::load(const std::string &filename)
xml_node->get("to-quad", &to);
for(unsigned int i=from; i<=to; i++)
{
m_all_nodes.push_back(new GraphNode(i));
m_all_nodes.push_back(new GraphNode(i, m_all_nodes.size()));
}
}
else if(xml_node->getName()=="node")
@@ -119,7 +119,7 @@ void QuadGraph::load(const std::string &filename)
// A single quad is connected to a single graph node.
unsigned int id;
xml_node->get("quad", &id);
m_all_nodes.push_back(new GraphNode(id));
m_all_nodes.push_back(new GraphNode(id, m_all_nodes.size()));
}
// Then the definition of edges between the graph nodes:

View File

@@ -403,6 +403,13 @@ void Track::loadQuadGraph(unsigned int mode_id)
{
m_quad_graph = new QuadGraph(m_root+"/"+m_all_modes[mode_id].m_quad_name,
m_root+"/"+m_all_modes[mode_id].m_graph_name);
#ifdef DEBUG
for(unsigned int i=0; i<m_quad_graph->getNumNodes(); i++)
{
assert(m_quad_graph->getNode(i).getPredecessor()!=-1);
}
#endif
if(m_quad_graph->getNumNodes()==0)
{
fprintf(stderr, "[Track] WARNING: No graph nodes defined for track '%s'\n",