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->search_step = 0;
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_goal;
node_start.hum = hum;
@ -315,6 +317,7 @@ FindPathStatus* MapService::AddFindPathRequest(Human* hum,
status->astar_search.SetStartAndGoalStates(node_start, node_goal);
}
list_add_tail(&status->entry, &findpath_list_);
findpath_requests_hash_[hum] = status;
return status;
}
@ -328,6 +331,12 @@ void MapService::DelFindPathRequest(Human* hum, FindPathStatus* status)
if (itr->second != status) {
abort();
}
if (use_navmesh_) {
if (status->navmesh_query) {
dtFreeNavMeshQuery(status->navmesh_query);
status->navmesh_query = nullptr;
}
}
list_del_init(&status->entry);
A8_SAFE_DELETE(status);
findpath_requests_hash_.erase(itr);
@ -335,39 +344,74 @@ void MapService::DelFindPathRequest(Human* hum, FindPathStatus* status)
void MapService::FindPathUpdate(FindPathStatus* find_status)
{
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 (use_navmesh_) {
float spos[3];
spos[0] = find_status->start_pos.x;
spos[1] = find_status->start_pos.y;
spos[2] = 0;
if (FindOk(find_status)) {
MapSearchNode *node = find_status->astar_search.GetSolutionStart();
int steps = 0;
for( ;; ) {
node = find_status->astar_search.GetSolutionNext();
if (!node) {
break;
}
float epos[3];
epos[0] = find_status->end_pos.x;
epos[1] = find_status->end_pos.x;
epos[2] = 0;
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);
};
dtQueryFilter filter;
filter.setIncludeFlags(0xffff);
filter.setExcludeFlags(0);
const float extents[3] = {2.f, 4.f, 2.f};
#if 0
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)
{
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)
{
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)

View File

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