Added ugly, but functional version of TiledNavMesh and a builder for the same.
Fixed a cost bug in the dtStatNavMesh::findPolysAround. Added debug draw functions for tiled navmesh.
This commit is contained in:
parent
9edeccea35
commit
4787a8d223
@ -20,9 +20,13 @@
|
||||
#define DETOURDEBUGDRAW_H
|
||||
|
||||
#include "DetourStatNavMesh.h"
|
||||
#include "DetourTiledNavMesh.h"
|
||||
|
||||
void dtDebugDrawStatNavMeshPoly(const dtStatNavMesh* mesh, dtPolyRef ref, const float* col);
|
||||
void dtDebugDrawStatNavMeshBVTree(const dtStatNavMesh* mesh);
|
||||
void dtDebugDrawStatNavMesh(const dtStatNavMesh* mesh);
|
||||
|
||||
void dtDebugDrawTiledNavMesh(const dtTiledNavMesh* mesh);
|
||||
void dtDebugDrawTiledNavMeshPoly(const dtTiledNavMesh* mesh, dtTilePolyRef ref, const float* col);
|
||||
|
||||
#endif // DETOURDEBUGDRAW_H
|
@ -84,7 +84,7 @@ public:
|
||||
// maxPolys - (in) The max number of polygons the polys array can hold.
|
||||
// Returns: Number of polygons in search result array.
|
||||
int queryPolygons(const float* center, const float* extents,
|
||||
unsigned short* polys, const int maxPolys);
|
||||
dtPolyRef* polys, const int maxPolys);
|
||||
|
||||
// Finds path from start polygon to end polygon.
|
||||
// If target polygon canno be reached through the navigation graph,
|
||||
@ -184,8 +184,6 @@ private:
|
||||
float getCost(dtPolyRef prev, dtPolyRef from, dtPolyRef to) const;
|
||||
float getHeuristic(dtPolyRef from, dtPolyRef to) const;
|
||||
|
||||
bool getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const;
|
||||
|
||||
// Copies the locations of vertices of a polygon to an array.
|
||||
int getPolyVerts(dtPolyRef ref, float* verts) const;
|
||||
// Returns portal points between two polygons.
|
||||
|
209
Detour/Include/DetourTiledNavMesh.h
Normal file
209
Detour/Include/DetourTiledNavMesh.h
Normal file
@ -0,0 +1,209 @@
|
||||
//
|
||||
// Copyright (c) 2009 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURTILEDNAVMESH_H
|
||||
#define DETOURTILEDNAVMESH_H
|
||||
|
||||
// Reference to navigation polygon.
|
||||
typedef unsigned int dtTilePolyRef;
|
||||
|
||||
static const int DT_TILE_REF_SALT_BITS = 12;
|
||||
static const int DT_TILE_REF_SALT_MASK = (1<<DT_TILE_REF_SALT_BITS)-1;
|
||||
static const int DT_TILE_REF_TILE_BITS = 12;
|
||||
static const int DT_TILE_REF_TILE_MASK = (1<<DT_TILE_REF_TILE_BITS)-1;
|
||||
static const int DT_TILE_REF_POLY_BITS = 8;
|
||||
static const int DT_TILE_REF_POLY_MASK = (1<<DT_TILE_REF_POLY_BITS)-1;
|
||||
|
||||
// Maximum number of vertices per navigation polygon.
|
||||
static const int DT_TILE_VERTS_PER_POLYGON = 6;
|
||||
|
||||
static const int DT_MAX_TILES = 1 << DT_TILE_REF_TILE_BITS;
|
||||
static const int DT_MAX_POLYGONS = 1 << DT_TILE_REF_POLY_BITS;
|
||||
|
||||
// Structure holding the navigation polygon data.
|
||||
struct dtTilePoly
|
||||
{
|
||||
unsigned short v[DT_TILE_VERTS_PER_POLYGON]; // Indices to vertices of the poly.
|
||||
unsigned short n[DT_TILE_VERTS_PER_POLYGON]; // Refs to neighbours of the poly.
|
||||
unsigned short links;
|
||||
unsigned char nlinks;
|
||||
unsigned char nv; // Number of vertices.
|
||||
unsigned char flags; // Flags (not used).
|
||||
};
|
||||
|
||||
struct dtTileLink
|
||||
{
|
||||
dtTilePolyRef ref;
|
||||
unsigned short p;
|
||||
unsigned char e;
|
||||
unsigned char side;
|
||||
float bmin, bmax;
|
||||
};
|
||||
|
||||
static const int DT_TILE_NAVMESH_MAGIC = 'NAVT';
|
||||
static const int DT_TILE_NAVMESH_VERSION = 1;
|
||||
|
||||
struct dtTileHeader
|
||||
{
|
||||
int magic;
|
||||
int version;
|
||||
int npolys;
|
||||
int nverts;
|
||||
int nportals[4];
|
||||
int nlinks;
|
||||
int maxlinks;
|
||||
float cs;
|
||||
float bmin[3], bmax[3];
|
||||
dtTilePoly* polys;
|
||||
float* verts;
|
||||
dtTileLink* links;
|
||||
struct dtTile* nei[4];
|
||||
};
|
||||
|
||||
struct dtTile
|
||||
{
|
||||
int salt;
|
||||
int x,y;
|
||||
dtTileHeader* header;
|
||||
dtTile* next;
|
||||
};
|
||||
|
||||
inline dtTilePolyRef encodeId(unsigned int salt, unsigned int it, unsigned int ip)
|
||||
{
|
||||
return (salt << (DT_TILE_REF_POLY_BITS+DT_TILE_REF_TILE_BITS)) | ((it+1) << DT_TILE_REF_POLY_BITS) | ip;
|
||||
}
|
||||
|
||||
inline void decodeId(dtTilePolyRef ref, unsigned int& salt, unsigned int& it, unsigned int& ip)
|
||||
{
|
||||
salt = (ref >> (DT_TILE_REF_POLY_BITS+DT_TILE_REF_TILE_BITS)) & DT_TILE_REF_SALT_MASK;
|
||||
it = ((ref >> DT_TILE_REF_POLY_BITS) & DT_TILE_REF_TILE_MASK) - 1;
|
||||
ip = ref & DT_TILE_REF_POLY_MASK;
|
||||
}
|
||||
|
||||
static const int DT_TILE_LOOKUP_SIZE = DT_MAX_TILES/4;
|
||||
|
||||
class dtTiledNavMesh
|
||||
{
|
||||
public:
|
||||
dtTiledNavMesh();
|
||||
~dtTiledNavMesh();
|
||||
|
||||
bool init(const float* orig, float tileSize, float portalHeight);
|
||||
bool addTile(int x, int y, unsigned char* data, int dataSize);
|
||||
bool removeTile(int x, int y);
|
||||
dtTile* getTile(int x, int y);
|
||||
const dtTile* getTile(int i) const { return &m_tiles[i]; }
|
||||
|
||||
// Finds the nearest navigation polygon around the center location.
|
||||
// Params:
|
||||
// center - (in) The center of the search box.
|
||||
// extents - (in) The extents of the search box.
|
||||
// Returns: Reference identifier for the polygon, or 0 if no polygons found.
|
||||
dtTilePolyRef findNearestPoly(const float* center, const float* extents);
|
||||
|
||||
// Returns polygons which touch the query box.
|
||||
// Params:
|
||||
// center - (in) the center of the search box.
|
||||
// extents - (in) the extents of the search box.
|
||||
// polys - (out) array holding the search result.
|
||||
// maxPolys - (in) The max number of polygons the polys array can hold.
|
||||
// Returns: Number of polygons in search result array.
|
||||
int queryPolygons(const float* center, const float* extents,
|
||||
dtTilePolyRef* polys, const int maxPolys);
|
||||
|
||||
bool closestPointToPoly(dtTilePolyRef ref, const float* pos, float* closest) const;
|
||||
|
||||
int getPolyNeighbours(dtTilePolyRef ref, dtTilePolyRef* nei, int maxNei) const;
|
||||
|
||||
int findPath(dtTilePolyRef startRef, dtTilePolyRef endRef,
|
||||
dtTilePolyRef* path, const int maxPathSize);
|
||||
|
||||
int findStraightPath(const float* startPos, const float* endPos,
|
||||
const dtTilePolyRef* path, const int pathSize,
|
||||
float* straightPath, const int maxStraightPathSize);
|
||||
|
||||
int raycast(dtTilePolyRef startRef, const float* startPos, const float* endPos,
|
||||
float& t, dtTilePolyRef* path, const int pathSize);
|
||||
|
||||
int findPolysAround(dtTilePolyRef centerRef, const float* centerPos, float radius,
|
||||
dtTilePolyRef* resultRef, dtTilePolyRef* resultParent,
|
||||
float* resultCost, unsigned short* resultDepth,
|
||||
const int maxResult);
|
||||
|
||||
float findDistanceToWall(dtTilePolyRef centerRef, const float* centerPos, float maxRadius,
|
||||
float* hitPos, float* hitNormal);
|
||||
|
||||
inline const dtTilePoly* getPolyByRef(dtTilePolyRef ref) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
decodeId(ref, salt, it, ip);
|
||||
if (it >= DT_MAX_TILES) return 0;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0;
|
||||
if (ip >= m_tiles[it].header->npolys) return 0;
|
||||
return &m_tiles[it].header->polys[ip];
|
||||
}
|
||||
|
||||
inline const float* getPolyVertsByRef(dtTilePolyRef ref) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
decodeId(ref, salt, it, ip);
|
||||
if (it >= DT_MAX_TILES) return 0;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0;
|
||||
if (ip >= m_tiles[it].header->npolys) return 0;
|
||||
return m_tiles[it].header->verts;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
dtTilePolyRef getTileId(dtTile* tile);
|
||||
dtTile* getNeighbourTile(int x, int y, int side);
|
||||
|
||||
void buildIntLinks(dtTile* tile);
|
||||
void buildExtLinks(dtTile* tile, dtTile* target, int side);
|
||||
void removeExtLinks(dtTile* tile, int side);
|
||||
|
||||
void createConnections(dtTile* tilea, dtTile* tileb, int sidea);
|
||||
void removeConnections(dtTile* tile, int side);
|
||||
int queryTilePolygons(dtTile* tile, const float* qmin, const float* qmax,
|
||||
dtTilePolyRef* polys, const int maxPolys);
|
||||
int findConnectingPolys(const float* va, const float* vb,
|
||||
dtTile* tile, int side,
|
||||
dtTilePolyRef* con, float* conarea, int maxcon);
|
||||
|
||||
float getCost(dtTilePolyRef prev, dtTilePolyRef from, dtTilePolyRef to) const;
|
||||
float getHeuristic(dtTilePolyRef from, dtTilePolyRef to) const;
|
||||
|
||||
// Returns portal points between two polygons.
|
||||
bool getPortalPoints(dtTilePolyRef from, dtTilePolyRef to, float* left, float* right) const;
|
||||
|
||||
float m_orig[3];
|
||||
float m_tileSize;
|
||||
float m_portalHeight;
|
||||
|
||||
dtTile* m_posLookup[DT_TILE_LOOKUP_SIZE];
|
||||
dtTile* m_nextFree;
|
||||
dtTile m_tiles[DT_MAX_TILES];
|
||||
|
||||
dtTileLink* m_tmpLinks;
|
||||
int m_ntmpLinks;
|
||||
|
||||
class dtTileNodePool* m_nodePool;
|
||||
class dtTileNodeQueue* m_openList;
|
||||
};
|
||||
|
||||
#endif // DETOURTILEDNAVMESH_H
|
9
Detour/Include/DetourTiledNavMeshBuilder.h
Normal file
9
Detour/Include/DetourTiledNavMeshBuilder.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef DETOURTILEDNAVMESHBUILDER_H
|
||||
#define DETOURTILEDNAVMESHBUILDER_H
|
||||
|
||||
bool dtCreateNavMeshTileData(const unsigned short* verts, const int nverts,
|
||||
const unsigned short* polys, const int npolys, const int nvp,
|
||||
const float* bmin, const float* bmax, float cs, float ch, int tileSize, int walkableClimb,
|
||||
unsigned char** outData, int* outDataSize);
|
||||
|
||||
#endif // DETOURTILEDNAVMESHBUILDER_H
|
@ -186,3 +186,244 @@ void dtDebugDrawStatNavMesh(const dtStatNavMesh* mesh)
|
||||
glEnd();
|
||||
glPointSize(1.0f);
|
||||
}
|
||||
|
||||
|
||||
static void drawTile(const dtTileHeader* header)
|
||||
{
|
||||
const float col[4] = {0,0,0,0.25f};
|
||||
glBegin(GL_LINES);
|
||||
drawBoxWire(header->bmin[0],header->bmin[1],header->bmin[2],
|
||||
header->bmax[0],header->bmax[1],header->bmax[2], col);
|
||||
glEnd();
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
for (int i = 0; i < header->npolys; ++i)
|
||||
{
|
||||
const dtTilePoly* p = &header->polys[i];
|
||||
|
||||
glColor4ub(0,196,255,64);
|
||||
|
||||
unsigned short vi[3];
|
||||
for (int j = 2; j < (int)p->nv; ++j)
|
||||
{
|
||||
vi[0] = p->v[0];
|
||||
vi[1] = p->v[j-1];
|
||||
vi[2] = p->v[j];
|
||||
for (int k = 0; k < 3; ++k)
|
||||
{
|
||||
const float* v = &header->verts[vi[k]*3];
|
||||
glVertex3f(v[0], v[1]+0.2f, v[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// Draw tri boundaries
|
||||
glLineWidth(1.5f);
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < header->npolys; ++i)
|
||||
{
|
||||
const dtTilePoly* p = &header->polys[i];
|
||||
for (int j = 0, nj = (int)p->nv; j < nj; ++j)
|
||||
{
|
||||
if (p->n[j] == 0) continue;
|
||||
if (p->n[j] & 0x8000)
|
||||
{
|
||||
bool con = false;
|
||||
for (int k = 0; k < p->nlinks; ++k)
|
||||
{
|
||||
if (header->links[p->links+k].e == j)
|
||||
{
|
||||
con = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (con)
|
||||
glColor4ub(255,255,255,128);
|
||||
else
|
||||
glColor4ub(0,0,0,128);
|
||||
}
|
||||
else
|
||||
glColor4ub(0,48,64,32);
|
||||
/*
|
||||
{
|
||||
// Portal
|
||||
int side = (p->n[j] >> 13) & 3;
|
||||
int i = p->n[j] & 0x1fff;
|
||||
if (!header->portals[side][i].ncon) continue;
|
||||
}*/
|
||||
|
||||
int vi[2];
|
||||
vi[0] = p->v[j];
|
||||
vi[1] = p->v[(j+1) % nj];
|
||||
for (int k = 0; k < 2; ++k)
|
||||
{
|
||||
const float* v = &header->verts[vi[k]*3];
|
||||
glVertex3f(v[0], v[1]+0.21f, v[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
// Draw boundaries
|
||||
glLineWidth(2.5f);
|
||||
glColor4ub(0,48,64,220);
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < header->npolys; ++i)
|
||||
{
|
||||
const dtTilePoly* p = &header->polys[i];
|
||||
for (int j = 0, nj = (int)p->nv; j < nj; ++j)
|
||||
{
|
||||
if (p->n[j] != 0)
|
||||
{
|
||||
/* if (p->n[j] & 0x8000)
|
||||
{
|
||||
// Portal
|
||||
int side = (p->n[j] >> 13) & 3;
|
||||
int i = p->n[j] & 0x1fff;
|
||||
if (header->portals[side][i].ncon) continue;
|
||||
}
|
||||
else*/
|
||||
continue;
|
||||
}
|
||||
int vi[2];
|
||||
vi[0] = p->v[j];
|
||||
vi[1] = p->v[(j+1) % nj];
|
||||
for (int k = 0; k < 2; ++k)
|
||||
{
|
||||
const float* v = &header->verts[vi[k]*3];
|
||||
glVertex3f(v[0], v[1]+0.21f, v[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
glLineWidth(1.0f);
|
||||
|
||||
glPointSize(3.0f);
|
||||
glColor4ub(0,0,0,196);
|
||||
glBegin(GL_POINTS);
|
||||
for (int i = 0; i < header->nverts; ++i)
|
||||
{
|
||||
const float* v = &header->verts[i*3];
|
||||
glVertex3f(v[0], v[1]+0.21f, v[2]);
|
||||
}
|
||||
glEnd();
|
||||
glPointSize(1.0f);
|
||||
|
||||
// Draw portals
|
||||
/* glBegin(GL_LINES);
|
||||
|
||||
for (int i = 0; i < header->nportals[0]; ++i)
|
||||
{
|
||||
const dtTilePortal* p = &header->portals[0][i];
|
||||
if (p->ncon)
|
||||
glColor4ub(255,255,255,192);
|
||||
else
|
||||
glColor4ub(255,0,0,64);
|
||||
glVertex3f(header->bmax[0]-0.1f, p->bmin[1], p->bmin[0]);
|
||||
glVertex3f(header->bmax[0]-0.1f, p->bmax[1], p->bmin[0]);
|
||||
|
||||
glVertex3f(header->bmax[0]-0.1f, p->bmax[1], p->bmin[0]);
|
||||
glVertex3f(header->bmax[0]-0.1f, p->bmax[1], p->bmax[0]);
|
||||
|
||||
glVertex3f(header->bmax[0]-0.1f, p->bmax[1], p->bmax[0]);
|
||||
glVertex3f(header->bmax[0]-0.1f, p->bmin[1], p->bmax[0]);
|
||||
|
||||
glVertex3f(header->bmax[0]-0.1f, p->bmin[1], p->bmax[0]);
|
||||
glVertex3f(header->bmax[0]-0.1f, p->bmin[1], p->bmin[0]);
|
||||
}
|
||||
for (int i = 0; i < header->nportals[1]; ++i)
|
||||
{
|
||||
const dtTilePortal* p = &header->portals[1][i];
|
||||
if (p->ncon)
|
||||
glColor4ub(255,255,255,192);
|
||||
else
|
||||
glColor4ub(255,0,0,64);
|
||||
glVertex3f(p->bmin[0], p->bmin[1], header->bmax[2]-0.1f);
|
||||
glVertex3f(p->bmin[0], p->bmax[1], header->bmax[2]-0.1f);
|
||||
|
||||
glVertex3f(p->bmin[0], p->bmax[1], header->bmax[2]-0.1f);
|
||||
glVertex3f(p->bmax[0], p->bmax[1], header->bmax[2]-0.1f);
|
||||
|
||||
glVertex3f(p->bmax[0], p->bmax[1], header->bmax[2]-0.1f);
|
||||
glVertex3f(p->bmax[0], p->bmin[1], header->bmax[2]-0.1f);
|
||||
|
||||
glVertex3f(p->bmax[0], p->bmin[1], header->bmax[2]-0.1f);
|
||||
glVertex3f(p->bmin[0], p->bmin[1], header->bmax[2]-0.1f);
|
||||
}
|
||||
for (int i = 0; i < header->nportals[2]; ++i)
|
||||
{
|
||||
const dtTilePortal* p = &header->portals[2][i];
|
||||
if (p->ncon)
|
||||
glColor4ub(255,255,255,192);
|
||||
else
|
||||
glColor4ub(255,0,0,64);
|
||||
glVertex3f(header->bmin[0]+0.1f, p->bmin[1], p->bmin[0]);
|
||||
glVertex3f(header->bmin[0]+0.1f, p->bmax[1], p->bmin[0]);
|
||||
|
||||
glVertex3f(header->bmin[0]+0.1f, p->bmax[1], p->bmin[0]);
|
||||
glVertex3f(header->bmin[0]+0.1f, p->bmax[1], p->bmax[0]);
|
||||
|
||||
glVertex3f(header->bmin[0]+0.1f, p->bmax[1], p->bmax[0]);
|
||||
glVertex3f(header->bmin[0]+0.1f, p->bmin[1], p->bmax[0]);
|
||||
|
||||
glVertex3f(header->bmin[0]+0.1f, p->bmin[1], p->bmax[0]);
|
||||
glVertex3f(header->bmin[0]+0.1f, p->bmin[1], p->bmin[0]);
|
||||
}
|
||||
for (int i = 0; i < header->nportals[3]; ++i)
|
||||
{
|
||||
const dtTilePortal* p = &header->portals[3][i];
|
||||
if (p->ncon)
|
||||
glColor4ub(255,255,255,192);
|
||||
else
|
||||
glColor4ub(255,0,0,64);
|
||||
glVertex3f(p->bmin[0], p->bmin[1], header->bmin[2]+0.1f);
|
||||
glVertex3f(p->bmin[0], p->bmax[1], header->bmin[2]+0.1f);
|
||||
|
||||
glVertex3f(p->bmin[0], p->bmax[1], header->bmin[2]+0.1f);
|
||||
glVertex3f(p->bmax[0], p->bmax[1], header->bmin[2]+0.1f);
|
||||
|
||||
glVertex3f(p->bmax[0], p->bmax[1], header->bmin[2]+0.1f);
|
||||
glVertex3f(p->bmax[0], p->bmin[1], header->bmin[2]+0.1f);
|
||||
|
||||
glVertex3f(p->bmax[0], p->bmin[1], header->bmin[2]+0.1f);
|
||||
glVertex3f(p->bmin[0], p->bmin[1], header->bmin[2]+0.1f);
|
||||
}
|
||||
glEnd();*/
|
||||
}
|
||||
|
||||
void dtDebugDrawTiledNavMesh(const dtTiledNavMesh* mesh)
|
||||
{
|
||||
if (!mesh) return;
|
||||
|
||||
for (int i = 0; i < DT_MAX_TILES; ++i)
|
||||
{
|
||||
const dtTile* tile = mesh->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
|
||||
drawTile(tile->header);
|
||||
}
|
||||
}
|
||||
|
||||
void dtDebugDrawTiledNavMeshPoly(const dtTiledNavMesh* mesh, dtTilePolyRef ref, const float* col)
|
||||
{
|
||||
const dtTilePoly* p = mesh->getPolyByRef(ref);
|
||||
if (!p) return;
|
||||
const float* verts = mesh->getPolyVertsByRef(ref);
|
||||
glColor4f(col[0],col[1],col[2],0.25f);
|
||||
glBegin(GL_TRIANGLES);
|
||||
unsigned short vi[3];
|
||||
for (int j = 2; j < (int)p->nv; ++j)
|
||||
{
|
||||
vi[0] = p->v[0];
|
||||
vi[1] = p->v[j-1];
|
||||
vi[2] = p->v[j];
|
||||
for (int k = 0; k < 3; ++k)
|
||||
{
|
||||
const float* v = &verts[vi[k]*3];
|
||||
glVertex3f(v[0], v[1]+0.2f, v[2]);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
@ -1204,7 +1204,7 @@ int dtStatNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos,
|
||||
if (resultCost)
|
||||
resultCost[n] = actualNode->total;
|
||||
if (resultDepth)
|
||||
resultDepth[n] = (unsigned short)actualNode->cost;
|
||||
resultDepth[n] = actualNode->cost;
|
||||
++n;
|
||||
}
|
||||
actualNode->flags = dtNode::OPEN;
|
||||
@ -1220,7 +1220,7 @@ int dtStatNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos,
|
||||
|
||||
// Returns polygons which are withing certain radius from the query location.
|
||||
int dtStatNavMesh::queryPolygons(const float* center, const float* extents,
|
||||
unsigned short* ids, const int maxIds)
|
||||
dtPolyRef* polys, const int maxIds)
|
||||
{
|
||||
if (!m_header) return 0;
|
||||
|
||||
@ -1256,7 +1256,7 @@ int dtStatNavMesh::queryPolygons(const float* center, const float* extents,
|
||||
{
|
||||
if (n < maxIds)
|
||||
{
|
||||
ids[n] = (unsigned short)node->i;
|
||||
polys[n] = (dtPolyRef)node->i;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
@ -1278,7 +1278,7 @@ dtPolyRef dtStatNavMesh::findNearestPoly(const float* center, const float* exten
|
||||
if (!m_header) return 0;
|
||||
|
||||
// Get nearby polygons from proximity grid.
|
||||
unsigned short polys[128];
|
||||
dtPolyRef polys[128];
|
||||
int npolys = queryPolygons(center, extents, polys, 128);
|
||||
|
||||
// Find nearest polygon amongst the nearby polygons.
|
||||
@ -1286,7 +1286,7 @@ dtPolyRef dtStatNavMesh::findNearestPoly(const float* center, const float* exten
|
||||
float nearestDistanceSqr = FLT_MAX;
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
{
|
||||
dtPolyRef ref = (dtPolyRef)polys[i];
|
||||
dtPolyRef ref = polys[i];
|
||||
float closest[3];
|
||||
if (!closestPointToPoly(ref, center, closest))
|
||||
continue;
|
||||
@ -1301,30 +1301,6 @@ dtPolyRef dtStatNavMesh::findNearestPoly(const float* center, const float* exten
|
||||
return nearest;
|
||||
}
|
||||
|
||||
bool dtStatNavMesh::getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const
|
||||
{
|
||||
const dtPoly* fromPoly = getPolyByRef(from);
|
||||
if (!fromPoly)
|
||||
return false;
|
||||
|
||||
// Find common edge between the polygons and returns the segment end points.
|
||||
for (unsigned i = 0, j = (int)fromPoly->nv - 1; i < (int)fromPoly->nv; j = i++)
|
||||
{
|
||||
unsigned short neighbour = fromPoly->n[j];
|
||||
if (neighbour == to)
|
||||
{
|
||||
const float* left = getVertex(fromPoly->v[j]);
|
||||
const float* right = getVertex(fromPoly->v[i]);
|
||||
mid[0] = (left[0]+right[0])*0.5f;
|
||||
mid[1] = (left[1]+right[1])*0.5f;
|
||||
mid[2] = (left[2]+right[2])*0.5f;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dtStatNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right) const
|
||||
{
|
||||
const dtPoly* fromPoly = getPolyByRef(from);
|
||||
|
1772
Detour/Source/DetourTiledNavMesh.cpp
Normal file
1772
Detour/Source/DetourTiledNavMesh.cpp
Normal file
File diff suppressed because it is too large
Load Diff
190
Detour/Source/DetourTiledNavMeshBuilder.cpp
Normal file
190
Detour/Source/DetourTiledNavMeshBuilder.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
//
|
||||
// Copyright (c) 2009 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "DetourTiledNavMesh.h"
|
||||
|
||||
template<class T> inline T abs(T a) { return a < 0 ? -a : a; }
|
||||
template<class T> inline T min(T a, T b) { return a < b ? a : b; }
|
||||
template<class T> inline T max(T a, T b) { return a > b ? a : b; }
|
||||
|
||||
bool dtCreateNavMeshTileData(const unsigned short* verts, const int nverts,
|
||||
const unsigned short* polys, const int npolys, const int nvp,
|
||||
const float* bmin, const float* bmax, float cs, float ch, int tileSize, int walkableClimb,
|
||||
unsigned char** outData, int* outDataSize)
|
||||
{
|
||||
if (nvp != DT_TILE_VERTS_PER_POLYGON)
|
||||
return false;
|
||||
if (nverts >= 0xffff)
|
||||
return false;
|
||||
|
||||
if (!nverts)
|
||||
return false;
|
||||
if (!npolys)
|
||||
return false;
|
||||
|
||||
/* int nportals[4] = {0,0,0,0};
|
||||
|
||||
// Find portals.
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
{
|
||||
const unsigned short* p = &polys[i*2*nvp];
|
||||
for (int j = 0; j < nvp; ++j)
|
||||
{
|
||||
if (p[j] == 0xffff) break;
|
||||
int nj = j+1;
|
||||
if (nj >= nvp || p[nj] == 0xffff) nj = 0;
|
||||
const unsigned short* va = &verts[p[j]*3];
|
||||
const unsigned short* vb = &verts[p[nj]*3];
|
||||
|
||||
if (va[0] == tileSize && vb[0] == tileSize)
|
||||
nportals[0]++; // x+
|
||||
else if (va[2] == tileSize && vb[2] == tileSize)
|
||||
nportals[1]++; // z+
|
||||
else if (va[0] == 0 && vb[0] == 0)
|
||||
nportals[2]++; // x-
|
||||
else if (va[2] == 0 && vb[2] == 0)
|
||||
nportals[3]++; // z-
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// Find portals.
|
||||
int nedges = 0;
|
||||
int nportals = 0;
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
{
|
||||
const unsigned short* p = &polys[i*2*nvp];
|
||||
for (int j = 0; j < nvp; ++j)
|
||||
{
|
||||
if (p[j] == 0xffff) break;
|
||||
int nj = j+1;
|
||||
if (nj >= nvp || p[nj] == 0xffff) nj = 0;
|
||||
const unsigned short* va = &verts[p[j]*3];
|
||||
const unsigned short* vb = &verts[p[nj]*3];
|
||||
|
||||
nedges++;
|
||||
|
||||
if (va[0] == tileSize && vb[0] == tileSize)
|
||||
nportals++; // x+
|
||||
else if (va[2] == tileSize && vb[2] == tileSize)
|
||||
nportals++; // z+
|
||||
else if (va[0] == 0 && vb[0] == 0)
|
||||
nportals++; // x-
|
||||
else if (va[2] == 0 && vb[2] == 0)
|
||||
nportals++; // z-
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate data size
|
||||
const int headerSize = sizeof(dtTileHeader);
|
||||
const int vertsSize = sizeof(float)*3*nverts;
|
||||
const int polysSize = sizeof(dtTilePoly)*npolys;
|
||||
// const int portalsSize = sizeof(dtTilePortal)*(nportals[0]+nportals[1]+nportals[2]+nportals[3]);
|
||||
// const int dataSize = headerSize + vertsSize + polysSize + portalsSize;
|
||||
const int linksSize = sizeof(dtTileLink)*(nedges + nportals*2);
|
||||
const int dataSize = headerSize + vertsSize + polysSize + linksSize;
|
||||
unsigned char* data = new unsigned char[dataSize];
|
||||
if (!data)
|
||||
return false;
|
||||
memset(data, 0, dataSize);
|
||||
|
||||
dtTileHeader* header = (dtTileHeader*)(data);
|
||||
float* navVerts = (float*)(data + headerSize);
|
||||
dtTilePoly* navPolys = (dtTilePoly*)(data + headerSize + vertsSize);
|
||||
/* dtTilePortal* portals[4];
|
||||
portals[0] = (dtTilePortal*)(data + headerSize + vertsSize + polysSize);
|
||||
portals[1] = portals[0] + nportals[0];
|
||||
portals[2] = portals[1] + nportals[1];
|
||||
portals[3] = portals[2] + nportals[2];*/
|
||||
|
||||
// Store header
|
||||
header->magic = DT_TILE_NAVMESH_MAGIC;
|
||||
header->version = DT_TILE_NAVMESH_VERSION;
|
||||
header->npolys = npolys;
|
||||
header->nverts = nverts;
|
||||
header->maxlinks = nedges + nportals*2;
|
||||
/* header->nportals[0] = nportals[0];
|
||||
header->nportals[1] = nportals[1];
|
||||
header->nportals[2] = nportals[2];
|
||||
header->nportals[3] = nportals[3];*/
|
||||
header->cs = cs;
|
||||
header->bmin[0] = bmin[0];
|
||||
header->bmin[1] = bmin[1];
|
||||
header->bmin[2] = bmin[2];
|
||||
header->bmax[0] = bmax[0];
|
||||
header->bmax[1] = bmax[1];
|
||||
header->bmax[2] = bmax[2];
|
||||
|
||||
// Store vertices
|
||||
for (int i = 0; i < nverts; ++i)
|
||||
{
|
||||
const unsigned short* iv = &verts[i*3];
|
||||
float* v = &navVerts[i*3];
|
||||
v[0] = bmin[0] + iv[0] * cs;
|
||||
v[1] = bmin[1] + iv[1] * ch;
|
||||
v[2] = bmin[2] + iv[2] * cs;
|
||||
}
|
||||
|
||||
// Store polygons
|
||||
const unsigned short* src = polys;
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
{
|
||||
dtTilePoly* p = &navPolys[i];
|
||||
p->nv = 0;
|
||||
for (int j = 0; j < nvp; ++j)
|
||||
{
|
||||
if (src[j] == 0xffff) break;
|
||||
p->v[j] = src[j];
|
||||
p->n[j] = (src[nvp+j]+1) & 0xffff;
|
||||
p->nv++;
|
||||
}
|
||||
src += nvp*2;
|
||||
}
|
||||
|
||||
// Store portals.
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
{
|
||||
dtTilePoly* poly = &navPolys[i];
|
||||
for (int j = 0; j < poly->nv; ++j)
|
||||
{
|
||||
int nj = j+1;
|
||||
if (nj >= poly->nv) nj = 0;
|
||||
|
||||
const unsigned short* va = &verts[poly->v[j]*3];
|
||||
const unsigned short* vb = &verts[poly->v[nj]*3];
|
||||
|
||||
if (va[0] == tileSize && vb[0] == tileSize) // x+
|
||||
poly->n[j] = 0x8000 | 0;
|
||||
else if (va[2] == tileSize && vb[2] == tileSize) // z+
|
||||
poly->n[j] = 0x8000 | 1;
|
||||
else if (va[0] == 0 && vb[0] == 0) // x-
|
||||
poly->n[j] = 0x8000 | 2;
|
||||
else if (va[2] == 0 && vb[2] == 0) // z-
|
||||
poly->n[j] = 0x8000 | 3;
|
||||
}
|
||||
}
|
||||
|
||||
*outData = data;
|
||||
*outDataSize = dataSize;
|
||||
|
||||
return true;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user