添加navmesh初始化
This commit is contained in:
parent
710dc290f7
commit
de55876ca5
@ -23,6 +23,7 @@ include_directories(
|
||||
/usr/include/glm
|
||||
../../third_party
|
||||
../../third_party/behaviac/inc
|
||||
../../third_party/recastnavigation/Recast/Include
|
||||
../../third_party/recastnavigation/Detour/Include
|
||||
../../third_party/recastnavigation/DetourTileCache/Include
|
||||
.
|
||||
@ -42,6 +43,10 @@ aux_source_directory(../../third_party/framework/cpp
|
||||
SRC_LIST
|
||||
)
|
||||
|
||||
aux_source_directory(../../third_party/recastnavigation/Recast/Source
|
||||
SRC_LIST
|
||||
)
|
||||
|
||||
aux_source_directory(../../third_party/recastnavigation/Detour/Source
|
||||
SRC_LIST
|
||||
)
|
||||
|
@ -1,5 +1,15 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "Recast.h"
|
||||
#include "RecastAlloc.h"
|
||||
#include "DetourTileCache.h"
|
||||
#include "DetourTileCacheBuilder.h"
|
||||
|
||||
#include "DetourNavMeshBuilder.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "DetourNavMesh.h"
|
||||
|
||||
#include "mapinstance.h"
|
||||
#include "mapservice.h"
|
||||
#include "gridservice.h"
|
||||
@ -61,6 +71,9 @@ void MapInstance::Init()
|
||||
#ifdef DEBUG
|
||||
OutputObjFile();
|
||||
#endif
|
||||
#ifdef FIND_PATH_TEST
|
||||
GenNavMesh();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MapInstance::UnInit()
|
||||
@ -378,3 +391,275 @@ void MapInstance::OutputObjFile()
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
struct LinearAllocator : public dtTileCacheAlloc
|
||||
{
|
||||
unsigned char* buffer;
|
||||
size_t capacity;
|
||||
size_t top;
|
||||
size_t high;
|
||||
|
||||
LinearAllocator(const size_t cap) : buffer(0), capacity(0), top(0), high(0)
|
||||
{
|
||||
resize(cap);
|
||||
}
|
||||
|
||||
~LinearAllocator()
|
||||
{
|
||||
dtFree(buffer);
|
||||
}
|
||||
|
||||
void resize(const size_t cap)
|
||||
{
|
||||
if (buffer) dtFree(buffer);
|
||||
buffer = (unsigned char*)dtAlloc(cap, DT_ALLOC_PERM);
|
||||
capacity = cap;
|
||||
}
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
high = dtMax(high, top);
|
||||
top = 0;
|
||||
}
|
||||
|
||||
virtual void* alloc(const size_t size)
|
||||
{
|
||||
if (!buffer)
|
||||
return 0;
|
||||
if (top+size > capacity)
|
||||
return 0;
|
||||
unsigned char* mem = &buffer[top];
|
||||
top += size;
|
||||
return mem;
|
||||
}
|
||||
|
||||
virtual void free(void* /*ptr*/)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
};
|
||||
|
||||
struct FastLZCompressor : public dtTileCacheCompressor
|
||||
{
|
||||
virtual int maxCompressedSize(const int bufferSize)
|
||||
{
|
||||
return (int)(bufferSize* 1.05f);
|
||||
}
|
||||
|
||||
virtual dtStatus compress(const unsigned char* buffer, const int bufferSize,
|
||||
unsigned char* compressed, const int /*maxCompressedSize*/, int* compressedSize)
|
||||
{
|
||||
#if 0
|
||||
*compressedSize = fastlz_compress((const void *const)buffer, bufferSize, compressed);
|
||||
#endif
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
virtual dtStatus decompress(const unsigned char* compressed, const int compressedSize,
|
||||
unsigned char* buffer, const int maxBufferSize, int* bufferSize)
|
||||
{
|
||||
#if 0
|
||||
*bufferSize = fastlz_decompress(compressed, compressedSize, buffer, maxBufferSize);
|
||||
#endif
|
||||
return *bufferSize < 0 ? DT_FAILURE : DT_SUCCESS;
|
||||
}
|
||||
};
|
||||
|
||||
struct MeshProcess : public dtTileCacheMeshProcess
|
||||
{
|
||||
inline MeshProcess()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void process(struct dtNavMeshCreateParams* params,
|
||||
unsigned char* polyAreas, unsigned short* polyFlags)
|
||||
{
|
||||
#if 0
|
||||
// Update poly flags from areas.
|
||||
for (int i = 0; i < params->polyCount; ++i)
|
||||
{
|
||||
polyFlags[i] = sampleAreaToFlags(polyAreas[i]);
|
||||
}
|
||||
|
||||
// Pass in off-mesh connections.
|
||||
if (m_geom)
|
||||
{
|
||||
params->offMeshConVerts = m_geom->getOffMeshConnectionVerts();
|
||||
params->offMeshConRad = m_geom->getOffMeshConnectionRads();
|
||||
params->offMeshConDir = m_geom->getOffMeshConnectionDirs();
|
||||
params->offMeshConAreas = m_geom->getOffMeshConnectionAreas();
|
||||
params->offMeshConFlags = m_geom->getOffMeshConnectionFlags();
|
||||
params->offMeshConUserID = m_geom->getOffMeshConnectionId();
|
||||
params->offMeshConCount = m_geom->getOffMeshConnectionCount();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
void MapInstance::GenNavMesh()
|
||||
{
|
||||
static const float kCellHeight = 1;
|
||||
|
||||
static const float kAgentMaxSlope = 90;
|
||||
static const float kAgentHeight = 1;
|
||||
static const float kAgentMaxClimb = 1;
|
||||
static const float kAgentRadius = 40;
|
||||
|
||||
static const float kEdgeMaxLen = 6;
|
||||
static const float kEdgeMaxError = 6;
|
||||
|
||||
static const float kRegionMinSize = 6;
|
||||
static const float kRegionMergeSize = 6;
|
||||
|
||||
static const int kVertsPerPoly = 1;
|
||||
|
||||
static const int kTileSize = 48;
|
||||
|
||||
static const float kDetailSampleDist = 1;
|
||||
static const float kDetailSampleMaxError = 1;
|
||||
|
||||
static const int EXPECTED_LAYERS_PER_TILE = 4;
|
||||
|
||||
static const int MAX_LAYERS = 32;
|
||||
|
||||
struct TileCacheData
|
||||
{
|
||||
unsigned char* data;
|
||||
int dataSize;
|
||||
};
|
||||
|
||||
float kCellSize = 64;
|
||||
|
||||
// Init cache
|
||||
const float* bmin = nullptr;
|
||||
const float* bmax = nullptr;
|
||||
int gw = 0, gh = 0;
|
||||
rcCalcGridSize(bmin, bmax, kCellSize, &gw, &gh);
|
||||
const int ts = (int)kTileSize;
|
||||
const int tw = (gw + ts-1) / ts;
|
||||
const int th = (gh + ts-1) / ts;
|
||||
|
||||
rcConfig cfg;
|
||||
{
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.cs = kCellSize;
|
||||
cfg.ch = kCellHeight;
|
||||
cfg.walkableSlopeAngle = kAgentMaxSlope;
|
||||
cfg.walkableHeight = (int)ceilf(kAgentHeight / cfg.ch);
|
||||
cfg.walkableClimb = (int)floorf(kAgentMaxClimb / cfg.ch);
|
||||
cfg.walkableRadius = (int)ceilf(kAgentRadius / cfg.cs);
|
||||
cfg.maxEdgeLen = (int)(kEdgeMaxLen / kCellSize);
|
||||
cfg.maxSimplificationError = kEdgeMaxError;
|
||||
cfg.minRegionArea = (int)rcSqr(kRegionMinSize); // Note: area = size*size
|
||||
cfg.mergeRegionArea = (int)rcSqr(kRegionMergeSize); // Note: area = size*size
|
||||
cfg.maxVertsPerPoly = (int)kVertsPerPoly;
|
||||
cfg.tileSize = (int)kTileSize;
|
||||
cfg.borderSize = cfg.walkableRadius + 3; // Reserve enough padding.
|
||||
cfg.width = cfg.tileSize + cfg.borderSize*2;
|
||||
cfg.height = cfg.tileSize + cfg.borderSize*2;
|
||||
cfg.detailSampleDist = kDetailSampleDist < 0.9f ? 0 : kCellSize * kDetailSampleDist;
|
||||
cfg.detailSampleMaxError = kCellHeight * kDetailSampleMaxError;
|
||||
rcVcopy(cfg.bmin, bmin);
|
||||
rcVcopy(cfg.bmax, bmax);
|
||||
}
|
||||
|
||||
dtTileCacheParams tcparams;
|
||||
{
|
||||
// Tile cache params.
|
||||
memset(&tcparams, 0, sizeof(tcparams));
|
||||
rcVcopy(tcparams.orig, bmin);
|
||||
tcparams.cs = kCellSize;
|
||||
tcparams.ch = kCellHeight;
|
||||
tcparams.width = (int)kTileSize;
|
||||
tcparams.height = (int)kTileSize;
|
||||
tcparams.walkableHeight = kAgentHeight;
|
||||
tcparams.walkableRadius = kAgentRadius;
|
||||
tcparams.walkableClimb = kAgentMaxClimb;
|
||||
tcparams.maxSimplificationError = kEdgeMaxError;
|
||||
tcparams.maxTiles = tw*th*EXPECTED_LAYERS_PER_TILE;
|
||||
tcparams.maxObstacles = 128;
|
||||
}
|
||||
|
||||
dtStatus status;
|
||||
|
||||
dtTileCache* tile_cache = dtAllocTileCache();
|
||||
#if 0
|
||||
dtStatus status = tile_cache->init(&tcparams, m_talloc, m_tcomp, m_tmproc);;
|
||||
#endif
|
||||
dtNavMeshParams params;
|
||||
{
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
rcVcopy(params.orig, bmin);
|
||||
params.tileWidth = kTileSize * kCellSize;
|
||||
params.tileHeight = kTileSize * kCellSize;
|
||||
#if 0
|
||||
params.maxTiles = kMaxTiles;
|
||||
params.maxPolys = kMaxPolysPerTile;
|
||||
#endif
|
||||
}
|
||||
|
||||
navmesh_ = dtAllocNavMesh();
|
||||
|
||||
status = navmesh_->init(¶ms);
|
||||
if (dtStatusFailed(status)) {
|
||||
abort();
|
||||
}
|
||||
|
||||
int m_cacheLayerCount = 0;
|
||||
int m_cacheCompressedSize = 0;
|
||||
int m_cacheRawSize = 0;
|
||||
|
||||
for (int y = 0; y < th; ++y)
|
||||
{
|
||||
for (int x = 0; x < tw; ++x)
|
||||
{
|
||||
TileCacheData tiles[MAX_LAYERS];
|
||||
memset(tiles, 0, sizeof(tiles));
|
||||
#if 1
|
||||
int ntiles = 0;
|
||||
#else
|
||||
int ntiles = rasterizeTileLayers(x, y, cfg, tiles, MAX_LAYERS);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < ntiles; ++i)
|
||||
{
|
||||
TileCacheData* tile = &tiles[i];
|
||||
status = tile_cache->addTile(tile->data, tile->dataSize, DT_COMPRESSEDTILE_FREE_DATA, 0);
|
||||
if (dtStatusFailed(status))
|
||||
{
|
||||
dtFree(tile->data);
|
||||
tile->data = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_cacheLayerCount++;
|
||||
m_cacheCompressedSize += tile->dataSize;
|
||||
#if 0
|
||||
m_cacheRawSize += calcLayerBufferSize(tcparams.width, tcparams.height);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build initial meshes
|
||||
for (int y = 0; y < th; ++y)
|
||||
for (int x = 0; x < tw; ++x)
|
||||
tile_cache->buildNavMeshTilesAt(x,y, navmesh_);
|
||||
|
||||
#if 0
|
||||
m_cacheBuildTimeMs = m_ctx->getAccumulatedTime(RC_TIMER_TOTAL)/1000.0f;
|
||||
m_cacheBuildMemUsage = m_talloc->high;
|
||||
#endif
|
||||
|
||||
const dtNavMesh* nav = navmesh_;
|
||||
int navmeshMemUsage = 0;
|
||||
for (int i = 0; i < nav->getMaxTiles(); ++i)
|
||||
{
|
||||
const dtMeshTile* tile = nav->getTile(i);
|
||||
if (tile->header)
|
||||
navmeshMemUsage += tile->dataSize;
|
||||
}
|
||||
printf("navmeshMemUsage = %.1f kB", navmeshMemUsage/1024.0f);
|
||||
|
||||
map_service_->SetNavMesh(navmesh_);
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ namespace MetaData
|
||||
struct MapTplThing;
|
||||
}
|
||||
|
||||
class dtNavMesh;
|
||||
class Entity;
|
||||
class Obstacle;
|
||||
class Building;
|
||||
@ -32,8 +33,10 @@ class MapInstance
|
||||
Entity* GetEntityByUniId(int uniid);
|
||||
int AllocUniid();
|
||||
void OutputObjFile();
|
||||
void GenNavMesh();
|
||||
|
||||
private:
|
||||
dtNavMesh* navmesh_ = nullptr;
|
||||
int current_uniid_ = 0;
|
||||
std::map<int, Entity*> uniid_hash_;
|
||||
|
||||
|
@ -94,6 +94,7 @@ class MapService
|
||||
bool FindFailed(FindPathStatus* find_status);
|
||||
bool MoveDone(FindPathStatus* find_status);
|
||||
void DoMove(FindPathStatus* find_status);
|
||||
void SetNavMesh(dtNavMesh* navmesh) { navmesh_ = navmesh; };
|
||||
|
||||
private:
|
||||
int GetGridId(float world_x, float world_y);
|
||||
|
Loading…
x
Reference in New Issue
Block a user