From 1491236e8425501c529893c303575d1780b563ee Mon Sep 17 00:00:00 2001 From: Benau Date: Thu, 15 Sep 2016 15:47:17 +0800 Subject: [PATCH] Allow TrackSector to use with new graph class --- src/karts/controller/arena_ai.hpp | 1 - src/karts/controller/soccer_ai.cpp | 1 - src/modes/soccer_world.cpp | 58 ++++++++++++++++++++++-------- src/modes/soccer_world.hpp | 13 +++---- src/modes/three_strikes_battle.cpp | 33 ++++++++++++----- src/modes/three_strikes_battle.hpp | 6 ++-- src/tracks/arena_graph.cpp | 10 +++--- src/tracks/arena_node.hpp | 2 +- src/tracks/track_sector.cpp | 28 +++++++++++---- src/tracks/track_sector.hpp | 2 +- 10 files changed, 104 insertions(+), 50 deletions(-) diff --git a/src/karts/controller/arena_ai.hpp b/src/karts/controller/arena_ai.hpp index a30c87bff..40122e5b6 100644 --- a/src/karts/controller/arena_ai.hpp +++ b/src/karts/controller/arena_ai.hpp @@ -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 diff --git a/src/karts/controller/soccer_ai.cpp b/src/karts/controller/soccer_ai.cpp index 85ff79222..146fdffd0 100644 --- a/src/karts/controller/soccer_ai.cpp +++ b/src/karts/controller/soccer_ai.cpp @@ -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" diff --git a/src/modes/soccer_world.cpp b/src/modes/soccer_world.cpp index a56c32728..eba9e1479 100644 --- a/src/modes/soccer_world.cpp +++ b/src/modes/soccer_world.cpp @@ -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 @@ -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& 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 { diff --git a/src/modes/soccer_world.hpp b/src/modes/soccer_world.hpp index 5875d6c4f..97d57b2e5 100644 --- a/src/modes/soccer_world.hpp +++ b/src/modes/soccer_world.hpp @@ -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 m_kart_position_map; /** Data generated from navmesh */ - std::vector m_kart_on_node; - int m_ball_on_node; + std::vector 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(); } diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index 83282c045..535671d1c 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -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 @@ -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; nsetPosition(-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 //----------------------------------------------------------------------------- diff --git a/src/modes/three_strikes_battle.hpp b/src/modes/three_strikes_battle.hpp index 2d01a646b..07f90ad27 100644 --- a/src/modes/three_strikes_battle.hpp +++ b/src/modes/three_strikes_battle.hpp @@ -29,6 +29,7 @@ #include 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 m_tires; - /** Function to update the locations of all karts on the polygon map */ + std::vector m_kart_track_sector; + + /** Function to update the locations of all karts on the navigation map */ void updateKartNodes(); /** Profiling usage */ diff --git a/src/tracks/arena_graph.cpp b/src/tracks/arena_graph.cpp index 7233a8c57..9c1f65759 100644 --- a/src/tracks/arena_graph.cpp +++ b/src/tracks/arena_graph.cpp @@ -357,7 +357,7 @@ std::vector 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 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& getAdjacentNodes() { return m_adjacent_nodes; } // ------------------------------------------------------------------------ - const std::vector& getNearbyNodes() { return m_nearby_nodes; } + std::vector* getNearbyNodes() { return &m_nearby_nodes; } // ------------------------------------------------------------------------ void setAdjacentNodes(const std::vector& nodes) { diff --git a/src/tracks/track_sector.cpp b/src/tracks/track_sector.cpp index 6273b4999..8f1e8a28f 100644 --- a/src/tracks/track_sector.cpp +++ b/src/tracks/track_sector.cpp @@ -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* 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); diff --git a/src/tracks/track_sector.hpp b/src/tracks/track_sector.hpp index 138db8e6f..f10716dd0 100644 --- a/src/tracks/track_sector.hpp +++ b/src/tracks/track_sector.hpp @@ -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. */