Add minimap for battle mode when it has a navigation mesh

TODO: update battle island arena to use only 4 vertices per poly
This commit is contained in:
Benau 2015-12-15 02:32:01 +08:00
parent e6068923b4
commit 12e4c76a6f
8 changed files with 383 additions and 109 deletions

View File

@ -832,7 +832,7 @@ void BattleAI::handleItems(const float dt)
void BattleAI::handleItemCollection(Vec3* aim_point, int* target_node)
{
float distance = 99999.9f;
const std::vector< std::pair<Item*, int> >& item_list =
const std::vector< std::pair<const Item*, int> >& item_list =
BattleGraph::get()->getItemList();
const unsigned int items_count = item_list.size();
unsigned int closest_item_num = 0;

View File

@ -342,8 +342,10 @@ void RaceGUI::drawGlobalTimer()
void RaceGUI::drawGlobalMiniMap()
{
World *world = World::getWorld();
// arenas currently don't have a map.
if(world->getTrack()->isArena() || world->getTrack()->isSoccer()) return;
// draw a map when arena has a navigation mesh.
if ((world->getTrack()->isArena() && !(world->getTrack()->hasNavMesh())) ||
world->getTrack()->isSoccer())
return;
const video::ITexture *old_rtt_mini_map = world->getTrack()->getOldRttMiniMap();
const FrameBuffer* new_rtt_mini_map = world->getTrack()->getNewRttMiniMap();

View File

@ -24,10 +24,13 @@
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/glwrap.hpp"
#include "graphics/shaders.hpp"
#include "graphics/rtts.hpp"
#include "items/item_manager.hpp"
#include "modes/world.hpp"
#include "tracks/navmesh.hpp"
#include "utils/log.hpp"
#include "utils/vec3.hpp"
const int BattleGraph::UNKNOWN_POLY = -1;
BattleGraph * BattleGraph::m_battle_graph = NULL;
@ -37,14 +40,30 @@ BattleGraph * BattleGraph::m_battle_graph = NULL;
* by the AI. */
BattleGraph::BattleGraph(const std::string &navmesh_file_name)
{
m_node = NULL;
m_mesh = NULL;
m_mesh_buffer = NULL;
m_new_rtt = NULL;
m_items_on_graph.clear();
NavMesh::create(navmesh_file_name);
m_navmesh_file = navmesh_file_name;
buildGraph(NavMesh::get());
computeFloydWarshall();
findItemsOnGraphNodes(ItemManager::get());
} // BattleGraph
// -----------------------------------------------------------------------------
/** Destructor, destroys NavMesh and the debug mesh if it exists */
BattleGraph::~BattleGraph(void)
{
NavMesh::destroy();
if(UserConfigParams::m_track_debug)
cleanupDebugMesh();
if (m_new_rtt != NULL)
delete m_new_rtt;
} // ~BattleGraph
// -----------------------------------------------------------------------------
/** Builds a graph from an existing NavMesh. The graph is stored as an adjacency
* matrix. */
@ -113,17 +132,7 @@ void BattleGraph::computeFloydWarshall()
} // computeFloydWarshall
// -----------------------------------------------------------------------------
/** Destructor, destroys NavMesh and the debug mesh if it exists */
BattleGraph::~BattleGraph(void)
{
NavMesh::destroy();
if(UserConfigParams::m_track_debug)
cleanupDebugMesh();
} // ~BattleGraph
// -----------------------------------------------------------------------------
/** Creates the actual mesh that is used by createDebugMesh() */
/** Creates the actual mesh that is used by createDebugMesh() or makeMiniMap() */
void BattleGraph::createMesh(bool enable_transparency,
const video::SColor *track_color)
{
@ -133,78 +142,56 @@ void BattleGraph::createMesh(bool enable_transparency,
m.Lighting = false;
if(enable_transparency)
m.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
m.setTexture(0, getUnicolorTexture(video::SColor(255, 255, 255, 255)));
m.setTexture(1, getUnicolorTexture(video::SColor(0, 0, 0, 0)));
m_mesh = irr_driver->createQuadMesh(&m);
m_mesh_buffer = m_mesh->getMeshBuffer(0);
assert(m_mesh_buffer->getVertexType()==video::EVT_STANDARD);
// Eps is used to raise the track debug quads a little bit higher than
// the ground, so that they are actually visible.
core::vector3df eps(0, 0.4f, 0);
video::SColor c = video::SColor(255, 255, 0, 0);
const unsigned int num_nodes = getNumNodes();
// Declare vector to hold new converted vertices, vertices are copied over
// for each polygon, although it results in redundant vertex copies in the
// final vector, this is the only way I know to make each poly have different color.
std::vector<video::S3DVertex> new_v;
// Four vertices for each of the n-1 remaining quads
video::S3DVertex *new_v = new video::S3DVertex[4*num_nodes];
// Each quad consists of 2 triangles with 3 elements, so
// we need 2*3 indices for each quad.
irr::u16 *ind = new irr::u16[6*num_nodes];
video::SColor c(255, 255, 0, 0);
// Declare vector to hold indices
std::vector<irr::u16> ind;
if(track_color)
c = *track_color;
// Now add all polygons
// Now add all quads
int i=0;
for(unsigned int count=0; count<getNumNodes(); count++)
for(unsigned int count=0; count<num_nodes; count++)
{
///compute colors
// There should not be a poly which isn't made of 4 vertices
if((NavMesh::get()->getNavPoly(count).getVerticesIndex()).size() !=4)
{
Log::warn("Battle Graph", "There is an invalid poly!");
continue;
}
// Swap the colours from red to blue and back
if(!track_color)
{
c.setAlpha(178);
//c.setRed ((i%2) ? 255 : 0);
//c.setBlue((i%3) ? 0 : 255);
c.setRed(7*i%256);
c.setBlue((2*i)%256);
c.setGreen((3*i)%256);
c.setRed ((i%2) ? 255 : 0);
c.setBlue((i%2) ? 0 : 255);
}
NavPoly poly = NavMesh::get()->getNavPoly(count);
//std::vector<int> vInd = poly.getVerticesIndex();
const std::vector<Vec3>& v = poly.getVertices();
// Number of triangles in the triangle fan
unsigned int numberOfTriangles = v.size() -2 ;
// Transfer the 4 points of the current quad to the list of vertices
NavMesh::get()->setVertices(count, new_v+4*i, c);
// Set up the indices for the triangles
// (note, afaik with opengl we could use quads directly, but the code
// would not be portable to directx anymore).
ind[6*i ] = 4*i+2; // First triangle: vertex 0, 1, 2
ind[6*i+1] = 4*i+1;
ind[6*i+2] = 4*i;
ind[6*i+3] = 4*i+3; // second triangle: vertex 0, 1, 3
ind[6*i+4] = 4*i+2;
ind[6*i+5] = 4*i;
i++;
} // for i=1; i<QuadSet::get()
for( unsigned int count = 1; count<=numberOfTriangles; count++)
{
video::S3DVertex v1,v2,v3;
v1.Pos=v[0].toIrrVector() + eps;
v2.Pos=v[count].toIrrVector() + eps;
v3.Pos=v[count+1].toIrrVector() + eps;
v1.Color = c;
v2.Color = c;
v3.Color = c;
core::triangle3df tri(v1.Pos, v2.Pos, v3.Pos);
core::vector3df normal = tri.getNormal();
normal.normalize();
v1.Normal = normal;
v2.Normal = normal;
v3.Normal = normal;
new_v.push_back(v1);
new_v.push_back(v2);
new_v.push_back(v3);
ind.push_back(i++);
ind.push_back(i++);
ind.push_back(i++);
}
}
m_mesh_buffer->append(new_v.data(), new_v.size(), ind.data(), ind.size());
m_mesh_buffer->append(new_v, num_nodes*4, ind, num_nodes*6);
// Instead of setting the bounding boxes, we could just disable culling,
// since the debug track should always be drawn.
@ -212,7 +199,157 @@ void BattleGraph::createMesh(bool enable_transparency,
m_mesh_buffer->recalculateBoundingBox();
m_mesh->setBoundingBox(m_mesh_buffer->getBoundingBox());
m_mesh_buffer->getMaterial().setTexture(0, irr_driver->getTexture("unlit.png"));
} // createMesh
// -----------------------------------------------------------------------------
/** Takes a snapshot of the navmesh so they can be used as minimap.
*/
void BattleGraph::makeMiniMap(const core::dimension2du &dimension,
const std::string &name,
const video::SColor &fill_color,
video::ITexture** oldRttMinimap,
FrameBuffer** newRttMinimap)
{
const video::SColor oldClearColor = World::getWorld()->getClearColor();
World::getWorld()->setClearbackBufferColor(video::SColor(0, 255, 255, 255));
World::getWorld()->forceFogDisabled(true);
*oldRttMinimap = NULL;
*newRttMinimap = NULL;
RTT* newRttProvider = NULL;
IrrDriver::RTTProvider* oldRttProvider = NULL;
if (CVS->isGLSL())
{
m_new_rtt = newRttProvider = new RTT(dimension.Width, dimension.Height);
}
else
{
oldRttProvider = new IrrDriver::RTTProvider(dimension, name, true);
}
irr_driver->getSceneManager()->setAmbientLight(video::SColor(255, 255, 255, 255));
createMesh(/*enable_transparency*/ false,
/*track_color*/ &fill_color);
m_node = irr_driver->addMesh(m_mesh, "mini_map");
#ifdef DEBUG
m_node->setName("minimap-mesh");
#endif
m_node->setAutomaticCulling(0);
m_node->setMaterialFlag(video::EMF_LIGHTING, false);
// Add the camera:
// ---------------
scene::ICameraSceneNode *camera = irr_driver->addCameraSceneNode();
Vec3 bb_min, bb_max;
NavMesh::get()->getBoundingBox(&bb_min, &bb_max);
Vec3 center = (bb_max+bb_min)*0.5f;
float dx = bb_max.getX()-bb_min.getX();
float dz = bb_max.getZ()-bb_min.getZ();
// Set the scaling correctly. Also the center point (which is used
// as the camera position) needs to be adjusted: the track must
// be aligned to the left/top of the texture which is used (otherwise
// mapPoint2MiniMap doesn't work), so adjust the camera position
// that the track is properly aligned (view from the side):
// c camera
// / \ .
// / \ <--- camera angle
// / \ .
// { [-] } <--- track flat (viewed from the side)
// If [-] is the shorter side of the track, then the camera will
// actually render the area in { } - which is the length of the
// longer side of the track.
// To align the [-] side to the left, the camera must be moved
// the distance betwwen '{' and '[' to the right. This distance
// is exacly (longer_side - shorter_side) / 2.
// So, adjust the center point by this amount:
if(dz > dx)
{
center.setX(center.getX() + (dz-dx)*0.5f);
m_scaling = dimension.Width / dz;
}
else
{
center.setZ(center.getZ() + (dx-dz)*0.5f);
m_scaling = dimension.Width / dx;
}
float range = (dx>dz) ? dx : dz;
core::matrix4 projection;
projection.buildProjectionMatrixOrthoLH(range /* width */,
range /* height */,
-1, bb_max.getY()-bb_min.getY()+1);
camera->setProjectionMatrix(projection, true);
irr_driver->suppressSkyBox();
irr_driver->clearLights();
// Adjust Y position by +1 for max, -1 for min - this helps in case that
// the maximum Y coordinate is negative (otherwise the minimap is mirrored)
// and avoids problems for tracks which have a flat (max Y = min Y) minimap.
camera->setPosition(core::vector3df(center.getX(), bb_min.getY() + 1.0f, center.getZ()));
//camera->setPosition(core::vector3df(center.getX() - 5.0f, bb_min.getY() - 1 - 5.0f, center.getZ() - 15.0f));
camera->setUpVector(core::vector3df(0, 0, 1));
camera->setTarget(core::vector3df(center.getX(),bb_min.getY()-1,center.getZ()));
//camera->setAspectRatio(1.0f);
camera->updateAbsolutePosition();
video::ITexture* texture = NULL;
FrameBuffer* frame_buffer = NULL;
if (CVS->isGLSL())
{
frame_buffer = newRttProvider->render(camera, GUIEngine::getLatestDt());
}
else
{
texture = oldRttProvider->renderToTexture();
delete oldRttProvider;
}
cleanupDebugMesh();
irr_driver->removeCameraSceneNode(camera);
m_min_coord = bb_min;
if (texture == NULL && frame_buffer == NULL)
{
Log::error("BattleGraph", "[makeMiniMap] WARNING: RTT does not appear to work,"
"mini-map will not be available.");
}
*oldRttMinimap = texture;
*newRttMinimap = frame_buffer;
World::getWorld()->setClearbackBufferColor(oldClearColor);
World::getWorld()->forceFogDisabled(false);
irr_driver->getSceneManager()->clear();
VAOManager::kill();
irr_driver->clearGlowingNodes();
irr_driver->clearLights();
irr_driver->clearForcedBloom();
irr_driver->clearBackgroundNodes();
} // makeMiniMap
// -----------------------------------------------------------------------------
/** Returns the 2d coordinates of a point when drawn on the mini map
* texture.
* \param xyz Coordinates of the point to map.
* \param draw_at The coordinates in pixel on the mini map of the point,
* only the first two coordinates will be used.
*/
void BattleGraph::mapPoint2MiniMap(const Vec3 &xyz,Vec3 *draw_at) const
{
draw_at->setX((xyz.getX()-m_min_coord.getX())*m_scaling);
draw_at->setY((xyz.getZ()-m_min_coord.getZ())*m_scaling);
} // mapPoint
// -----------------------------------------------------------------------------
/** Creates the debug mesh to display the quad graph on top of the track
@ -221,10 +358,21 @@ void BattleGraph::createDebugMesh()
{
if(getNumNodes()<=0) return; // no debug output if not graph
createMesh(/*enable_transparency*/false);
createMesh(/*enable_transparency*/true);
// Now colour the quads red/blue/red ...
video::SColor c( 128, 255, 0, 0);
video::S3DVertex *v = (video::S3DVertex*)m_mesh_buffer->getVertices();
for(unsigned int i=0; i<m_mesh_buffer->getVertexCount(); i++)
{
// Swap the colours from red to blue and back
c.setRed ((i%2) ? 255 : 0);
c.setBlue((i%2) ? 0 : 255);
v[i].Color = c;
}
m_node = irr_driver->addMesh(m_mesh, "track-debug-mesh");
#ifdef DEBUG
// m_node->setName("track-debug-mesh");
m_node->setName("track-debug-mesh");
#endif
} // createDebugMesh
@ -244,14 +392,15 @@ void BattleGraph::cleanupDebugMesh()
}
// -----------------------------------------------------------------------------
void BattleGraph::findItemsOnGraphNodes(ItemManager * item_manager)
/** Maps items on battle graph */
void BattleGraph::findItemsOnGraphNodes()
{
const ItemManager* item_manager = ItemManager::get();
unsigned int item_count = item_manager->getNumberOfItems();
for (unsigned int i = 0; i < item_count; ++i)
{
Item* item = item_manager->getItem(i);
const Item* item = item_manager->getItem(i);
Vec3 xyz = item->getXYZ();
int polygon = BattleGraph::UNKNOWN_POLY;

View File

@ -23,12 +23,9 @@
#include <string>
#include <set>
#include <dimension2d.h>
#include "tracks/navmesh.hpp"
class Navmesh;
class Item;
class ItemManager;
namespace irr
{
namespace scene { class ISceneNode; class IMesh; class IMeshBuffer; }
@ -36,6 +33,12 @@ namespace irr
}
using namespace irr;
class FrameBuffer;
class Item;
class ItemManager;
class Navmesh;
class RTT;
/**
* \ingroup tracks
*
@ -52,6 +55,8 @@ class BattleGraph
private:
static BattleGraph *m_battle_graph;
RTT* m_new_rtt;
/** The actual graph data structure, it is an adjacency matrix */
std::vector< std::vector< float > > m_distance_matrix;
/** The matrix that is used to store computed shortest paths */
@ -63,16 +68,21 @@ private:
/** For debug only: the actual mesh buffer storing the quads. */
scene::IMeshBuffer *m_mesh_buffer;
/** Stores the name of the file containing the NavMesh data */
std::string m_navmesh_file;
/** The minimum coordinates of the quad graph. */
Vec3 m_min_coord;
std::vector< std::pair<Item*, int> > m_items_on_graph;
/** Scaling for mini map. */
float m_scaling;
/** Stores the name of the file containing the NavMesh data */
std::string m_navmesh_file;
std::vector< std::pair<const Item*, int> > m_items_on_graph;
void buildGraph(NavMesh*);
void computeFloydWarshall();
void createMesh(bool enable_transparency=false,
const video::SColor *track_color=NULL);
void findItemsOnGraphNodes(ItemManager*);
BattleGraph(const std::string &navmesh_file_name);
~BattleGraph(void);
@ -105,7 +115,7 @@ public:
// ----------------------------------------------------------------------
/** Returns the number of nodes in the BattleGraph (equal to the number of
* polygons in the NavMesh */
unsigned int getNumNodes() const { return m_distance_matrix.size(); }
unsigned int getNumNodes() const { return m_distance_matrix.size(); }
// ----------------------------------------------------------------------
/** Returns the NavPoly corresponding to the i-th node of the BattleGraph */
@ -116,13 +126,20 @@ public:
/** Returns the next polygon on the shortest path from i to j.
* Note: m_parent_poly[j][i] contains the parent of i on path from j to i,
* which is the next node on the path from i to j (undirected graph) */
const int & getNextShortestPathPoly(int i, int j) const;
const int & getNextShortestPathPoly(int i, int j) const;
const std::vector< std::pair<Item*, int> >& getItemList()
const std::vector < std::pair<const Item*, int> >& getItemList()
{ return m_items_on_graph; }
void createDebugMesh();
void cleanupDebugMesh();
void createDebugMesh();
void cleanupDebugMesh();
void findItemsOnGraphNodes();
void makeMiniMap(const core::dimension2du &where,
const std::string &name,
const video::SColor &fill_color,
video::ITexture** oldRttMinimap,
FrameBuffer** newRttMinimap);
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *out) const;
}; //BattleGraph
#endif

View File

@ -37,6 +37,8 @@ NavMesh *NavMesh::m_nav_mesh = NULL;
NavMesh::NavMesh(const std::string &filename)
{
m_min = Vec3( 99999, 99999, 99999);
m_max = Vec3(-99999, -99999, -99999);
m_n_verts=0;
m_n_polys=0;
@ -68,6 +70,8 @@ NavMesh::NavMesh(const std::string &filename)
//Reading vertices
Vec3 p;
readVertex(xml_node_node, &p);
m_max.max(p);
m_min.min(p);
m_n_verts++;
m_verts.push_back(p);
}
@ -116,6 +120,44 @@ NavMesh::~NavMesh()
{
} // ~NavMesh
// ----------------------------------------------------------------------------
/** Sets the vertices in a irrlicht vertex array to the 4 points of this quad.
*/
void NavMesh::setVertices(int n, video::S3DVertex *v, const video::SColor &color) const
{
NavPoly poly = NavMesh::get()->getNavPoly(n);
const std::vector<Vec3>& p = poly.getVertices();
if (p.size() !=4) return;
// Eps is used to raise the track debug quads a little bit higher than
// the ground, so that they are actually visible.
core::vector3df eps(0, 0.1f, 0);
v[0].Pos = p[0].toIrrVector()+eps;
v[1].Pos = p[1].toIrrVector()+eps;
v[2].Pos = p[2].toIrrVector()+eps;
v[3].Pos = p[3].toIrrVector()+eps;
core::triangle3df tri(p[0].toIrrVector(), p[1].toIrrVector(),
p[2].toIrrVector());
core::vector3df normal = tri.getNormal();
normal.normalize();
v[0].Normal = normal;
v[1].Normal = normal;
v[2].Normal = normal;
core::triangle3df tri1(p[0].toIrrVector(), p[2].toIrrVector(),
p[3].toIrrVector());
core::vector3df normal1 = tri1.getNormal();
normal1.normalize();
v[3].Normal = normal1;
v[0].Color = color;
v[1].Color = color;
v[2].Color = color;
v[3].Color = color;
} // setVertices
// ----------------------------------------------------------------------------
/** Reads the vertex information from an XMLNode */

View File

@ -55,6 +55,10 @@ class NavMesh
private:
static NavMesh *m_nav_mesh;
/** The 2d bounding box, used for hashing. */
Vec3 m_min;
Vec3 m_max;
/** The actual set of nav polys that constitute the nav mesh */
std::vector<NavPoly> m_polys;
@ -102,39 +106,53 @@ public:
* also don't create one if it doesn't exists. */
static NavMesh *get() { return m_nav_mesh; }
// ------------------------------------------------------------------------
/** Return the minimum and maximum coordinates of this navmesh. */
void getBoundingBox(Vec3 *min, Vec3 *max)
{ *min=m_min; *max=m_max; }
// ------------------------------------------------------------------------
/** Returns a const reference to a NavPoly */
const NavPoly& getNavPoly(int n) const
{ return m_polys[n]; }
// ------------------------------------------------------------------------
/** Returns a const reference to a vertex(Vec3) */
const Vec3& getVertex(int n) const
{ return m_verts[n]; }
// ------------------------------------------------------------------------
/** Sets the vertices in a irrlicht vertex array to
* the 4 points of a navpoly.
* \param n The number of a navpoly.
* \param v The vertex array in which to set the vertices.
* \param color The color to use for this quad.
*/
void setVertices(int n, video::S3DVertex *v,
const video::SColor &color) const;
// ------------------------------------------------------------------------
/** Returns a const reference to a vector containing all vertices */
const std::vector<Vec3>& getAllVertices() const
{ return m_verts; }
// ------------------------------------------------------------------------
/** Returns the total number of polys */
unsigned int getNumberOfPolys() const
{ return m_n_polys; }
// ------------------------------------------------------------------------
/** Returns the total number of vertices */
unsigned int getNumberOfVerts() const
{ return m_n_verts; }
// ------------------------------------------------------------------------
/** Returns maximum vertices per polygon */
unsigned int getMaxVertsPerPoly() const
{ return m_nvp; }
// ------------------------------------------------------------------------
/** Returns the center of a polygon */
const Vec3& getCenterOfPoly(int n) const
{return m_polys[n].getCenter();}
// ------------------------------------------------------------------------
/** Returns a const referece to a vector containing the indices
* of polygons adjacent to a given polygon */
const std::vector<int>& getAdjacentPolys(int n) const
{return m_polys[n].getAdjacents();}
// ------------------------------------------------------------------------
/** Returns a const reference to a vector containing the vertices
* of a given polygon. */
const std::vector<Vec3> getVertsOfPoly(int n)

View File

@ -657,6 +657,53 @@ void Track::startMusic() const
music_manager->clearCurrentMusic();
} // startMusic
//-----------------------------------------------------------------------------
/** Loads the polygon graph for battle, i.e. the definition of all polys, and the way
* they are connected to each other. Input file name is hardcoded for now
*/
void Track::loadBattleGraph()
{
BattleGraph::create(m_root+"navmesh.xml");
if(BattleGraph::get()->getNumNodes()==0)
{
Log::warn("track", "No graph nodes defined for track '%s'\n",
m_filename.c_str());
}
else
{
//Check whether the hardware can do nonsquare or
// non power-of-two textures
video::IVideoDriver* const video_driver = irr_driver->getVideoDriver();
bool nonpower = false; //video_driver->queryFeature(video::EVDF_TEXTURE_NPOT);
bool nonsquare =
video_driver->queryFeature(video::EVDF_TEXTURE_NSQUARE);
//Create the minimap resizing it as necessary.
m_mini_map_size = World::getWorld()->getRaceGUI()->getMiniMapSize();
core::dimension2du size = m_mini_map_size
.getOptimalSize(!nonpower,!nonsquare);
BattleGraph::get()->makeMiniMap(size, "minimap::" + m_ident, video::SColor(127, 255, 255, 255),
&m_old_rtt_mini_map, &m_new_rtt_mini_map);
if (m_old_rtt_mini_map)
{
m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_old_rtt_mini_map->getSize().Width);
m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_old_rtt_mini_map->getSize().Height);
}
else if (m_new_rtt_mini_map)
{
m_minimap_x_scale = float(m_mini_map_size.Width) / float(m_new_rtt_mini_map->getWidth());
m_minimap_y_scale = float(m_mini_map_size.Height) / float(m_new_rtt_mini_map->getHeight());
}
else
{
m_minimap_x_scale = 0;
m_minimap_y_scale = 0;
}
}
} // loadBattleGraph
//-----------------------------------------------------------------------------
/** Loads the quad graph, i.e. the definition of all quads, and the way
* they are connected to each other.
@ -723,7 +770,10 @@ void Track::loadQuadGraph(unsigned int mode_id, const bool reverse)
void Track::mapPoint2MiniMap(const Vec3 &xyz, Vec3 *draw_at) const
{
QuadGraph::get()->mapPoint2MiniMap(xyz, draw_at);
if (m_is_arena && m_has_navmesh)
BattleGraph::get()->mapPoint2MiniMap(xyz, draw_at);
else
QuadGraph::get()->mapPoint2MiniMap(xyz, draw_at);
draw_at->setX(draw_at->getX() * m_minimap_x_scale);
draw_at->setY(draw_at->getY() * m_minimap_y_scale);
}
@ -1605,6 +1655,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
// the information about the size of the texture to render the mini
// map to.
if (!m_is_arena && !m_is_soccer && !m_is_cutscene) loadQuadGraph(mode_id, reverse_track);
else if (m_is_arena && !m_is_soccer && !m_is_cutscene && m_has_navmesh)
loadBattleGraph();
ItemManager::create();
@ -1829,15 +1881,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
delete root;
// ItemManager assumes the existence of a QuadGraph, that is why the
// quad graph is loaded before ItemManager::create(). This is undesirable
// but requires signifcant code overhaul to fix. The new battle graph
// performs its own computatoins separate from ItemManager. But
// Battle Graph needs ItemManager to be created, and all items to be
// added to ItemManager. Loading battle graph here is therefore a workaround
// to the main problem.
if (m_is_arena && !m_is_soccer && !m_is_cutscene && m_has_navmesh)
BattleGraph::create(m_root + "navmesh.xml");
BattleGraph::get()->findItemsOnGraphNodes();
if (UserConfigParams::m_track_debug &&
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES &&

View File

@ -379,6 +379,7 @@ private:
void loadTrackInfo();
void loadQuadGraph(unsigned int mode_id, const bool reverse);
void loadBattleGraph();
void convertTrackToBullet(scene::ISceneNode *node);
bool loadMainTrack(const XMLNode &node);
void createWater(const XMLNode &node);