This commit is contained in:
aozhiwei 2020-08-10 11:18:27 +08:00
parent d0ee13ac0a
commit 4ef4228bbb
2 changed files with 83 additions and 27 deletions

View File

@ -300,8 +300,10 @@ FindPathStatus* MapService::AddFindPathRequest(Human* hum,
status->end_pos = end_pos; status->end_pos = end_pos;
status->search_step = 0; status->search_step = 0;
status->max_step_num = max_step_num; status->max_step_num = max_step_num;
list_add_tail(&status->entry, &findpath_list_); if (use_navmesh_) {
{ status->navmesh_query = new dtNavMeshQuery();
status->navmesh_query->init(navmesh_, 1024);
} else {
MapSearchNode node_start; MapSearchNode node_start;
MapSearchNode node_goal; MapSearchNode node_goal;
node_start.hum = hum; node_start.hum = hum;
@ -315,6 +317,7 @@ FindPathStatus* MapService::AddFindPathRequest(Human* hum,
status->astar_search.SetStartAndGoalStates(node_start, node_goal); status->astar_search.SetStartAndGoalStates(node_start, node_goal);
} }
list_add_tail(&status->entry, &findpath_list_);
findpath_requests_hash_[hum] = status; findpath_requests_hash_[hum] = status;
return status; return status;
} }
@ -328,6 +331,12 @@ void MapService::DelFindPathRequest(Human* hum, FindPathStatus* status)
if (itr->second != status) { if (itr->second != status) {
abort(); abort();
} }
if (use_navmesh_) {
if (status->navmesh_query) {
dtFreeNavMeshQuery(status->navmesh_query);
status->navmesh_query = nullptr;
}
}
list_del_init(&status->entry); list_del_init(&status->entry);
A8_SAFE_DELETE(status); A8_SAFE_DELETE(status);
findpath_requests_hash_.erase(itr); findpath_requests_hash_.erase(itr);
@ -335,39 +344,74 @@ void MapService::DelFindPathRequest(Human* hum, FindPathStatus* status)
void MapService::FindPathUpdate(FindPathStatus* find_status) void MapService::FindPathUpdate(FindPathStatus* find_status)
{ {
do { if (use_navmesh_) {
find_status->search_state = find_status->astar_search.SearchStep(); float spos[3];
++find_status->search_step; spos[0] = find_status->start_pos.x;
} while (find_status->search_state == AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING); spos[1] = find_status->start_pos.y;
spos[2] = 0;
if (FindOk(find_status)) { float epos[3];
MapSearchNode *node = find_status->astar_search.GetSolutionStart(); epos[0] = find_status->end_pos.x;
int steps = 0; epos[1] = find_status->end_pos.x;
for( ;; ) { epos[2] = 0;
node = find_status->astar_search.GetSolutionNext();
if (!node) {
break;
}
steps++; dtQueryFilter filter;
MovePathPoint point; filter.setIncludeFlags(0xffff);
point.pos = a8::Vec2( filter.setExcludeFlags(0);
node->x * cell_width_ + cell_width_ / 2,
node->y * cell_width_ + cell_width_ / 2 const float extents[3] = {2.f, 4.f, 2.f};
); #if 0
find_status->out_points.push_back(point); dtPolyRef startRef = INVALID_NAVMESH_POLYREF;
}; dtPolyRef endRef = INVALID_NAVMESH_POLYREF;
float startNearestPt[3];
float endNearestPt[3];
find_status->navmesh_query->findNearestPoly(spos, extents, &filter, &startRef, startNearestPt);
find_status->navmesh_query->findNearestPoly(epos, extents, &filter, &endRef, endNearestPt);
#endif
} else {
do {
find_status->search_state = find_status->astar_search.SearchStep();
++find_status->search_step;
} while (find_status->search_state == AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING);
if (FindOk(find_status)) {
MapSearchNode *node = find_status->astar_search.GetSolutionStart();
int steps = 0;
for( ;; ) {
node = find_status->astar_search.GetSolutionNext();
if (!node) {
break;
}
steps++;
MovePathPoint point;
point.pos = a8::Vec2(
node->x * cell_width_ + cell_width_ / 2,
node->y * cell_width_ + cell_width_ / 2
);
find_status->out_points.push_back(point);
};
}
} }
} }
bool MapService::FindOk(FindPathStatus* find_status) bool MapService::FindOk(FindPathStatus* find_status)
{ {
return find_status->search_state == AStarSearch<MapSearchNode>::SEARCH_STATE_SUCCEEDED; if (use_navmesh_) {
return find_status->navmesh_search_state == kNavMesh_SearchOk;
} else {
return find_status->search_state == AStarSearch<MapSearchNode>::SEARCH_STATE_SUCCEEDED;
}
} }
bool MapService::FindFailed(FindPathStatus* find_status) bool MapService::FindFailed(FindPathStatus* find_status)
{ {
return find_status->search_state == AStarSearch<MapSearchNode>::SEARCH_STATE_FAILED; if (use_navmesh_) {
return find_status->navmesh_search_state == kNavMesh_SearchFailed;
} else {
return find_status->search_state == AStarSearch<MapSearchNode>::SEARCH_STATE_FAILED;
}
} }
bool MapService::MoveDone(FindPathStatus* find_status) bool MapService::MoveDone(FindPathStatus* find_status)

View File

@ -2,6 +2,9 @@
#include "mapsearchnode.h" #include "mapsearchnode.h"
class dtNavMesh;
class dtNavMeshQuery;
class Room;
class Human; class Human;
class ColliderComponent; class ColliderComponent;
@ -16,6 +19,13 @@ enum TILE_STATE
TILE_STATE_CLOSED = 9 TILE_STATE_CLOSED = 9
}; };
enum NavMeshSearchState_e
{
kNavMesh_Searching = 0,
kNavMesh_SearchOk = 1,
kNavMesh_SearchFailed = 2,
};
struct CellNode struct CellNode
{ {
ColliderComponent* collider; ColliderComponent* collider;
@ -39,6 +49,7 @@ struct FindPathStatus
Human* hum = nullptr; Human* hum = nullptr;
a8::Vec2 start_pos; a8::Vec2 start_pos;
a8::Vec2 end_pos; a8::Vec2 end_pos;
int search_step = 0; int search_step = 0;
int max_step_num = 0; int max_step_num = 0;
int path_index = 0; int path_index = 0;
@ -47,14 +58,15 @@ struct FindPathStatus
int search_state = AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING; int search_state = AStarSearch<MapSearchNode>::SEARCH_STATE_SEARCHING;
AStarSearch<MapSearchNode> astar_search; AStarSearch<MapSearchNode> astar_search;
int navmesh_search_state = kNavMesh_Searching;
dtNavMeshQuery* navmesh_query = nullptr;
FindPathStatus() FindPathStatus()
{ {
INIT_LIST_HEAD(&entry); INIT_LIST_HEAD(&entry);
} }
}; };
class Room;
class dtNavMesh;
class MapService class MapService
{ {
public: public:
@ -88,6 +100,7 @@ class MapService
bool IsValidPos(int x, int y); bool IsValidPos(int x, int y);
private: private:
bool use_navmesh_ = false;
dtNavMesh* navmesh_ = nullptr; dtNavMesh* navmesh_ = nullptr;
list_head* map_cells_ = nullptr; list_head* map_cells_ = nullptr;
int map_width_ = 0; int map_width_ = 0;
@ -98,5 +111,4 @@ class MapService
list_head findpath_list_; list_head findpath_list_;
std::map<Human*, FindPathStatus*> findpath_requests_hash_; std::map<Human*, FindPathStatus*> findpath_requests_hash_;
std::map<ColliderComponent*, CellNode*> node_hash_; std::map<ColliderComponent*, CellNode*> node_hash_;
}; };