Merge branch 'jump' into dev

This commit is contained in:
aozhiwei 2023-05-15 18:12:23 +08:00
commit 9fa4062b82
3 changed files with 201 additions and 6 deletions

View File

@ -2563,12 +2563,14 @@ void Creature::OnLand()
}
{
glm::vec3 center = GetPos().ToGlmVec3();
#if 0
room->map_instance->PtInHouse(GetPos().ToGlmVec3(), center);
#endif
room->map_instance->Scale(center);
glm::vec3 point;
bool ok = false;
for (int i = 0; i < 10; ++i) {
ok = room->map_instance->FindNearestPoint(center, 1.0f + 10 * i, point);
ok = room->map_instance->FindConnectableNearestPoint(center, 1.0f + 10 * i, point);
if (ok) {
break;
}
@ -2587,6 +2589,7 @@ void Creature::OnLand()
abort();
#endif
} else {
room->map_instance->AdjustOnLandPoint(point);
room->map_instance->UnScale(point);
}
Global::Instance()->verify_set_pos = 1;
@ -2595,6 +2598,7 @@ void Creature::OnLand()
GetMovement()->ClearPath();
room->grid_service->MoveCreature(this);
#ifdef DEBUG
if (IsPlayer()) {
a8::XPrintf("OnLoad ok:%d pos:%f,%f,%f\n",
{
ok ? 1 : 0,
@ -2602,6 +2606,7 @@ void Creature::OnLand()
point.y,
point.z
});
}
#endif
}
if (IsAndroid()) {

View File

@ -72,6 +72,20 @@ static void TraverseMapColliderNode(mc::ColliderNode* node, std::function<void (
}
}
class ConnectableQueryFilter : public dtQueryFilter
{
public:
MapInstance* map_instance = nullptr;
virtual bool passFilter(const dtPolyRef ref,
const dtMeshTile* tile,
const dtPoly* poly) const override
{
return map_instance->IsConnectablePoly(ref);
}
};
void MapInstance::Init()
{
map_meta_ = mt::Map::GetById(map_id);
@ -92,11 +106,6 @@ void MapInstance::Init()
map_service_->Init(map_meta_->map_width() / MAP_GRID_WIDTH,
map_meta_->map_height() / MAP_GRID_WIDTH,
MAP_GRID_WIDTH);
f8::UdpLog::Instance()->Info
("map_id:%d",
{
map_id
});
{
navmesh_ = dtAllocNavMesh();
FILE *fp = fopen((mt::MetaMgr::Instance()->GetResDir() + "map4.bin").c_str(), "rb");
@ -178,7 +187,14 @@ void MapInstance::Init()
navmesh_query_ = new dtNavMeshQuery();
navmesh_query_->init(navmesh_, 1024);
MarkMapAreaPolys();
MarkConnectablePolys();
LoadHouse();
f8::UdpLog::Instance()->Info
("map_id:%d connectable_polys:%d",
{
map_id,
connectable_polys_.size()
});
}
void MapInstance::UnInit()
@ -433,6 +449,34 @@ bool MapInstance::FindNearestPoint(const glm::vec3& center, float radius, glm::v
return true;
}
bool MapInstance::FindConnectableNearestPoint(const glm::vec3& center, float radius, glm::vec3& nearest_pt)
{
dtPolyRef startRef = INVALID_NAVMESH_POLYREF;
ConnectableQueryFilter filter;
filter.map_instance = this;
filter.setIncludeFlags(0xffff);
filter.setExcludeFlags(0);
const float extents[3] = {radius, 10.0f, radius};
float nearestPt[3];
float pos[3];
pos[0] = center.x;
pos[1] = center.y;
pos[2] = center.z;
navmesh_query_->findNearestPoly(pos, extents, &filter, &startRef, nearestPt);
if (!startRef) {
return false;
}
nearest_pt.x = nearestPt[0];
nearest_pt.y = nearestPt[1];
nearest_pt.z = nearestPt[2];
return true;
}
bool MapInstance::GetPosHeight(const Position& pos, float& out_height)
{
dtPolyRef startRef = INVALID_NAVMESH_POLYREF;
@ -1110,3 +1154,144 @@ bool MapInstance::GetNearestGrass(const glm::vec3& center, glm::vec3& out_pt)
}
return false;
}
void MapInstance::AdjustOnLandPoint(glm::vec3& point)
{
float center[3];
center[0] = point.x;
center[1] = point.y;
center[2] = point.z;
const float extents[3] = {4.0f/10.0f, 100.0f, 4.0f/10.0f};
ConnectableQueryFilter filter;
filter.map_instance = this;
filter.setIncludeFlags(0xffff);
filter.setExcludeFlags(0);
int poly_count = 0;
dtStatus status = navmesh_query_->queryPolygons(center,
extents,
&filter,
polys_,
&poly_count,
MAX_POLYS);
if (dtStatusFailed(status) || poly_count <= 0) {
return;
}
glm::vec3 orig = glm::vec3(point.x, 100.0f, point.z);;
glm::vec3 dir = glm::vec3(0.0f, -1.0f, 0.0f);
const dtPoly* nearest_poly = nullptr;
float nearest_distance = 0.0f;
for (int i = 0; i < poly_count; ++i) {
unsigned int slat = 0;
unsigned int it = 0;
unsigned int ip = 0;
navmesh_->decodePolyId(polys_[i], slat, it, ip);
const dtMeshTile* tile = navmesh_->getTileByRef(polys_[i]);
if (!tile) {
abort();
}
if (ip >= tile->header->polyCount) {
abort();
}
const dtPoly* poly = &tile->polys[ip];
for (int ii = 2; ii < poly->vertCount; ++ii) {
const float* va = &tile->verts[poly->verts[0]*3];
const float* vb = &tile->verts[poly->verts[ii-1]*3];
const float* vc = &tile->verts[poly->verts[ii]*3];
glm::vec3 v0 = glm::vec3(va[0], va[1], va[2]);
glm::vec3 v1 = glm::vec3(vb[0], vb[1], vb[2]);
glm::vec3 v2 = glm::vec3(vc[0], vc[1], vc[2]);
glm::vec2 bary_position;
float distance;
bool hit = glm::intersectRayTriangle
(orig,
dir,
v0,
v1,
v2,
bary_position,
distance
);
if (hit && distance > 0.00001f) {
if (nearest_poly) {
if (distance < nearest_distance) {
nearest_poly = poly;
nearest_distance = distance;
}
} else {
nearest_poly = poly;
nearest_distance = distance;
}
}
}//end for ii
}//end for i;
if (!nearest_poly) {
return;
}
glm::vec3 nearest_pt = orig + dir * nearest_distance;
point.y = nearest_pt.y;
}
void MapInstance::MarkConnectablePolys()
{
dtPolyRef startRef = INVALID_NAVMESH_POLYREF;
{
glm::vec3 pos = glm::vec3(5120.000000000000f, 6.250846862793f, 5120.000000000000f);
dtQueryFilter filter;
filter.setIncludeFlags(0xffff);
filter.setExcludeFlags(0);
const float extents[3] = {2.f, 4.f, 2.f};
float nearestPt[3];
Scale(pos);
float pos1[3];
pos1[0] = pos.x;
pos1[1] = pos.y;
pos1[2] = pos.z;
navmesh_query_->findNearestPoly(pos1, extents, &filter, &startRef, nearestPt);
}
if (!startRef) {
abort();
}
std::list<dtPolyRef> queue;
queue.push_back(startRef);
connectable_polys_.insert(startRef);
while (!queue.empty()) {
dtPolyRef poly_ref = queue.front();
queue.pop_front();
const dtPoly* poly = nullptr;
const dtMeshTile* tile = 0;
navmesh_->getTileAndPolyByRefUnsafe(poly_ref, &tile, &poly);
for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = tile->links[i].next) {
dtPolyRef neighbour_ref = tile->links[i].ref;
if (!neighbour_ref) {
continue;
}
if (connectable_polys_.find(neighbour_ref) !=
connectable_polys_.end()) {
continue;
}
queue.push_back(neighbour_ref);
connectable_polys_.insert(neighbour_ref);
}
}
}
bool MapInstance::IsConnectablePoly(dtPolyRef poly_ref)
{
return connectable_polys_.find(poly_ref) != connectable_polys_.end();
}

View File

@ -48,6 +48,7 @@ class MapInstance : public std::enable_shared_from_this<MapInstance>
int& same_polys_flags, std::vector<dtPolyRef>& spec_polys,
unsigned short exclude_flags);
bool FindNearestPoint(const glm::vec3& center, float radius, glm::vec3& nearestPt);
bool FindConnectableNearestPoint(const glm::vec3& center, float radius, glm::vec3& nearestPt);
bool GetPosHeight(const Position& pos, float& out_height);
dtPoly* GetPoly(glm::vec3 pos, int& poly_idx);
void Scale(glm::vec3& v);
@ -59,10 +60,13 @@ class MapInstance : public std::enable_shared_from_this<MapInstance>
bool SceneRaycast(const glm::vec3& orig, const glm::vec3& dir, float max_distance,
glm::vec3& hit_pos, float& ray_length);
bool GetNearestGrass(const glm::vec3& center, glm::vec3& out_pt);
void AdjustOnLandPoint(glm::vec3& point);
bool IsConnectablePoly(dtPolyRef poly_ref);
private:
void LoadHouse();
void MarkMapAreaPolys();
void MarkConnectablePolys();
private:
dtNavMesh* navmesh_ = nullptr;
@ -78,6 +82,7 @@ class MapInstance : public std::enable_shared_from_this<MapInstance>
std::list<HouseInfo> houses_;
std::vector<mc::ColliderNode*> things_;
std::set<dtPolyRef> connectable_polys_;
std::string map_tpl_name_;
const mt::Map* map_meta_ = nullptr;