1) Fixed computing of checkling requirements to work properly with

reverse tracks. Simplified code by moving some functionality
   from QuadGraph to CheckManager.
2) Added comments, renamed some functions to better indicate
   what they are doing.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/reverse_mode@10843 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2012-02-14 20:51:29 +00:00
parent 8a0fe903a4
commit fcdf44c764
8 changed files with 96 additions and 72 deletions

View File

@ -137,7 +137,7 @@ public:
virtual bool haveBonusBoxes(){ return true; }
// ------------------------------------------------------------------------
/** Override settings from base class */
virtual bool computeChecklineRequirements() const { return true; }
virtual bool useChecklineRequirements() const { return true; }
// ------------------------------------------------------------------------
/** Returns true if the kart is on a valid driveline quad.
* \param kart_index Index of the kart. */

View File

@ -68,7 +68,7 @@ public:
virtual void onFirePressed(Controller* who);
// ------------------------------------------------------------------------
/** Override settings from base class */
virtual bool computeChecklineRequirements() const { return false; }
virtual bool useChecklineRequirements() const { return false; }
};
#endif

View File

@ -279,7 +279,7 @@ public:
/** Whether to compute checkline requirements for each world on the
* quadgraph. Override to change value. */
virtual bool computeChecklineRequirements() const { return false; }
virtual bool useChecklineRequirements() const { return false; }
}; // World

View File

@ -118,3 +118,41 @@ void CheckManager::update(float dt)
(*i)->update(dt);
} // update
// ----------------------------------------------------------------------------
/** Returns the index of the first check structures that triggers a new
* lap to be counted. It aborts if no lap structure is defined.
*/
unsigned int CheckManager::getLapLineIndex() const
{
for (unsigned int i=0; i<getCheckStructureCount(); i++)
{
CheckStructure* c = getCheckStructure(i);
if (dynamic_cast<CheckLap*>(c) != NULL) return i;
}
fprintf(stderr, "Error, no lap line for track found, aborting.\n");
exit(-1);
} // getLapLineIndex
// ----------------------------------------------------------------------------
/** Returns the check line index that is triggered when going from 'from'
* to 'to'. If no check line is triggered, -1 will be returned.
* \param from Coordinates to start from.
* \param to Coordinates to go to.
*/
int CheckManager::getChecklineTriggering(const Vec3 &from,
const Vec3 &to) const
{
for (unsigned int i=0; i<getCheckStructureCount(); i++)
{
CheckStructure* c = getCheckStructure(i);
// FIXME: why is the lapline skipped?
if (dynamic_cast<CheckLap*>(c) != NULL) continue;
if (c->isTriggered(from, to, 0 /* kart id */))
return i;
}
return -1;
} // getChecklineTriggering

View File

@ -25,9 +25,10 @@
#include <string>
#include <vector>
class XMLNode;
class CheckStructure;
class Track;
class XMLNode;
class Vec3;
/**
* \brief Controls all checks structures of a track.
@ -46,6 +47,8 @@ public:
void load(const XMLNode &node);
void update(float dt);
void reset(const Track &track);
unsigned int getLapLineIndex() const;
int getChecklineTriggering(const Vec3 &from, const Vec3 &to) const;
// ------------------------------------------------------------------------
/** Creates an instance of the check manager. */
static void create()
@ -61,10 +64,10 @@ public:
static void destroy() { delete m_check_manager; m_check_manager = NULL; }
// ------------------------------------------------------------------------
/** Returns the number of check structures defined. */
int getCheckStructureCount() const { return m_all_checks.size(); }
unsigned int getCheckStructureCount() const { return m_all_checks.size(); }
// ------------------------------------------------------------------------
/** Returns the nth. check structure. */
CheckStructure *getCheckStructure(unsigned int n)
CheckStructure *getCheckStructure(unsigned int n) const
{
assert(n < m_all_checks.size());
return m_all_checks[n];

View File

@ -183,13 +183,7 @@ void QuadGraph::load(const std::string &filename)
delete xml;
setDefaultSuccessors();
// The track exporter always exports quad 0 as first quad after (or at)
// the start line (start line is lower side of quad 0). In reverse mode
// the start quad is the predecessor of node 0.
unsigned int start_node = m_reverse ? m_all_nodes[0]->getSuccessor(0)
: 0;
computeDistanceFromStart(start_node, 0.0f);
computeDistanceFromStart(getStartNode(), 0.0f);
// Define the track length as the maximum at the end of a quad
// (i.e. distance_from_start + length till successor 0).
@ -204,55 +198,46 @@ void QuadGraph::load(const std::string &filename)
} // load
// ----------------------------------------------------------------------------
/**
* Finds which checklines must be visited before driving on this quad
* (useful for rescue)
*/
void QuadGraph::setChecklineRequirements(GraphNode* node, int latest_checkline)
/** Returns the index of the first graph node (i.e. the graph node which
* will trigger a new lap when a kart first enters it). This is always
* 0 for normal direction (this is guaranteed by the track exporter),
* but in reverse mode (where node 0 is actually the end of the track)
* this is 0's successor.
*/
unsigned int QuadGraph::getStartNode() const
{
Track* t = World::getWorld()->getTrack();
CheckManager* cm = CheckManager::get();
assert(cm != NULL);
// Find lapline
if (latest_checkline == -1)
{
for (int i=0; i<cm->getCheckStructureCount(); i++)
{
CheckStructure* c = cm->getCheckStructure(i);
if (dynamic_cast<CheckLap*>(c) != NULL)
{
latest_checkline = i;
break;
}
}
}
return m_reverse ? m_all_nodes[0]->getSuccessor(0)
: 0;
} // getStartNode
// ----------------------------------------------------------------------------
void QuadGraph::computeChecklineRequirements()
{
computeChecklineRequirements(m_all_nodes[0],
CheckManager::get()->getLapLineIndex());
} // computeChecklineRequirements
// ----------------------------------------------------------------------------
/** Finds which checklines must be visited before driving on this quad
* (useful for rescue)
*/
void QuadGraph::computeChecklineRequirements(GraphNode* node,
int latest_checkline)
{
for (unsigned int n=0; n<node->getNumberOfSuccessors(); n++)
{
const int succ_id = node->getSuccessor(n);
// warp-around
if (succ_id == 0) break;
int new_latest_checkline = latest_checkline;
GraphNode* succ = m_all_nodes[succ_id];
for (int i=0; i<cm->getCheckStructureCount(); i++)
{
CheckStructure* c = cm->getCheckStructure(i);
// skip lapline
if (dynamic_cast<CheckLap*>(c) != NULL) continue;
if (c->isTriggered(node->getCenter(), succ->getCenter(), 0 /* kart id */))
{
new_latest_checkline = i;
break;
}
}
GraphNode* succ = m_all_nodes[succ_id];
int new_latest_checkline =
CheckManager::get()->getChecklineTriggering(node->getCenter(),
succ->getCenter() );
if(new_latest_checkline==-1)
new_latest_checkline = latest_checkline;
/*
printf("Quad %i : checkline %i\n", succ_id, new_latest_checkline);
@ -266,9 +251,9 @@ void QuadGraph::setChecklineRequirements(GraphNode* node, int latest_checkline)
if (new_latest_checkline != -1)
succ->setChecklineRequirements(new_latest_checkline);
setChecklineRequirements(succ, new_latest_checkline);
computeChecklineRequirements(succ, new_latest_checkline);
}
}
} // computeChecklineRequirements
// ----------------------------------------------------------------------------
/** This function defines the "path-to-nodes" for each graph node that has
@ -334,13 +319,9 @@ void QuadGraph::setDefaultStartPositions(AlignedArray<btTransform>
float sidewards_distance,
float upwards_distance) const
{
// In non-reverse mode: node 0 is the node on which the start line is.
// So get its predecessor (which is therefore just
// before the start line) to find the first quad
// to place karts on.
// In reverse mode, karts can start to placed on quad 0.
int current_node = m_reverse ? getNode(0).getIndex()
: getNode(0).getPredecessor();
// We start just before the start node (which will trigger lap
// counting when reached).
int current_node = m_all_nodes[getStartNode()]->getPredecessor();
float distance_from_start = 0.1f+forwards_distance;
@ -585,6 +566,11 @@ void QuadGraph::getSuccessors(int node_number,
} // getSuccessors
// ----------------------------------------------------------------------------
/** Recursively determines the distance the beginning (lower end) of the quads
* have from the start of the track.
* \param node The node index for which to set the distance from start.
* \param new_distance The new distance for the specified graph node.
*/
void QuadGraph::computeDistanceFromStart(unsigned int node, float new_distance)
{
GraphNode *gn = m_all_nodes[node];

View File

@ -79,7 +79,7 @@ private:
bool m_reverse;
void setDefaultSuccessors();
void setChecklineRequirements(GraphNode* node, int latest_checkline);
void computeChecklineRequirements(GraphNode* node, int latest_checkline);
void addSuccessor(unsigned int from, unsigned int to);
void load (const std::string &filename);
@ -87,6 +87,7 @@ private:
void createMesh(bool show_invisible=true,
const video::SColor *track_color=NULL,
const video::SColor *lap_color=NULL);
unsigned int getStartNode() const;
QuadGraph (const std::string &quad_file_name,
const std::string graph_file_name,
const bool reverse);
@ -120,7 +121,8 @@ public:
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *out) const;
void updateDistancesForAllSuccessors(unsigned int indx, float delta);
void setupPaths();
// ----------------------------------------------------------------------
void computeChecklineRequirements();
// ----------------------------------------------------------------------
/** Returns the one instance of this object. It is possible that there
* is no instance created (e.g. in battle mode, since it doesn't have
* a quad graph), so we don't assert that an instance exist, and we
@ -182,11 +184,6 @@ public:
// ----------------------------------------------------------------------
/** Returns true if the graph is to be reversed. */
bool isReverse() const {return m_reverse; }
// ----------------------------------------------------------------------
void setChecklineRequirements()
{
setChecklineRequirements(m_all_nodes[0], -1);
}
}; // QuadGraph

View File

@ -1557,9 +1557,9 @@ void Track::loadTrackModel(World* parent, bool reverse_track,
irr_driver->getSceneManager()->getMeshCache()->getMeshCount(),
irr_driver->getVideoDriver()->getTextureCount());
if (World::getWorld()->computeChecklineRequirements())
if (World::getWorld()->useChecklineRequirements())
{
QuadGraph::get()->setChecklineRequirements();
QuadGraph::get()->computeChecklineRequirements();
}
} // loadTrackModel