commit
5095fbe28b
@ -717,7 +717,7 @@ dtPolyRef dtNavMesh::findNearestPolyInTile(const dtMeshTile* tile,
|
|||||||
float closestPtPoly[3];
|
float closestPtPoly[3];
|
||||||
float diff[3];
|
float diff[3];
|
||||||
bool posOverPoly = false;
|
bool posOverPoly = false;
|
||||||
float d = 0;
|
float d;
|
||||||
closestPointOnPoly(ref, center, closestPtPoly, &posOverPoly);
|
closestPointOnPoly(ref, center, closestPtPoly, &posOverPoly);
|
||||||
|
|
||||||
// If a point is directly over a polygon and closer than
|
// If a point is directly over a polygon and closer than
|
||||||
|
@ -308,7 +308,7 @@ dtStatus dtNavMeshQuery::findRandomPoint(const dtQueryFilter* filter, float (*fr
|
|||||||
return DT_SUCCESS;
|
return DT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
dtStatus dtNavMeshQuery::findRandomPointAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius,
|
dtStatus dtNavMeshQuery::findRandomPointAroundCircle(dtPolyRef startRef, const float* centerPos, const float maxRadius,
|
||||||
const dtQueryFilter* filter, float (*frand)(),
|
const dtQueryFilter* filter, float (*frand)(),
|
||||||
dtPolyRef* randomRef, float* randomPt) const
|
dtPolyRef* randomRef, float* randomPt) const
|
||||||
{
|
{
|
||||||
@ -340,7 +340,7 @@ dtStatus dtNavMeshQuery::findRandomPointAroundCircle(dtPolyRef startRef, const f
|
|||||||
|
|
||||||
dtStatus status = DT_SUCCESS;
|
dtStatus status = DT_SUCCESS;
|
||||||
|
|
||||||
const float radiusSqr = dtSqr(radius);
|
const float radiusSqr = dtSqr(maxRadius);
|
||||||
float areaSum = 0.0f;
|
float areaSum = 0.0f;
|
||||||
|
|
||||||
const dtMeshTile* randomTile = 0;
|
const dtMeshTile* randomTile = 0;
|
||||||
|
@ -40,7 +40,7 @@ class dtLocalBoundary
|
|||||||
dtPolyRef m_polys[MAX_LOCAL_POLYS];
|
dtPolyRef m_polys[MAX_LOCAL_POLYS];
|
||||||
int m_npolys;
|
int m_npolys;
|
||||||
|
|
||||||
void addSegment(const float dist, const float* seg);
|
void addSegment(const float dist, const float* s);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
dtLocalBoundary();
|
dtLocalBoundary();
|
||||||
|
@ -131,9 +131,6 @@ private:
|
|||||||
const float minPenalty,
|
const float minPenalty,
|
||||||
dtObstacleAvoidanceDebugData* debug);
|
dtObstacleAvoidanceDebugData* debug);
|
||||||
|
|
||||||
dtObstacleCircle* insertCircle(const float dist);
|
|
||||||
dtObstacleSegment* insertSegment(const float dist);
|
|
||||||
|
|
||||||
dtObstacleAvoidanceParams m_params;
|
dtObstacleAvoidanceParams m_params;
|
||||||
float m_invHorizTime;
|
float m_invHorizTime;
|
||||||
float m_vmax;
|
float m_vmax;
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
class dtProximityGrid
|
class dtProximityGrid
|
||||||
{
|
{
|
||||||
int m_maxItems;
|
|
||||||
float m_cellSize;
|
float m_cellSize;
|
||||||
float m_invCellSize;
|
float m_invCellSize;
|
||||||
|
|
||||||
@ -44,7 +43,7 @@ public:
|
|||||||
dtProximityGrid();
|
dtProximityGrid();
|
||||||
~dtProximityGrid();
|
~dtProximityGrid();
|
||||||
|
|
||||||
bool init(const int maxItems, const float cellSize);
|
bool init(const int poolSize, const float cellSize);
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ void dtObstacleAvoidanceQuery::prepare(const float* pos, const float* dvel)
|
|||||||
const float* pa = pos;
|
const float* pa = pos;
|
||||||
const float* pb = cir->p;
|
const float* pb = cir->p;
|
||||||
|
|
||||||
const float orig[3] = {0,0};
|
const float orig[3] = {0,0,0};
|
||||||
float dv[3];
|
float dv[3];
|
||||||
dtVsub(cir->dp,pb,pa);
|
dtVsub(cir->dp,pb,pa);
|
||||||
dtVnormalize(cir->dp);
|
dtVnormalize(cir->dp);
|
||||||
|
@ -47,7 +47,6 @@ inline int hashPos2(int x, int y, int n)
|
|||||||
|
|
||||||
|
|
||||||
dtProximityGrid::dtProximityGrid() :
|
dtProximityGrid::dtProximityGrid() :
|
||||||
m_maxItems(0),
|
|
||||||
m_cellSize(0),
|
m_cellSize(0),
|
||||||
m_pool(0),
|
m_pool(0),
|
||||||
m_poolHead(0),
|
m_poolHead(0),
|
||||||
|
@ -1068,6 +1068,7 @@ static bool buildMeshAdjacency(dtTileCacheAlloc* alloc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Last time I checked the if version got compiled using cmov, which was a lot faster than module (with idiv).
|
||||||
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
|
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
|
||||||
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
|
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ static void calcTriNormal(const float* v0, const float* v1, const float* v2, flo
|
|||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
///
|
///
|
||||||
/// Only sets the aread id's for the walkable triangles. Does not alter the
|
/// Only sets the area id's for the walkable triangles. Does not alter the
|
||||||
/// area id's for unwalkable triangles.
|
/// area id's for unwalkable triangles.
|
||||||
///
|
///
|
||||||
/// See the #rcConfig documentation for more information on the configuration parameters.
|
/// See the #rcConfig documentation for more information on the configuration parameters.
|
||||||
@ -267,7 +267,7 @@ void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle,
|
|||||||
|
|
||||||
/// @par
|
/// @par
|
||||||
///
|
///
|
||||||
/// Only sets the aread id's for the unwalkable triangles. Does not alter the
|
/// Only sets the area id's for the unwalkable triangles. Does not alter the
|
||||||
/// area id's for walkable triangles.
|
/// area id's for walkable triangles.
|
||||||
///
|
///
|
||||||
/// See the #rcConfig documentation for more information on the configuration parameters.
|
/// See the #rcConfig documentation for more information on the configuration parameters.
|
||||||
@ -318,7 +318,7 @@ int rcGetHeightFieldSpanCount(rcContext* ctx, rcHeightfield& hf)
|
|||||||
/// @par
|
/// @par
|
||||||
///
|
///
|
||||||
/// This is just the beginning of the process of fully building a compact heightfield.
|
/// This is just the beginning of the process of fully building a compact heightfield.
|
||||||
/// Various filters may be applied applied, then the distance field and regions built.
|
/// Various filters may be applied, then the distance field and regions built.
|
||||||
/// E.g: #rcBuildDistanceField and #rcBuildRegions
|
/// E.g: #rcBuildDistanceField and #rcBuildRegions
|
||||||
///
|
///
|
||||||
/// See the #rcConfig documentation for more information on the configuration parameters.
|
/// See the #rcConfig documentation for more information on the configuration parameters.
|
||||||
|
@ -464,7 +464,7 @@ static int calcAreaOfPolygon2D(const int* verts, const int nverts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: these are the same as in RecastMesh.cpp, consider using the same.
|
// TODO: these are the same as in RecastMesh.cpp, consider using the same.
|
||||||
|
// Last time I checked the if version got compiled using cmov, which was a lot faster than module (with idiv).
|
||||||
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
|
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
|
||||||
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
|
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
|
||||||
|
|
||||||
|
@ -160,6 +160,7 @@ static unsigned short addVertex(unsigned short x, unsigned short y, unsigned sho
|
|||||||
return (unsigned short)i;
|
return (unsigned short)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Last time I checked the if version got compiled using cmov, which was a lot faster than module (with idiv).
|
||||||
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
|
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
|
||||||
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
|
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
|
||||||
|
|
||||||
|
@ -237,8 +237,8 @@ static unsigned short getHeight(const float fx, const float fy, const float fz,
|
|||||||
|
|
||||||
enum EdgeValues
|
enum EdgeValues
|
||||||
{
|
{
|
||||||
UNDEF = -1,
|
EV_UNDEF = -1,
|
||||||
HULL = -2,
|
EV_HULL = -2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int findEdge(const int* edges, int nedges, int s, int t)
|
static int findEdge(const int* edges, int nedges, int s, int t)
|
||||||
@ -249,7 +249,7 @@ static int findEdge(const int* edges, int nedges, int s, int t)
|
|||||||
if ((e[0] == s && e[1] == t) || (e[0] == t && e[1] == s))
|
if ((e[0] == s && e[1] == t) || (e[0] == t && e[1] == s))
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return UNDEF;
|
return EV_UNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int addEdge(rcContext* ctx, int* edges, int& nedges, const int maxEdges, int s, int t, int l, int r)
|
static int addEdge(rcContext* ctx, int* edges, int& nedges, const int maxEdges, int s, int t, int l, int r)
|
||||||
@ -257,12 +257,12 @@ static int addEdge(rcContext* ctx, int* edges, int& nedges, const int maxEdges,
|
|||||||
if (nedges >= maxEdges)
|
if (nedges >= maxEdges)
|
||||||
{
|
{
|
||||||
ctx->log(RC_LOG_ERROR, "addEdge: Too many edges (%d/%d).", nedges, maxEdges);
|
ctx->log(RC_LOG_ERROR, "addEdge: Too many edges (%d/%d).", nedges, maxEdges);
|
||||||
return UNDEF;
|
return EV_UNDEF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add edge if not already in the triangulation.
|
// Add edge if not already in the triangulation.
|
||||||
int e = findEdge(edges, nedges, s, t);
|
int e = findEdge(edges, nedges, s, t);
|
||||||
if (e == UNDEF)
|
if (e == EV_UNDEF)
|
||||||
{
|
{
|
||||||
int* edge = &edges[nedges*4];
|
int* edge = &edges[nedges*4];
|
||||||
edge[0] = s;
|
edge[0] = s;
|
||||||
@ -273,15 +273,15 @@ static int addEdge(rcContext* ctx, int* edges, int& nedges, const int maxEdges,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return UNDEF;
|
return EV_UNDEF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void updateLeftFace(int* e, int s, int t, int f)
|
static void updateLeftFace(int* e, int s, int t, int f)
|
||||||
{
|
{
|
||||||
if (e[0] == s && e[1] == t && e[2] == UNDEF)
|
if (e[0] == s && e[1] == t && e[2] == EV_UNDEF)
|
||||||
e[2] = f;
|
e[2] = f;
|
||||||
else if (e[1] == s && e[0] == t && e[3] == UNDEF)
|
else if (e[1] == s && e[0] == t && e[3] == EV_UNDEF)
|
||||||
e[3] = f;
|
e[3] = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,12 +322,12 @@ static void completeFacet(rcContext* ctx, const float* pts, int npts, int* edges
|
|||||||
|
|
||||||
// Cache s and t.
|
// Cache s and t.
|
||||||
int s,t;
|
int s,t;
|
||||||
if (edge[2] == UNDEF)
|
if (edge[2] == EV_UNDEF)
|
||||||
{
|
{
|
||||||
s = edge[0];
|
s = edge[0];
|
||||||
t = edge[1];
|
t = edge[1];
|
||||||
}
|
}
|
||||||
else if (edge[3] == UNDEF)
|
else if (edge[3] == EV_UNDEF)
|
||||||
{
|
{
|
||||||
s = edge[1];
|
s = edge[1];
|
||||||
t = edge[0];
|
t = edge[0];
|
||||||
@ -390,15 +390,15 @@ static void completeFacet(rcContext* ctx, const float* pts, int npts, int* edges
|
|||||||
|
|
||||||
// Add new edge or update face info of old edge.
|
// Add new edge or update face info of old edge.
|
||||||
e = findEdge(edges, nedges, pt, s);
|
e = findEdge(edges, nedges, pt, s);
|
||||||
if (e == UNDEF)
|
if (e == EV_UNDEF)
|
||||||
addEdge(ctx, edges, nedges, maxEdges, pt, s, nfaces, UNDEF);
|
addEdge(ctx, edges, nedges, maxEdges, pt, s, nfaces, EV_UNDEF);
|
||||||
else
|
else
|
||||||
updateLeftFace(&edges[e*4], pt, s, nfaces);
|
updateLeftFace(&edges[e*4], pt, s, nfaces);
|
||||||
|
|
||||||
// Add new edge or update face info of old edge.
|
// Add new edge or update face info of old edge.
|
||||||
e = findEdge(edges, nedges, t, pt);
|
e = findEdge(edges, nedges, t, pt);
|
||||||
if (e == UNDEF)
|
if (e == EV_UNDEF)
|
||||||
addEdge(ctx, edges, nedges, maxEdges, t, pt, nfaces, UNDEF);
|
addEdge(ctx, edges, nedges, maxEdges, t, pt, nfaces, EV_UNDEF);
|
||||||
else
|
else
|
||||||
updateLeftFace(&edges[e*4], t, pt, nfaces);
|
updateLeftFace(&edges[e*4], t, pt, nfaces);
|
||||||
|
|
||||||
@ -406,7 +406,7 @@ static void completeFacet(rcContext* ctx, const float* pts, int npts, int* edges
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updateLeftFace(&edges[e*4], s, t, HULL);
|
updateLeftFace(&edges[e*4], s, t, EV_HULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -420,14 +420,14 @@ static void delaunayHull(rcContext* ctx, const int npts, const float* pts,
|
|||||||
edges.resize(maxEdges*4);
|
edges.resize(maxEdges*4);
|
||||||
|
|
||||||
for (int i = 0, j = nhull-1; i < nhull; j=i++)
|
for (int i = 0, j = nhull-1; i < nhull; j=i++)
|
||||||
addEdge(ctx, &edges[0], nedges, maxEdges, hull[j],hull[i], HULL, UNDEF);
|
addEdge(ctx, &edges[0], nedges, maxEdges, hull[j],hull[i], EV_HULL, EV_UNDEF);
|
||||||
|
|
||||||
int currentEdge = 0;
|
int currentEdge = 0;
|
||||||
while (currentEdge < nedges)
|
while (currentEdge < nedges)
|
||||||
{
|
{
|
||||||
if (edges[currentEdge*4+2] == UNDEF)
|
if (edges[currentEdge*4+2] == EV_UNDEF)
|
||||||
completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge);
|
completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge);
|
||||||
if (edges[currentEdge*4+3] == UNDEF)
|
if (edges[currentEdge*4+3] == EV_UNDEF)
|
||||||
completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge);
|
completeFacet(ctx, pts, npts, &edges[0], nedges, maxEdges, nfaces, currentEdge);
|
||||||
currentEdge++;
|
currentEdge++;
|
||||||
}
|
}
|
||||||
@ -507,15 +507,9 @@ static float polyMinExtent(const float* verts, const int nverts)
|
|||||||
return rcSqrt(minDist);
|
return rcSqrt(minDist);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int next(int i, int n)
|
// Last time I checked the if version got compiled using cmov, which was a lot faster than module (with idiv).
|
||||||
{
|
inline int prev(int i, int n) { return i-1 >= 0 ? i-1 : n-1; }
|
||||||
return (i+1) % n;
|
inline int next(int i, int n) { return i+1 < n ? i+1 : 0; }
|
||||||
}
|
|
||||||
|
|
||||||
inline int prev(int i, int n)
|
|
||||||
{
|
|
||||||
return (i + n-1) % n;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void triangulateHull(const int nverts, const float* verts, const int nhull, const int* hull, rcIntArray& tris)
|
static void triangulateHull(const int nverts, const float* verts, const int nhull, const int* hull, rcIntArray& tris)
|
||||||
{
|
{
|
||||||
|
@ -50,7 +50,7 @@ static rcSpan* allocSpan(rcHeightfield& hf)
|
|||||||
// Allocate memory for the new pool.
|
// Allocate memory for the new pool.
|
||||||
rcSpanPool* pool = (rcSpanPool*)rcAlloc(sizeof(rcSpanPool), RC_ALLOC_PERM);
|
rcSpanPool* pool = (rcSpanPool*)rcAlloc(sizeof(rcSpanPool), RC_ALLOC_PERM);
|
||||||
if (!pool) return 0;
|
if (!pool) return 0;
|
||||||
pool->next = 0;
|
|
||||||
// Add the pool into the list of pools.
|
// Add the pool into the list of pools.
|
||||||
pool->next = hf.pools;
|
pool->next = hf.pools;
|
||||||
hf.pools = pool;
|
hf.pools = pool;
|
||||||
|
@ -82,6 +82,9 @@ public:
|
|||||||
void addTempObstacle(const float* pos);
|
void addTempObstacle(const float* pos);
|
||||||
void removeTempObstacle(const float* sp, const float* sq);
|
void removeTempObstacle(const float* sp, const float* sq);
|
||||||
void clearAllTempObstacles();
|
void clearAllTempObstacles();
|
||||||
|
|
||||||
|
void saveAll(const char* path);
|
||||||
|
void loadAll(const char* path);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1143,7 +1143,7 @@ void NavMeshTesterTool::handleRender()
|
|||||||
dd.begin(DU_DRAW_LINES, 2.0f);
|
dd.begin(DU_DRAW_LINES, 2.0f);
|
||||||
for (int i = 0; i < m_nstraightPath-1; ++i)
|
for (int i = 0; i < m_nstraightPath-1; ++i)
|
||||||
{
|
{
|
||||||
unsigned int col = 0;
|
unsigned int col;
|
||||||
if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)
|
if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)
|
||||||
col = offMeshCol;
|
col = offMeshCol;
|
||||||
else
|
else
|
||||||
@ -1156,10 +1156,10 @@ void NavMeshTesterTool::handleRender()
|
|||||||
dd.begin(DU_DRAW_POINTS, 6.0f);
|
dd.begin(DU_DRAW_POINTS, 6.0f);
|
||||||
for (int i = 0; i < m_nstraightPath; ++i)
|
for (int i = 0; i < m_nstraightPath; ++i)
|
||||||
{
|
{
|
||||||
unsigned int col = 0;
|
unsigned int col;
|
||||||
if (m_straightPathFlags[i] & DT_STRAIGHTPATH_START)
|
if (m_straightPathFlags[i] & DT_STRAIGHTPATH_START)
|
||||||
col = startCol;
|
col = startCol;
|
||||||
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_START)
|
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_END)
|
||||||
col = endCol;
|
col = endCol;
|
||||||
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)
|
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)
|
||||||
col = offMeshCol;
|
col = offMeshCol;
|
||||||
|
@ -912,6 +912,27 @@ void Sample_TempObstacles::handleSettings()
|
|||||||
imguiValue(msg);
|
imguiValue(msg);
|
||||||
|
|
||||||
imguiSeparator();
|
imguiSeparator();
|
||||||
|
|
||||||
|
imguiIndent();
|
||||||
|
imguiIndent();
|
||||||
|
|
||||||
|
if (imguiButton("Save"))
|
||||||
|
{
|
||||||
|
saveAll("all_tiles_tilecache.bin");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imguiButton("Load"))
|
||||||
|
{
|
||||||
|
dtFreeNavMesh(m_navMesh);
|
||||||
|
dtFreeTileCache(m_tileCache);
|
||||||
|
loadAll("all_tiles_tilecache.bin");
|
||||||
|
m_navQuery->init(m_navMesh, 2048);
|
||||||
|
}
|
||||||
|
|
||||||
|
imguiUnindent();
|
||||||
|
imguiUnindent();
|
||||||
|
|
||||||
|
imguiSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sample_TempObstacles::handleTools()
|
void Sample_TempObstacles::handleTools()
|
||||||
@ -1361,3 +1382,129 @@ void Sample_TempObstacles::getTilePos(const float* pos, int& tx, int& ty)
|
|||||||
tx = (int)((pos[0] - bmin[0]) / ts);
|
tx = (int)((pos[0] - bmin[0]) / ts);
|
||||||
ty = (int)((pos[2] - bmin[2]) / ts);
|
ty = (int)((pos[2] - bmin[2]) / ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const int TILECACHESET_MAGIC = 'T'<<24 | 'S'<<16 | 'E'<<8 | 'T'; //'TSET';
|
||||||
|
static const int TILECACHESET_VERSION = 1;
|
||||||
|
|
||||||
|
struct TileCacheSetHeader
|
||||||
|
{
|
||||||
|
int magic;
|
||||||
|
int version;
|
||||||
|
int numTiles;
|
||||||
|
dtNavMeshParams meshParams;
|
||||||
|
dtTileCacheParams cacheParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TileCacheTileHeader
|
||||||
|
{
|
||||||
|
dtCompressedTileRef tileRef;
|
||||||
|
int dataSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Sample_TempObstacles::saveAll(const char* path)
|
||||||
|
{
|
||||||
|
if (!m_tileCache) return;
|
||||||
|
|
||||||
|
FILE* fp = fopen(path, "wb");
|
||||||
|
if (!fp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Store header.
|
||||||
|
TileCacheSetHeader header;
|
||||||
|
header.magic = TILECACHESET_MAGIC;
|
||||||
|
header.version = TILECACHESET_VERSION;
|
||||||
|
header.numTiles = 0;
|
||||||
|
for (int i = 0; i < m_tileCache->getTileCount(); ++i)
|
||||||
|
{
|
||||||
|
const dtCompressedTile* tile = m_tileCache->getTile(i);
|
||||||
|
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||||
|
header.numTiles++;
|
||||||
|
}
|
||||||
|
memcpy(&header.cacheParams, m_tileCache->getParams(), sizeof(dtTileCacheParams));
|
||||||
|
memcpy(&header.meshParams, m_navMesh->getParams(), sizeof(dtNavMeshParams));
|
||||||
|
fwrite(&header, sizeof(TileCacheSetHeader), 1, fp);
|
||||||
|
|
||||||
|
// Store tiles.
|
||||||
|
for (int i = 0; i < m_tileCache->getTileCount(); ++i)
|
||||||
|
{
|
||||||
|
const dtCompressedTile* tile = m_tileCache->getTile(i);
|
||||||
|
if (!tile || !tile->header || !tile->dataSize) continue;
|
||||||
|
|
||||||
|
TileCacheTileHeader tileHeader;
|
||||||
|
tileHeader.tileRef = m_tileCache->getTileRef(tile);
|
||||||
|
tileHeader.dataSize = tile->dataSize;
|
||||||
|
fwrite(&tileHeader, sizeof(tileHeader), 1, fp);
|
||||||
|
|
||||||
|
fwrite(tile->data, tile->dataSize, 1, fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sample_TempObstacles::loadAll(const char* path)
|
||||||
|
{
|
||||||
|
FILE* fp = fopen(path, "rb");
|
||||||
|
if (!fp) return;
|
||||||
|
|
||||||
|
// Read header.
|
||||||
|
TileCacheSetHeader header;
|
||||||
|
fread(&header, sizeof(TileCacheSetHeader), 1, fp);
|
||||||
|
if (header.magic != TILECACHESET_MAGIC)
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (header.version != TILECACHESET_VERSION)
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_navMesh = dtAllocNavMesh();
|
||||||
|
if (!m_navMesh)
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dtStatus status = m_navMesh->init(&header.meshParams);
|
||||||
|
if (dtStatusFailed(status))
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_tileCache = dtAllocTileCache();
|
||||||
|
if (!m_tileCache)
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
status = m_tileCache->init(&header.cacheParams, m_talloc, m_tcomp, m_tmproc);
|
||||||
|
if (dtStatusFailed(status))
|
||||||
|
{
|
||||||
|
fclose(fp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read tiles.
|
||||||
|
for (int i = 0; i < header.numTiles; ++i)
|
||||||
|
{
|
||||||
|
TileCacheTileHeader tileHeader;
|
||||||
|
fread(&tileHeader, sizeof(tileHeader), 1, fp);
|
||||||
|
if (!tileHeader.tileRef || !tileHeader.dataSize)
|
||||||
|
break;
|
||||||
|
|
||||||
|
unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM);
|
||||||
|
if (!data) break;
|
||||||
|
memset(data, 0, tileHeader.dataSize);
|
||||||
|
fread(data, tileHeader.dataSize, 1, fp);
|
||||||
|
|
||||||
|
dtCompressedTileRef tile = 0;
|
||||||
|
m_tileCache->addTile(data, tileHeader.dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tile);
|
||||||
|
|
||||||
|
if (tile)
|
||||||
|
m_tileCache->buildNavMeshTile(tile, m_navMesh);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user