Allow TrackSector to use with new graph class

This commit is contained in:
Benau 2016-09-15 15:47:17 +08:00
parent 05ad91c701
commit 1491236e84
10 changed files with 104 additions and 50 deletions

View File

@ -21,7 +21,6 @@
#include "karts/controller/ai_base_controller.hpp"
#include "race/race_manager.hpp"
#include "utils/random_generator.hpp"
#undef AI_DEBUG
#ifdef AI_DEBUG

View File

@ -24,7 +24,6 @@
#include "karts/controller/kart_control.hpp"
#include "karts/kart_properties.hpp"
#include "modes/soccer_world.hpp"
#include "tracks/battle_graph.hpp"
#ifdef AI_DEBUG
#include "irrlicht.h"

View File

@ -34,9 +34,9 @@
#include "karts/controller/soccer_ai.hpp"
#include "physics/physics.hpp"
#include "states_screens/race_gui_base.hpp"
#include "tracks/battle_graph.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object_manager.hpp"
#include "tracks/track_sector.hpp"
#include "utils/constants.hpp"
#include <IMeshSceneNode.h>
@ -61,6 +61,7 @@ SoccerWorld::SoccerWorld() : WorldWithRank()
m_use_highscores = false;
m_red_ai = 0;
m_blue_ai = 0;
m_ball_track_sector = NULL;
} // SoccerWorld
//-----------------------------------------------------------------------------
@ -69,6 +70,15 @@ SoccerWorld::SoccerWorld() : WorldWithRank()
SoccerWorld::~SoccerWorld()
{
m_goal_sound->deleteSFX();
delete m_ball_track_sector;
m_ball_track_sector = NULL;
for (unsigned int i = 0; i < m_kart_track_sector.size(); i++)
{
delete m_kart_track_sector[i];
}
m_kart_track_sector.clear();
} // ~SoccerWorld
//-----------------------------------------------------------------------------
@ -88,6 +98,14 @@ void SoccerWorld::init()
m_goal_target = race_manager->getMaxGoal();
m_goal_sound = SFXManager::get()->createSoundSource("goal_scored");
if (m_track->hasNavMesh())
{
// Init track sector if navmesh is found
m_ball_track_sector = new TrackSector();
for (unsigned int i = 0; i < m_karts.size(); i++)
m_kart_track_sector.push_back(new TrackSector());
}
TrackObjectManager* tom = getTrack()->getTrackObjectManager();
assert(tom);
PtrVector<TrackObject>& objects = tom->getObjects();
@ -141,10 +159,17 @@ void SoccerWorld::reset()
m_goal_sound->stop();
}
if (m_track->hasNavMesh())
{
m_ball_track_sector->reset();
for (unsigned int i = 0; i < m_karts.size(); i++)
m_kart_track_sector[i]->reset();
}
initKartList();
resetAllPosition();
m_ball->reset();
m_bgd.reset();
// Make the player kart in profiling mode up
// ie make this kart less likely to affect gaming result
if (UserConfigParams::m_arena_ai_stats)
@ -439,9 +464,7 @@ void SoccerWorld::updateKartNodes()
for (unsigned int i = 0; i < n; i++)
{
if (m_karts[i]->isEliminated()) continue;
m_kart_on_node[i] = BattleGraph::get()->pointToNode(m_kart_on_node[i],
m_karts[i]->getXYZ(), false/*ignore_vertical*/);
m_kart_track_sector[i]->update(m_karts[i]->getXYZ());
}
} // updateKartNodes
@ -461,11 +484,9 @@ void SoccerWorld::updateBallPosition(float dt)
if (m_track->hasNavMesh())
{
m_ball_on_node = BattleGraph::get()->pointToNode(m_ball_on_node,
getBallPosition(), true/*ignore_vertical*/);
if (m_ball_on_node == BattleGraph::UNKNOWN_POLY &&
getPhase() == RACE_PHASE)
m_ball_track_sector
->update(getBallPosition(), true/*ignore_vertical*/);
if (!m_ball_track_sector->isOnRoad() && getPhase() == RACE_PHASE)
{
m_ball_invalid_timer += dt;
// Reset the ball and karts if out of navmesh after 2 seconds
@ -486,12 +507,19 @@ void SoccerWorld::updateBallPosition(float dt)
} // updateBallPosition
//-----------------------------------------------------------------------------
void SoccerWorld::resetAllPosition()
int SoccerWorld::getKartNode(unsigned int kart_id) const
{
m_kart_on_node.clear();
m_kart_on_node.resize(m_karts.size(), BattleGraph::UNKNOWN_POLY);
m_ball_on_node = BattleGraph::UNKNOWN_POLY;
} // resetAllPosition
assert(kart_id < m_kart_track_sector.size());
return m_kart_track_sector[kart_id]->getCurrentGraphNode();
} // getKartNode
//-----------------------------------------------------------------------------
int SoccerWorld::getBallNode() const
{
assert(m_ball_track_sector != NULL);
return m_ball_track_sector->getCurrentGraphNode();
} // getBallNode
//-----------------------------------------------------------------------------
SoccerTeam SoccerWorld::getKartTeam(unsigned int kart_id) const
{

View File

@ -31,6 +31,7 @@
class AbstractKart;
class Controller;
class TrackObject;
class TrackSector;
/** An implementation of World, to provide the soccer game mode
* Notice: In soccer world, true goal means blue, false means red.
@ -279,8 +280,8 @@ private:
std::map<int, unsigned int> m_kart_position_map;
/** Data generated from navmesh */
std::vector<int> m_kart_on_node;
int m_ball_on_node;
std::vector<TrackSector*> m_kart_track_sector;
TrackSector* m_ball_track_sector;
int m_red_ai;
int m_blue_ai;
@ -293,8 +294,6 @@ private:
void updateKartNodes();
/** Function to update the location the ball on the polygon map */
void updateBallPosition(float dt);
/** Clean up */
void resetAllPosition();
/** Function to update data for AI usage. */
void updateAIData();
/** Get number of teammates in a team, used by starting position assign. */
@ -357,11 +356,9 @@ public:
m_blue_score_times : m_red_score_times);
}
// ------------------------------------------------------------------------
int getKartNode(unsigned int kart_id) const
{ return m_kart_on_node[kart_id]; }
int getKartNode(unsigned int kart_id) const;
// ------------------------------------------------------------------------
int getBallNode() const
{ return m_ball_on_node; }
int getBallNode() const;
// ------------------------------------------------------------------------
const Vec3& getBallPosition() const
{ return (Vec3&)m_ball_body->getCenterOfMassTransform().getOrigin(); }

View File

@ -28,9 +28,9 @@
#include "karts/kart_properties.hpp"
#include "physics/physics.hpp"
#include "states_screens/race_gui_base.hpp"
#include "tracks/battle_graph.hpp"
#include "tracks/track.hpp"
#include "tracks/track_object_manager.hpp"
#include "tracks/track_sector.hpp"
#include "utils/constants.hpp"
#include <string>
@ -65,6 +65,12 @@ void ThreeStrikesBattle::init()
WorldWithRank::init();
m_display_rank = false;
m_kart_info.resize(m_karts.size());
if (m_track->hasNavMesh())
{
// Init track sector if navmesh is found
for (unsigned int i = 0; i < m_karts.size(); i++)
m_kart_track_sector.push_back(new TrackSector());
}
} // ThreeStrikesBattle
//-----------------------------------------------------------------------------
@ -80,6 +86,12 @@ ThreeStrikesBattle::~ThreeStrikesBattle()
// freed once all refernces to it (which will happen once all
// karts are being freed, which would have a pointer to this mesh)
irr_driver->removeMeshFromCache(m_tire);
for (unsigned int i = 0; i < m_kart_track_sector.size(); i++)
{
delete m_kart_track_sector[i];
}
m_kart_track_sector.clear();
} // ~ThreeStrikesBattle
//-----------------------------------------------------------------------------
@ -93,8 +105,7 @@ void ThreeStrikesBattle::reset()
for(unsigned int n=0; n<kart_amount; n++)
{
m_kart_info[n].m_lives = 3;
m_kart_info[n].m_on_node = BattleGraph::UNKNOWN_POLY;
m_kart_info[n].m_lives = 3;
// no positions in this mode
m_karts[n]->setPosition(-1);
@ -134,6 +145,12 @@ void ThreeStrikesBattle::reset()
m_track->getTrackObjectManager()->removeObject(obj);
}
m_tires.clearWithoutDeleting();
if (m_track->hasNavMesh())
{
for (unsigned int i = 0; i < kart_amount; i++)
m_kart_track_sector[i]->reset();
}
} // reset
//-----------------------------------------------------------------------------
@ -470,19 +487,17 @@ void ThreeStrikesBattle::updateKartNodes()
for (unsigned int i = 0; i < n; i++)
{
if (m_karts[i]->isEliminated()) continue;
m_kart_info[i].m_on_node = BattleGraph::get()
->pointToNode(m_kart_info[i].m_on_node,
m_karts[i]->getXYZ(), false/*ignore_vertical*/);
m_kart_track_sector[i]->update(m_karts[i]->getXYZ());
}
}
} // updateKartNodes
//-----------------------------------------------------------------------------
/** Get the which node the kart located in navigation mesh.
*/
int ThreeStrikesBattle::getKartNode(unsigned int kart_id) const
{
return m_kart_info[kart_id].m_on_node;
assert(kart_id < m_kart_track_sector.size());
return m_kart_track_sector[kart_id]->getCurrentGraphNode();
} // getKartNode
//-----------------------------------------------------------------------------

View File

@ -29,6 +29,7 @@
#include <string>
class PhysicalObject;
class TrackSector;
/**
* \brief An implementation of World, to provide the 3 strikes battle game mode
@ -40,7 +41,6 @@ private:
struct BattleInfo
{
int m_lives;
int m_on_node;
};
/** This vector contains an 'BattleInfo' struct for every kart in the race.
@ -71,7 +71,9 @@ private:
PtrVector<TrackObject, REF> m_tires;
/** Function to update the locations of all karts on the polygon map */
std::vector<TrackSector*> m_kart_track_sector;
/** Function to update the locations of all karts on the navigation map */
void updateKartNodes();
/** Profiling usage */

View File

@ -357,7 +357,7 @@ std::vector<int> ArenaGraph::getPathFromTo(int from, int to,
} // getPathFromTo
// ============================================================================
/** Unit testing for battle graph distance and parent node computation.
/** Unit testing for arena graph distance and parent node computation.
* Instead of using hand-tuned test cases we use the tested, verified and
* easier to understand Floyd-Warshall algorithm to compute the distances,
* and check if the (significanty faster) Dijkstra algorithm gives the same
@ -391,7 +391,7 @@ void ArenaGraph::unitTesting()
{
if(ag->m_distance_matrix[i][j] - distance_matrix[i][j] > 0.001f)
{
Log::error("BattleGraph",
Log::error("ArenaGraph",
"Incorrect distance %d, %d: Dijkstra: %f F.W.: %f",
i, j, distance_matrix[i][j], ag->m_distance_matrix[i][j]);
error_count++;
@ -412,17 +412,17 @@ void ArenaGraph::unitTesting()
std::vector<int> floyd_path = getPathFromTo(i, j, ag->m_parent_node);
if(dijkstra_path.size()!=floyd_path.size())
{
Log::error("BattleGraph",
Log::error("ArenaGraph",
"Incorrect path length %d, %d: Dijkstra: %d F.W.: %d",
i, j, parent_poly[i][j], ag->m_parent_poly[i][j]);
continue;
}
Log::error("BattleGraph", "Path problems from %d to %d:",
Log::error("ArenaGraph", "Path problems from %d to %d:",
i, j);
for (unsigned k = 0; k < dijkstra_path.size(); k++)
{
if(dijkstra_path[k]!=floyd_path[k])
Log::error("BattleGraph", "%d/%d dijkstra: %d floyd %d",
Log::error("ArenaGraph", "%d/%d dijkstra: %d floyd %d",
k, dijkstra_path.size(), dijkstra_path[k],
floyd_path[k]);
} // for k<dijkstra_path.size()

View File

@ -44,7 +44,7 @@ public:
// ------------------------------------------------------------------------
const std::vector<int>& getAdjacentNodes() { return m_adjacent_nodes; }
// ------------------------------------------------------------------------
const std::vector<int>& getNearbyNodes() { return m_nearby_nodes; }
std::vector<int>* getNearbyNodes() { return &m_nearby_nodes; }
// ------------------------------------------------------------------------
void setAdjacentNodes(const std::vector<int>& nodes)
{

View File

@ -21,6 +21,8 @@
#include "tracks/check_manager.hpp"
#include "tracks/check_structure.hpp"
#include "tracks/track_sector.hpp"
#include "tracks/arena_graph.hpp"
#include "tracks/arena_node.hpp"
#include "tracks/quad_graph.hpp"
#include "tracks/graph_node.hpp"
@ -46,23 +48,35 @@ void TrackSector::reset()
* the specified point.
* \param xyz The new coordinates to search the graph node for.
*/
void TrackSector::update(const Vec3 &xyz)
void TrackSector::update(const Vec3 &xyz, bool ignore_vertical)
{
int prev_sector = m_current_graph_node;
QuadGraph::get()->findRoadSector(xyz, &m_current_graph_node);
m_on_road = m_current_graph_node != QuadGraph::UNKNOWN_SECTOR;
const ArenaGraph* ag = ArenaGraph::get();
std::vector<int>* test_nodes = NULL;
if (ag)
{
// For ArenaGraph, only test nodes around current node
if (prev_sector != Graph::UNKNOWN_SECTOR)
test_nodes = ag->getNode(prev_sector)->getNearbyNodes();
}
Graph::get()->findRoadSector(xyz, &m_current_graph_node, test_nodes,
ignore_vertical);
m_on_road = m_current_graph_node != Graph::UNKNOWN_SECTOR;
// If m_track_sector == UNKNOWN_SECTOR, then the kart is not on top of
// the road, so we have to use search for the closest graph node.
if(m_current_graph_node == QuadGraph::UNKNOWN_SECTOR)
if(m_current_graph_node == Graph::UNKNOWN_SECTOR)
{
m_current_graph_node =
QuadGraph::get()->findOutOfRoadSector(xyz,
prev_sector);
m_current_graph_node = Graph::get()->findOutOfRoadSector(xyz,
prev_sector, test_nodes, ignore_vertical);
// ArenaGraph (battle and soccer mode) doesn't need the code below
if (ag) return;
}
else
{
if (ag) return;
// keep the current quad as the latest valid one IF the player has one
// of the required checklines
const GraphNode* gn = QuadGraph::get()->getNode(m_current_graph_node);

View File

@ -57,7 +57,7 @@ public:
TrackSector();
void reset();
void rescue();
void update(const Vec3 &xyz);
void update(const Vec3 &xyz, bool ignore_vertical = false);
float getRelativeDistanceToCenter() const;
// ------------------------------------------------------------------------
/** Returns how far the the object is from the start line. */