This commit is contained in:
aozhiwei 2020-08-10 20:04:05 +08:00
parent 0dd4f74bee
commit d5abdfbc95
2 changed files with 111 additions and 84 deletions

View File

@ -15,6 +15,7 @@
#include "room.h"
#include "roomobstacle.h"
const int MAX_POLYS = 256;
static const int INVALID_NAVMESH_POLYREF = 0;
MapService::MapService()
@ -347,91 +348,9 @@ void MapService::DelFindPathRequest(Human* hum, FindPathStatus* status)
void MapService::FindPathUpdate(FindPathStatus* find_status)
{
if (use_navmesh_) {
float spos[3];
spos[0] = find_status->start_pos.x;
spos[1] = find_status->start_pos.y;
spos[2] = 0;
float epos[3];
epos[0] = find_status->end_pos.x;
epos[1] = find_status->end_pos.x;
epos[2] = 0;
dtQueryFilter filter;
filter.setIncludeFlags(0xffff);
filter.setExcludeFlags(0);
const float extents[3] = {2.f, 4.f, 2.f};
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);
if (!startRef || !endRef) {
find_status->navmesh_search_state = kNavMesh_SearchFailed;
return;
}
const int MAX_POLYS = 256;
dtPolyRef polys[MAX_POLYS];
int npolys;
float straightPath[MAX_POLYS * 3];
unsigned char straightPathFlags[MAX_POLYS];
dtPolyRef straightPathPolys[MAX_POLYS];
int nstraightPath;
int pos = 0;
find_status->navmesh_query->findPath(startRef, endRef, startNearestPt, endNearestPt, &filter, polys, &npolys, MAX_POLYS);
nstraightPath = 0;
if (npolys) {
float epos1[3];
dtVcopy(epos1, endNearestPt);
if (polys[npolys-1] != endRef) {
find_status->navmesh_query->closestPointOnPoly(polys[npolys-1], endNearestPt, epos1, 0);
}
find_status->navmesh_query->findStraightPath(startNearestPt, endNearestPt, polys, npolys, straightPath, straightPathFlags, straightPathPolys, &nstraightPath, MAX_POLYS);
#if 0
a8::Vec3 currpos;
for(int i = 0; i < nstraightPath * 3; ) {
currpos.x = straightPath[i++];
currpos.y = straightPath[i++];
currpos.z = straightPath[i++];
paths.push_back(currpos);
pos++;
}
#endif
}
UpdateNavmesh(find_status);
} 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);
};
}
UpdateAStar(find_status);
}
}
@ -504,3 +423,109 @@ void MapService::DoMove(FindPathStatus* find_status)
#endif
}
}
void MapService::UpdateAStar(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 (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);
};
}
}
void MapService::UpdateNavmesh(FindPathStatus* find_status)
{
dtNavMeshQuery* navmesh_query = find_status->navmesh_query;
float spos[3];
spos[0] = find_status->start_pos.x;
spos[1] = find_status->start_pos.y;
spos[2] = 0;
float epos[3];
epos[0] = find_status->end_pos.x;
epos[1] = find_status->end_pos.x;
epos[2] = 0;
dtQueryFilter filter;
filter.setIncludeFlags(0xffff);
filter.setExcludeFlags(0);
const float extents[3] = {2.f, 4.f, 2.f};
dtPolyRef start_ref = INVALID_NAVMESH_POLYREF;
dtPolyRef end_ref = INVALID_NAVMESH_POLYREF;
float start_nearest_pt[3];
float end_nearest_pt[3];
navmesh_query->findNearestPoly(spos, extents, &filter, &start_ref, start_nearest_pt);
navmesh_query->findNearestPoly(epos, extents, &filter, &end_ref, end_nearest_pt);
if (!start_ref || !end_ref) {
find_status->navmesh_search_state = kNavMesh_SearchFailed;
return;
}
dtPolyRef polys[MAX_POLYS];
int npolys;
float straight_path[MAX_POLYS * 3];
unsigned char straight_path_flags[MAX_POLYS];
dtPolyRef straight_path_polys[MAX_POLYS];
int nstraight_path;
navmesh_query->findPath(start_ref,
end_ref,
start_nearest_pt,
end_nearest_pt,
&filter,
polys,
&npolys,
MAX_POLYS);
nstraight_path = 0;
if (npolys) {
float epos1[3];
dtVcopy(epos1, end_nearest_pt);
if (polys[npolys-1] != end_ref) {
navmesh_query->closestPointOnPoly(polys[npolys-1], end_nearest_pt, epos1, 0);
}
navmesh_query->findStraightPath(start_nearest_pt,
end_nearest_pt,
polys,
npolys,
straight_path,
straight_path_flags,
straight_path_polys,
&nstraight_path,
MAX_POLYS);
for (int i = 0; i < nstraight_path * 3; ) {
MovePathPoint point;
point.pos.x = straight_path[i++];
point.pos.y = straight_path[i++];
straight_path[i++];
find_status->out_points.push_back(point);
}
find_status->navmesh_search_state = kNavMesh_SearchOk;
} else {
find_status->navmesh_search_state = kNavMesh_SearchFailed;
}
}

View File

@ -98,6 +98,8 @@ class MapService
private:
int GetGridId(float world_x, float world_y);
bool IsValidPos(int x, int y);
void UpdateAStar(FindPathStatus* find_status);
void UpdateNavmesh(FindPathStatus* find_status);
private:
bool use_navmesh_ = false;