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:
parent
8a0fe903a4
commit
fcdf44c764
@ -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. */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
@ -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];
|
||||
|
@ -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];
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user