Improved handling of using the same quad more than once
(note: since esp. findOutOfRoadSector is not yet converted to use the quad graph structure, bugs and crashes can occur in some circumstances). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3539 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
1f362f88b0
commit
b5d7d2b506
@ -70,6 +70,26 @@ DefaultRobot::DefaultRobot(const std::string& kart_name,
|
||||
m_successor_index.push_back(indx);
|
||||
m_next_quad_index.push_back(next[indx]);
|
||||
}
|
||||
const int look_ahead=10;
|
||||
// Now compute for each node in the graph the list of the next 'look_ahead'
|
||||
// graph nodes. This is the list of node that is tested in checkCrashes.
|
||||
// If the look_ahead is too big, the AI can skip loops (see
|
||||
// QuadGraph::findRoadSector for details), if it's too short the AI won't
|
||||
// find too good a driveline. Note that in general this list should
|
||||
// be computed recursively, but since the AI for now is using only
|
||||
// (randomly picked) path this is fine
|
||||
m_all_look_aheads.reserve(m_quad_graph->getNumNodes());
|
||||
for(unsigned int i=0; i<m_quad_graph->getNumNodes(); i++)
|
||||
{
|
||||
std::vector<int> l;
|
||||
int current = i;
|
||||
for(unsigned int j=0; j<look_ahead; j++)
|
||||
{
|
||||
l.push_back(m_next_quad_index[current]);
|
||||
current = m_next_quad_index[current];
|
||||
} // for j<look_ahead
|
||||
m_all_look_aheads.push_back(l);
|
||||
}
|
||||
|
||||
m_world = dynamic_cast<LinearWorld*>(RaceManager::getWorld());
|
||||
assert(m_world != NULL);
|
||||
@ -133,6 +153,8 @@ void DefaultRobot::update(float dt)
|
||||
m_controls.m_look_back = false;
|
||||
m_controls.m_nitro = false;
|
||||
m_track_sector = m_world->m_kart_info[ getWorldKartId() ].m_track_sector;
|
||||
if(m_successor_index[m_track_sector]!=0)
|
||||
printf("XX");
|
||||
// The client does not do any AI computations.
|
||||
if(network_manager->getMode()==NetworkManager::NW_CLIENT)
|
||||
{
|
||||
@ -844,8 +866,12 @@ void DefaultRobot::checkCrashes( const int STEPS, const Vec3& pos )
|
||||
}
|
||||
|
||||
/*Find if we crash with the drivelines*/
|
||||
m_track->getQuadGraph().findRoadSector(step_coord, &m_sector,
|
||||
/* max look ahead */ 10);
|
||||
if(m_sector!=QuadGraph::UNKNOWN_SECTOR)
|
||||
m_track->getQuadGraph().findRoadSector(step_coord, &m_sector,
|
||||
/* sectors to test*/ &m_all_look_aheads[m_sector]);
|
||||
else
|
||||
m_track->getQuadGraph().findRoadSector(step_coord, &m_sector);
|
||||
|
||||
|
||||
#undef SHOW_FUTURE_PATH
|
||||
#ifdef SHOW_FUTURE_PATH
|
||||
|
@ -133,6 +133,9 @@ private:
|
||||
* m_next_quad_index[i] = (i+1) % size;
|
||||
* but if a branch is possible, the AI will select one option here. */
|
||||
std::vector<int> m_next_quad_index;
|
||||
/** For each graph node this list contains a list of the next X
|
||||
* graph nodes. */
|
||||
std::vector<std::vector<int> > m_all_look_aheads;
|
||||
float m_time_since_stuck;
|
||||
|
||||
int m_start_kart_crash_direction; //-1 = left, 1 = right, 0 = no crash.
|
||||
|
@ -66,6 +66,8 @@ GraphNode::GraphNode(unsigned int index)
|
||||
*/
|
||||
void GraphNode::addSuccessor(unsigned int to)
|
||||
{
|
||||
if(m_index==4 || m_index==5)
|
||||
printf("XX");
|
||||
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);
|
||||
|
@ -76,9 +76,9 @@ void QuadGraph::load(const std::string &filename)
|
||||
|
||||
// The graph file exist, so read it in. The graph file must first contain
|
||||
// the node definitions, before the edges can be set.
|
||||
for(unsigned int i=0; i<xml->getNumNodes(); i++)
|
||||
for(unsigned int node_index=0; node_index<xml->getNumNodes(); node_index++)
|
||||
{
|
||||
const XMLNode *xml_node = xml->getNode(i);
|
||||
const XMLNode *xml_node = xml->getNode(node_index);
|
||||
// First graph node definitions:
|
||||
// -----------------------------
|
||||
if(xml_node->getName()=="node-list")
|
||||
@ -247,38 +247,20 @@ void QuadGraph::spatialToTrack(Vec3 *dst, const Vec3& xyz,
|
||||
* \param XYZ Position for which the segment should be determined.
|
||||
* \param sector Contains the previous sector (as a shortcut, since usually
|
||||
* the sector is the same as the last one), and on return the result
|
||||
* \param max_lookahead Maximum number of graph nodes that are to be searched
|
||||
* from the current sector number. This is used by the AI to make sure
|
||||
* the AI does not skip any parts of the track (e.g. if the graph has
|
||||
* a loop, the AI code skip the whole loop otherwise and continue
|
||||
* on the normal path). Only used ith sector is not UNKNOWN_SECTOR.
|
||||
* Defaults to -1, which indicates to use all graph nodes. The actual
|
||||
* value might depend on the track, the size of the drivelines etc.
|
||||
* \param all_sectors If this is not NULL, it is a list of all sectors to
|
||||
* test. This is used by the AI to make sure that it ends up on the
|
||||
* selected way in case of a branch, and also to make sure that it
|
||||
* doesn't skip e.g. a loop (see explanation below for details).
|
||||
*/
|
||||
void QuadGraph::findRoadSector(const Vec3& xyz, int *sector,
|
||||
int max_lookahead) const
|
||||
std::vector<int> *all_sectors) const
|
||||
{
|
||||
if(*sector!=UNKNOWN_SECTOR)
|
||||
// Most likely the kart will still be on the sector it was before,
|
||||
// so this simple case is tested first.
|
||||
if(*sector!=UNKNOWN_SECTOR && getQuad(*sector).pointInQuad(xyz) )
|
||||
{
|
||||
// Most likely the kart will still be on the sector it was before,
|
||||
// so this simple case is tested first.
|
||||
if(getQuad(*sector).pointInQuad(xyz) )
|
||||
return;
|
||||
|
||||
// Then check all immediate neighbours. If it's any of them,
|
||||
// immediately return without any further tests.
|
||||
const GraphNode &node = *m_all_nodes[*sector];
|
||||
for(unsigned int i=0; i<node.getNumberOfSuccessors(); i++)
|
||||
{
|
||||
int succ = node.getSuccessor(i);
|
||||
if(getQuad(succ).pointInQuad(xyz))
|
||||
{
|
||||
*sector = succ;
|
||||
return;
|
||||
} // if pointInQuad
|
||||
} // for i<node.getNumberOfSuccessors()
|
||||
|
||||
} // if *sector!=UNKNOWN_SECTOR
|
||||
return;
|
||||
} // if still on same quad
|
||||
|
||||
// Now we search through all graph nodes, starting with
|
||||
// the current one
|
||||
@ -294,13 +276,16 @@ void QuadGraph::findRoadSector(const Vec3& xyz, int *sector,
|
||||
// and the track is supposed to be driven: ABCDEBF, the AI might find
|
||||
// the node on F, and then keep on going straight ahead instead of
|
||||
// using the loop at all.
|
||||
unsigned int max_count = (*sector!=UNKNOWN_SECTOR && max_lookahead>0)
|
||||
? max_lookahead
|
||||
unsigned int max_count = (*sector!=UNKNOWN_SECTOR && all_sectors!=NULL)
|
||||
? all_sectors->size()
|
||||
: m_all_nodes.size();
|
||||
*sector = UNKNOWN_SECTOR;
|
||||
for(unsigned int i=0; i<max_count; i++)
|
||||
{
|
||||
indx = indx<(int)m_all_nodes.size()-1 ? indx +1 : 0;
|
||||
if(all_sectors)
|
||||
indx = (*all_sectors)[i];
|
||||
else
|
||||
indx = indx<(int)m_all_nodes.size()-1 ? indx +1 : 0;
|
||||
const Quad &q = getQuad(indx);
|
||||
float dist = xyz.getZ() - q.getMinHeight();
|
||||
// While negative distances are unlikely, we allow some small netative
|
||||
|
@ -55,7 +55,7 @@ public:
|
||||
void spatialToTrack(Vec3 *dst, const Vec3& xyz,
|
||||
const int sector) const;
|
||||
void findRoadSector(const Vec3& XYZ, int *sector,
|
||||
int max_lookahead=-1) const;
|
||||
std::vector<int> *all_sectors=NULL) const;
|
||||
|
||||
/** Returns the number of nodes in the graph. */
|
||||
unsigned int getNumNodes() const { return m_all_nodes.size(); }
|
||||
|
Loading…
Reference in New Issue
Block a user