Changed Detour header var names more to verbose. Pass params as a struct to dtCreateNavMeshData. Named Off-mesh links to Off-mesh connections. Cleaned up Off-mesh connection code and samples. Added connection radius and direction to Off-mesh connections. Agent dimensions passed store in navmesh header.
This commit is contained in:
parent
da9dec1eef
commit
3abbfe006d
@ -30,6 +30,8 @@ enum duDebugDrawPrimitives
|
||||
// Abstrace debug draw interface.
|
||||
struct duDebugDraw
|
||||
{
|
||||
virtual void depthMask(bool state) = 0;
|
||||
|
||||
// Begin drawing primitives.
|
||||
// Params:
|
||||
// prim - (in) primitive type to draw, one of rcDebugDrawPrimitives.
|
||||
@ -79,7 +81,8 @@ void duDebugDrawBoxWire(struct duDebugDraw* dd, float minx, float miny, float mi
|
||||
float maxx, float maxy, float maxz, unsigned int col, const float lineWidth);
|
||||
|
||||
void duDebugDrawArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0,
|
||||
const float x1, const float y1, const float z1, const float h, unsigned int col, const float lineWidth);
|
||||
const float x1, const float y1, const float z1, const float h,
|
||||
const float as0, const float as1, unsigned int col, const float lineWidth);
|
||||
|
||||
void duDebugDrawCircle(struct duDebugDraw* dd, const float x, const float y, const float z,
|
||||
const float r, unsigned int col, const float lineWidth);
|
||||
@ -103,7 +106,8 @@ void duAppendBoxWire(struct duDebugDraw* dd, float minx, float miny, float minz,
|
||||
float maxx, float maxy, float maxz, unsigned int col);
|
||||
|
||||
void duAppendArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0,
|
||||
const float x1, const float y1, const float z1, const float h, unsigned int col);
|
||||
const float x1, const float y1, const float z1, const float h,
|
||||
const float as0, const float as1, unsigned int col);
|
||||
|
||||
void duAppendCircle(struct duDebugDraw* dd, const float x, const float y, const float z,
|
||||
const float r, unsigned int col);
|
||||
|
@ -21,7 +21,13 @@
|
||||
|
||||
#include "DetourNavMesh.h"
|
||||
|
||||
void duDebugDrawNavMesh(struct duDebugDraw* dd, const dtNavMesh* mesh, bool drawClosedList = false);
|
||||
enum DrawNavMeshFlags
|
||||
{
|
||||
DU_DRAWNAVMESH_CLOSEDLIST = 0x01,
|
||||
DU_DRAWNAVMESH_OFFMESHCONS = 0x02
|
||||
};
|
||||
|
||||
void duDebugDrawNavMesh(struct duDebugDraw* dd, const dtNavMesh* mesh, unsigned char flags);
|
||||
void duDebugDrawNavMeshBVTree(struct duDebugDraw* dd, const dtNavMesh* mesh);
|
||||
void duDebugDrawNavMeshPoly(struct duDebugDraw* dd, const dtNavMesh* mesh, dtPolyRef ref, const unsigned int col);
|
||||
|
||||
|
@ -79,10 +79,11 @@ void duDebugDrawBoxWire(struct duDebugDraw* dd, float minx, float miny, float mi
|
||||
}
|
||||
|
||||
void duDebugDrawArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0,
|
||||
const float x1, const float y1, const float z1, const float h, unsigned int col, const float lineWidth)
|
||||
const float x1, const float y1, const float z1, const float h,
|
||||
const float as0, const float as1, unsigned int col, const float lineWidth)
|
||||
{
|
||||
dd->begin(DU_DRAW_LINES, lineWidth);
|
||||
duAppendArc(dd, x0,y0,z0, x1,y1,z1, h, col);
|
||||
duAppendArc(dd, x0,y0,z0, x1,y1,z1, h, as0, as1, col);
|
||||
dd->end();
|
||||
}
|
||||
|
||||
@ -234,25 +235,98 @@ void duAppendBox(struct duDebugDraw* dd, float minx, float miny, float minz,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void evalArc(const float x0, const float y0, const float z0,
|
||||
const float dx, const float dy, const float dz,
|
||||
const float h, const float u, float* res)
|
||||
{
|
||||
res[0] = x0 + dx * u;
|
||||
res[1] = y0 + dy * u + h * (1-(u*2-1)*(u*2-1));
|
||||
res[2] = z0 + dz * u;
|
||||
}
|
||||
|
||||
|
||||
inline void vcross(float* dest, const float* v1, const float* v2)
|
||||
{
|
||||
dest[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||
dest[1] = v1[2]*v2[0] - v1[0]*v2[2];
|
||||
dest[2] = v1[0]*v2[1] - v1[1]*v2[0];
|
||||
}
|
||||
|
||||
inline void vnormalize(float* v)
|
||||
{
|
||||
float d = 1.0f / sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
v[0] *= d;
|
||||
v[1] *= d;
|
||||
v[2] *= d;
|
||||
}
|
||||
|
||||
inline void vsub(float* dest, const float* v1, const float* v2)
|
||||
{
|
||||
dest[0] = v1[0]-v2[0];
|
||||
dest[1] = v1[1]-v2[1];
|
||||
dest[2] = v1[2]-v2[2];
|
||||
}
|
||||
|
||||
|
||||
void appendArrowHead(struct duDebugDraw* dd, const float* p, const float* q,
|
||||
const float s, unsigned int col)
|
||||
{
|
||||
float ax[3], ay[3] = {0,1,0}, az[3];
|
||||
vsub(az, q, p);
|
||||
vnormalize(az);
|
||||
vcross(ax, ay, az);
|
||||
vcross(ay, az, ax);
|
||||
vnormalize(ay);
|
||||
|
||||
dd->vertex(p, col);
|
||||
// dd->vertex(p[0]+az[0]*s+ay[0]*s/2, p[1]+az[1]*s+ay[1]*s/2, p[2]+az[2]*s+ay[2]*s/2, col);
|
||||
dd->vertex(p[0]+az[0]*s+ax[0]*s/3, p[1]+az[1]*s+ax[1]*s/3, p[2]+az[2]*s+ax[2]*s/3, col);
|
||||
|
||||
dd->vertex(p, col);
|
||||
// dd->vertex(p[0]+az[0]*s-ay[0]*s/2, p[1]+az[1]*s-ay[1]*s/2, p[2]+az[2]*s-ay[2]*s/2, col);
|
||||
dd->vertex(p[0]+az[0]*s-ax[0]*s/3, p[1]+az[1]*s-ax[1]*s/3, p[2]+az[2]*s-ax[2]*s/3, col);
|
||||
|
||||
}
|
||||
|
||||
void duAppendArc(struct duDebugDraw* dd, const float x0, const float y0, const float z0,
|
||||
const float x1, const float y1, const float z1, const float h, unsigned int col)
|
||||
const float x1, const float y1, const float z1, const float h,
|
||||
const float as0, const float as1, unsigned int col)
|
||||
{
|
||||
static const int NUM_ARC_PTS = 8;
|
||||
static const float ARC_PTS_SCALE = 1.0f / (float)NUM_ARC_PTS;
|
||||
static const float PAD = 0.05f;
|
||||
static const float ARC_PTS_SCALE = (1.0f-PAD*2) / (float)NUM_ARC_PTS;
|
||||
const float dx = x1 - x0;
|
||||
const float dy = y1 - y0;
|
||||
const float dz = z1 - z0;
|
||||
const float len = sqrtf(dx*dx + dy*dy + dz*dz);
|
||||
float px = x0, py = y0, pz = z0;
|
||||
float prev[3];
|
||||
evalArc(x0,y0,z0, dx,dy,dz, len*h, PAD, prev);
|
||||
for (int i = 1; i <= NUM_ARC_PTS; ++i)
|
||||
{
|
||||
const float u = i * ARC_PTS_SCALE;
|
||||
const float x = x0 + dx * u;
|
||||
const float y = y0 + dy * u + (len*h) * (1-(u*2-1)*(u*2-1));
|
||||
const float z = z0 + dz * u;
|
||||
dd->vertex(px,py,pz, col);
|
||||
dd->vertex(x,y,z, col);
|
||||
px = x; py = y; pz = z;
|
||||
const float u = PAD + i * ARC_PTS_SCALE;
|
||||
float pt[3];
|
||||
evalArc(x0,y0,z0, dx,dy,dz, len*h, u, pt);
|
||||
dd->vertex(prev[0],prev[1],prev[2], col);
|
||||
dd->vertex(pt[0],pt[1],pt[2], col);
|
||||
prev[0] = pt[0]; prev[1] = pt[1]; prev[2] = pt[2];
|
||||
}
|
||||
|
||||
// End arrows
|
||||
if (as0 > 0.001f)
|
||||
{
|
||||
float p[3], q[3];
|
||||
evalArc(x0,y0,z0, dx,dy,dz, len*h, PAD, p);
|
||||
evalArc(x0,y0,z0, dx,dy,dz, len*h, PAD+0.05f, q);
|
||||
appendArrowHead(dd, p, q, as0, col);
|
||||
}
|
||||
|
||||
if (as1 > 0.001f)
|
||||
{
|
||||
float p[3], q[3];
|
||||
evalArc(x0,y0,z0, dx,dy,dz, len*h, 1-PAD, p);
|
||||
evalArc(x0,y0,z0, dx,dy,dz, len*h, 1-(PAD+0.05f), q);
|
||||
appendArrowHead(dd, p, q, as1, col);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,9 +16,11 @@
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include <math.h>
|
||||
#include "DebugDraw.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourCommon.h"
|
||||
|
||||
|
||||
static float distancePtLine2d(const float* pt, const float* p, const float* q)
|
||||
@ -43,26 +45,26 @@ static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshHeader* header,
|
||||
|
||||
dd->begin(DU_DRAW_LINES, linew);
|
||||
|
||||
for (int i = 0; i < header->npolys; ++i)
|
||||
for (int i = 0; i < header->polyCount; ++i)
|
||||
{
|
||||
const dtPoly* p = &header->polys[i];
|
||||
|
||||
if (p->flags & DT_POLY_OFFMESH_LINK) continue;
|
||||
if (p->flags & DT_POLY_OFFMESH_CONNECTION) continue;
|
||||
|
||||
const dtPolyDetail* pd = &header->dmeshes[i];
|
||||
const dtPolyDetail* pd = &header->detailMeshes[i];
|
||||
|
||||
for (int j = 0, nj = (int)p->nv; j < nj; ++j)
|
||||
for (int j = 0, nj = (int)p->vertCount; j < nj; ++j)
|
||||
{
|
||||
unsigned int c = col;
|
||||
if (inner)
|
||||
{
|
||||
if (p->n[j] == 0) continue;
|
||||
if (p->n[j] & 0x8000)
|
||||
if (p->neis[j] == 0) continue;
|
||||
if (p->neis[j] & DT_EXT_LINK)
|
||||
{
|
||||
bool con = false;
|
||||
for (int k = 0; k < p->nlinks; ++k)
|
||||
for (int k = 0; k < p->linkCount; ++k)
|
||||
{
|
||||
if (header->links[p->links+k].e == j)
|
||||
if (header->links[p->linkBase+k].edge == j)
|
||||
{
|
||||
con = true;
|
||||
break;
|
||||
@ -78,24 +80,24 @@ static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshHeader* header,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p->n[j] != 0) continue;
|
||||
if (p->neis[j] != 0) continue;
|
||||
}
|
||||
|
||||
const float* v0 = &header->verts[p->v[j]*3];
|
||||
const float* v1 = &header->verts[p->v[(j+1)%nj]*3];
|
||||
const float* v0 = &header->verts[p->verts[j]*3];
|
||||
const float* v1 = &header->verts[p->verts[(j+1) % nj]*3];
|
||||
|
||||
// Draw detail mesh edges which align with the actual poly edge.
|
||||
// This is really slow.
|
||||
for (int k = 0; k < pd->ntris; ++k)
|
||||
for (int k = 0; k < pd->triCount; ++k)
|
||||
{
|
||||
const unsigned char* t = &header->dtris[(pd->tbase+k)*4];
|
||||
const unsigned char* t = &header->detailTris[(pd->triBase+k)*4];
|
||||
const float* tv[3];
|
||||
for (int m = 0; m < 3; ++m)
|
||||
{
|
||||
if (t[m] < p->nv)
|
||||
tv[m] = &header->verts[p->v[t[m]]*3];
|
||||
if (t[m] < p->vertCount)
|
||||
tv[m] = &header->verts[p->verts[t[m]]*3];
|
||||
else
|
||||
tv[m] = &header->dverts[(pd->vbase+(t[m]-p->nv))*3];
|
||||
tv[m] = &header->detailVerts[(pd->vertBase+(t[m]-p->vertCount))*3];
|
||||
}
|
||||
for (int m = 0, n = 2; m < 3; n=m++)
|
||||
{
|
||||
@ -113,59 +115,88 @@ static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshHeader* header,
|
||||
dd->end();
|
||||
}
|
||||
|
||||
static void drawMeshTile(duDebugDraw* dd, const dtNavMesh* mesh, const dtMeshTile* tile, bool drawClosedList)
|
||||
static void drawMeshTile(duDebugDraw* dd, const dtNavMesh* mesh, const dtMeshTile* tile, unsigned char flags)
|
||||
{
|
||||
const dtMeshHeader* header = tile->header;
|
||||
dtPolyRef base = mesh->getTileId(tile);
|
||||
|
||||
dd->depthMask(false);
|
||||
|
||||
dd->begin(DU_DRAW_TRIS);
|
||||
for (int i = 0; i < header->npolys; ++i)
|
||||
for (int i = 0; i < header->polyCount; ++i)
|
||||
{
|
||||
const dtPoly* p = &header->polys[i];
|
||||
if (p->flags & DT_POLY_OFFMESH_LINK) // Skip off-mesh links.
|
||||
if (p->flags & DT_POLY_OFFMESH_CONNECTION) // Skip off-mesh links.
|
||||
continue;
|
||||
|
||||
const dtPolyDetail* pd = &header->dmeshes[i];
|
||||
const dtPolyDetail* pd = &header->detailMeshes[i];
|
||||
|
||||
unsigned int col;
|
||||
if (drawClosedList && mesh->isInClosedList(base | (dtPolyRef)i))
|
||||
if ((flags & DU_DRAWNAVMESH_CLOSEDLIST) && mesh->isInClosedList(base | (dtPolyRef)i))
|
||||
col = duRGBA(255,196,0,64);
|
||||
else
|
||||
col = duRGBA(0,196,255,64);
|
||||
|
||||
for (int j = 0; j < pd->ntris; ++j)
|
||||
for (int j = 0; j < pd->triCount; ++j)
|
||||
{
|
||||
const unsigned char* t = &header->dtris[(pd->tbase+j)*4];
|
||||
const unsigned char* t = &header->detailTris[(pd->triBase+j)*4];
|
||||
for (int k = 0; k < 3; ++k)
|
||||
{
|
||||
if (t[k] < p->nv)
|
||||
dd->vertex(&header->verts[p->v[t[k]]*3], col);
|
||||
if (t[k] < p->vertCount)
|
||||
dd->vertex(&header->verts[p->verts[t[k]]*3], col);
|
||||
else
|
||||
dd->vertex(&header->dverts[(pd->vbase+t[k]-p->nv)*3], col);
|
||||
dd->vertex(&header->detailVerts[(pd->vertBase+t[k]-p->vertCount)*3], col);
|
||||
}
|
||||
}
|
||||
}
|
||||
dd->end();
|
||||
|
||||
if (flags & DU_DRAWNAVMESH_OFFMESHCONS)
|
||||
{
|
||||
dd->begin(DU_DRAW_LINES, 2.0f);
|
||||
for (int i = 0; i < header->npolys; ++i)
|
||||
for (int i = 0; i < header->polyCount; ++i)
|
||||
{
|
||||
const dtPoly* p = &header->polys[i];
|
||||
if ((p->flags & DT_POLY_OFFMESH_LINK) == 0) // Skip regular polys.
|
||||
if ((p->flags & DT_POLY_OFFMESH_CONNECTION) == 0) // Skip regular polys.
|
||||
continue;
|
||||
|
||||
unsigned int col;
|
||||
if (drawClosedList && mesh->isInClosedList(base | (dtPolyRef)i))
|
||||
if ((flags & DU_DRAWNAVMESH_CLOSEDLIST) && mesh->isInClosedList(base | (dtPolyRef)i))
|
||||
col = duRGBA(255,196,0,220);
|
||||
else
|
||||
col = duRGBA(0,196,255,220);
|
||||
col = duRGBA(255,255,255,220);
|
||||
|
||||
const float* va = &header->verts[p->v[0]*3];
|
||||
const float* vb = &header->verts[p->v[1]*3];
|
||||
const dtOffMeshConnection* con = &header->offMeshCons[i - header->offMeshBase];
|
||||
const float* va = &header->verts[p->verts[0]*3];
|
||||
const float* vb = &header->verts[p->verts[1]*3];
|
||||
|
||||
duDebugDrawArc(dd, va[0],va[1]+0.1f,va[2], vb[0],vb[1]+0.1f,vb[2], 0.25f, col, 2.0f);
|
||||
// End points and their on-mesh locations.
|
||||
if (con->ref[0])
|
||||
{
|
||||
dd->vertex(va[0],va[1],va[2], col);
|
||||
dd->vertex(con->pos[0],con->pos[1],con->pos[2], col);
|
||||
duAppendCircle(dd, con->pos[0],con->pos[1]+0.1f,con->pos[2], con->rad, duRGBA(0,48,64,196));
|
||||
}
|
||||
if (con->ref[1])
|
||||
{
|
||||
dd->vertex(vb[0],vb[1],vb[2], col);
|
||||
dd->vertex(con->pos[3],con->pos[4],con->pos[5], col);
|
||||
duAppendCircle(dd, con->pos[3],con->pos[4]+0.1f,con->pos[5], con->rad, duRGBA(0,48,64,196));
|
||||
}
|
||||
|
||||
// End point vertices.
|
||||
dd->vertex(con->pos[0],con->pos[1],con->pos[2], duRGBA(0,48,64,196));
|
||||
dd->vertex(con->pos[0],con->pos[1]+0.2f,con->pos[2], duRGBA(0,48,64,196));
|
||||
|
||||
dd->vertex(con->pos[3],con->pos[4],con->pos[5], duRGBA(0,48,64,196));
|
||||
dd->vertex(con->pos[3],con->pos[4]+0.2f,con->pos[5], duRGBA(0,48,64,196));
|
||||
|
||||
// Connection arc.
|
||||
duAppendArc(dd, con->pos[0],con->pos[1],con->pos[2], con->pos[3],con->pos[4],con->pos[5], 0.25f,
|
||||
(con->flags & 1) ? 0.6f : 0, 0.6f, col);
|
||||
}
|
||||
dd->end();
|
||||
}
|
||||
|
||||
// Draw inter poly boundaries
|
||||
drawPolyBoundaries(dd, header, duRGBA(0,48,64,32), 1.5f, true);
|
||||
@ -175,7 +206,7 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh* mesh, const dtMeshTil
|
||||
|
||||
const unsigned int vcol = duRGBA(0,0,0,196);
|
||||
dd->begin(DU_DRAW_POINTS, 3.0f);
|
||||
for (int i = 0; i < header->nverts; ++i)
|
||||
for (int i = 0; i < header->vertCount; ++i)
|
||||
{
|
||||
const float* v = &header->verts[i*3];
|
||||
dd->vertex(v[0], v[1], v[2], vcol);
|
||||
@ -262,9 +293,12 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh* mesh, const dtMeshTil
|
||||
glVertex3f(p->bmin[0], p->bmin[1], header->bmin[2]+0.1f);
|
||||
}
|
||||
glEnd();*/
|
||||
|
||||
dd->depthMask(true);
|
||||
|
||||
}
|
||||
|
||||
void duDebugDrawNavMesh(duDebugDraw* dd, const dtNavMesh* mesh, bool drawClosedList)
|
||||
void duDebugDrawNavMesh(duDebugDraw* dd, const dtNavMesh* mesh, unsigned char flags)
|
||||
{
|
||||
if (!mesh) return;
|
||||
|
||||
@ -272,7 +306,7 @@ void duDebugDrawNavMesh(duDebugDraw* dd, const dtNavMesh* mesh, bool drawClosedL
|
||||
{
|
||||
const dtMeshTile* tile = mesh->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
drawMeshTile(dd, mesh, tile, drawClosedList);
|
||||
drawMeshTile(dd, mesh, tile, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@ -282,11 +316,11 @@ static void drawMeshTileBVTree(duDebugDraw* dd, const dtNavMesh* mesh, const dtM
|
||||
const dtMeshHeader* header = tile->header;
|
||||
|
||||
// Draw BV nodes.
|
||||
const float cs = 1.0f / header->bvquant;
|
||||
const float cs = 1.0f / header->bvQuantFactor;
|
||||
dd->begin(DU_DRAW_LINES, 1.0f);
|
||||
for (int i = 0; i < header->nbvtree; ++i)
|
||||
for (int i = 0; i < header->bvNodeCount; ++i)
|
||||
{
|
||||
const dtBVNode* n = &header->bvtree[i];
|
||||
const dtBVNode* n = &header->bvTree[i];
|
||||
if (n->i < 0) // Leaf indices are positive.
|
||||
continue;
|
||||
duAppendBoxWire(dd, header->bmin[0] + n->bmin[0]*cs,
|
||||
@ -402,31 +436,43 @@ void duDebugDrawNavMeshPoly(duDebugDraw* dd, const dtNavMesh* mesh, dtPolyRef re
|
||||
const dtMeshHeader* header = tile->header;
|
||||
const dtPoly* p = &header->polys[ip];
|
||||
|
||||
dd->depthMask(false);
|
||||
|
||||
const unsigned int c = (col & 0x00ffffff) | (64 << 24);
|
||||
|
||||
if (p->flags & DT_POLY_OFFMESH_LINK)
|
||||
if (p->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
const float* va = &header->verts[p->v[0]*3];
|
||||
const float* vb = &header->verts[p->v[1]*3];
|
||||
duDebugDrawArc(dd, va[0],va[1]+0.1f,va[2], vb[0],vb[1]+0.1f,vb[2], 0.25f, c, 2.0f);
|
||||
dtOffMeshConnection* con = &header->offMeshCons[ip - header->offMeshBase];
|
||||
|
||||
dd->begin(DU_DRAW_LINES, 2.0f);
|
||||
|
||||
// Connection arc.
|
||||
duAppendArc(dd, con->pos[0],con->pos[1],con->pos[2], con->pos[3],con->pos[4],con->pos[5], 0.25f,
|
||||
(con->flags & 1) ? 0.6f : 0, 0.6f, c);
|
||||
|
||||
dd->end();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
const dtPolyDetail* pd = &header->dmeshes[ip];
|
||||
const dtPolyDetail* pd = &header->detailMeshes[ip];
|
||||
|
||||
dd->begin(DU_DRAW_TRIS);
|
||||
for (int i = 0; i < pd->ntris; ++i)
|
||||
for (int i = 0; i < pd->triCount; ++i)
|
||||
{
|
||||
const unsigned char* t = &header->dtris[(pd->tbase+i)*4];
|
||||
const unsigned char* t = &header->detailTris[(pd->triBase+i)*4];
|
||||
for (int j = 0; j < 3; ++j)
|
||||
{
|
||||
if (t[j] < p->nv)
|
||||
dd->vertex(&header->verts[p->v[t[j]]*3], c);
|
||||
if (t[j] < p->vertCount)
|
||||
dd->vertex(&header->verts[p->verts[t[j]]*3], c);
|
||||
else
|
||||
dd->vertex(&header->dverts[(pd->vbase+t[j]-p->nv)*3], c);
|
||||
dd->vertex(&header->detailVerts[(pd->vertBase+t[j]-p->vertCount)*3], c);
|
||||
}
|
||||
}
|
||||
dd->end();
|
||||
}
|
||||
|
||||
dd->depthMask(true);
|
||||
|
||||
}
|
||||
|
||||
|
@ -72,148 +72,6 @@ void duDebugDrawTriMeshSlope(duDebugDraw* dd, const float* verts, int nverts,
|
||||
dd->end();
|
||||
}
|
||||
|
||||
/*
|
||||
static void drawBoxWire(duDebugDraw* dd,
|
||||
float minx, float miny, float minz,
|
||||
float maxx, float maxy, float maxz,
|
||||
const float* col)
|
||||
{
|
||||
// Submits 24 vertices.
|
||||
|
||||
unsigned int color = duRGBAf(col[0],col[1],col[2],col[3]);
|
||||
|
||||
// Top
|
||||
dd->vertex(minx, miny, minz, color);
|
||||
dd->vertex(maxx, miny, minz, color);
|
||||
dd->vertex(maxx, miny, minz, color);
|
||||
dd->vertex(maxx, miny, maxz, color);
|
||||
dd->vertex(maxx, miny, maxz, color);
|
||||
dd->vertex(minx, miny, maxz, color);
|
||||
dd->vertex(minx, miny, maxz, color);
|
||||
dd->vertex(minx, miny, minz, color);
|
||||
|
||||
// bottom
|
||||
dd->vertex(minx, maxy, minz, color);
|
||||
dd->vertex(maxx, maxy, minz, color);
|
||||
dd->vertex(maxx, maxy, minz, color);
|
||||
dd->vertex(maxx, maxy, maxz, color);
|
||||
dd->vertex(maxx, maxy, maxz, color);
|
||||
dd->vertex(minx, maxy, maxz, color);
|
||||
dd->vertex(minx, maxy, maxz, color);
|
||||
dd->vertex(minx, maxy, minz, color);
|
||||
|
||||
// Sides
|
||||
dd->vertex(minx, miny, minz, color);
|
||||
dd->vertex(minx, maxy, minz, color);
|
||||
dd->vertex(maxx, miny, minz, color);
|
||||
dd->vertex(maxx, maxy, minz, color);
|
||||
dd->vertex(maxx, miny, maxz, color);
|
||||
dd->vertex(maxx, maxy, maxz, color);
|
||||
dd->vertex(minx, miny, maxz, color);
|
||||
dd->vertex(minx, maxy, maxz, color);
|
||||
}
|
||||
*/
|
||||
/*static void drawBox(duDebugDraw* dd,
|
||||
float minx, float miny, float minz,
|
||||
float maxx, float maxy, float maxz,
|
||||
const float* col1, const float* col2)
|
||||
{
|
||||
// Submits 24 vertices.
|
||||
|
||||
const float verts[8*3] =
|
||||
{
|
||||
minx, miny, minz,
|
||||
maxx, miny, minz,
|
||||
maxx, miny, maxz,
|
||||
minx, miny, maxz,
|
||||
minx, maxy, minz,
|
||||
maxx, maxy, minz,
|
||||
maxx, maxy, maxz,
|
||||
minx, maxy, maxz,
|
||||
};
|
||||
static const float dim[6] =
|
||||
{
|
||||
0.95f, 0.55f, 0.65f, 0.85f, 0.65f, 0.85f,
|
||||
};
|
||||
static const unsigned char inds[6*5] =
|
||||
{
|
||||
0, 7, 6, 5, 4,
|
||||
1, 0, 1, 2, 3,
|
||||
2, 1, 5, 6, 2,
|
||||
3, 3, 7, 4, 0,
|
||||
4, 2, 6, 7, 3,
|
||||
5, 0, 4, 5, 1,
|
||||
};
|
||||
|
||||
const unsigned char* in = inds;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
float d = dim[*in]; in++;
|
||||
unsigned int color;
|
||||
if (i == 0)
|
||||
color = duRGBAf(d*col2[0],d*col2[1],d*col2[2], col2[3]);
|
||||
else
|
||||
color = duRGBAf(d*col1[0],d*col1[1],d*col1[2], col1[3]);
|
||||
dd->vertex(&verts[*in*3], color); in++;
|
||||
dd->vertex(&verts[*in*3], color); in++;
|
||||
dd->vertex(&verts[*in*3], color); in++;
|
||||
dd->vertex(&verts[*in*3], color); in++;
|
||||
}
|
||||
}
|
||||
|
||||
void duDebugDrawCylinderWire(duDebugDraw* dd, float minx, float miny, float minz,
|
||||
float maxx, float maxy, float maxz,
|
||||
const float* col)
|
||||
{
|
||||
static const int NUM_SEG = 16;
|
||||
float dir[NUM_SEG*2];
|
||||
for (int i = 0; i < NUM_SEG; ++i)
|
||||
{
|
||||
const float a = (float)i/(float)NUM_SEG*(float)M_PI*2;
|
||||
dir[i*2] = cosf(a);
|
||||
dir[i*2+1] = sinf(a);
|
||||
}
|
||||
|
||||
const float cx = (maxx + minx)/2;
|
||||
const float cz = (maxz + minz)/2;
|
||||
const float rx = (maxx - minx)/2;
|
||||
const float rz = (maxz - minz)/2;
|
||||
|
||||
unsigned int color = duRGBAf(col[0],col[1],col[2],col[3]);
|
||||
|
||||
dd->begin(DU_DRAW_LINES);
|
||||
|
||||
for (int i = 0, j=NUM_SEG-1; i < NUM_SEG; j=i++)
|
||||
{
|
||||
dd->vertex(cx+dir[j*2+0]*rx, miny, cz+dir[j*2+1]*rz, color);
|
||||
dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, color);
|
||||
dd->vertex(cx+dir[j*2+0]*rx, maxy, cz+dir[j*2+1]*rz, color);
|
||||
dd->vertex(cx+dir[i*2+0]*rx, maxy, cz+dir[i*2+1]*rz, color);
|
||||
}
|
||||
for (int i = 0; i < NUM_SEG; i += NUM_SEG/4)
|
||||
{
|
||||
dd->vertex(cx+dir[i*2+0]*rx, miny, cz+dir[i*2+1]*rz, color);
|
||||
dd->vertex(cx+dir[i*2+0]*rx, maxy, cz+dir[i*2+1]*rz, color);
|
||||
}
|
||||
|
||||
dd->end();
|
||||
}
|
||||
|
||||
void duDebugDrawBoxWire(duDebugDraw* dd, float minx, float miny, float minz, float maxx, float maxy, float maxz, const float* col)
|
||||
{
|
||||
dd->begin(DU_DRAW_LINES, 1.0f);
|
||||
drawBoxWire(dd, minx, miny, minz, maxx, maxy, maxz, col);
|
||||
dd->end();
|
||||
}
|
||||
|
||||
void duDebugDrawBox(duDebugDraw* dd, float minx, float miny, float minz, float maxx, float maxy, float maxz,
|
||||
const float* col1, const float* col2)
|
||||
{
|
||||
dd->begin(DU_DRAW_QUADS,24);
|
||||
drawBox(dd, minx, miny, minz, maxx, maxy, maxz, col1, col2);
|
||||
dd->end();
|
||||
}*/
|
||||
|
||||
static int getSpanCount(const rcHeightfield& hf)
|
||||
{
|
||||
const int w = hf.width;
|
||||
@ -433,6 +291,7 @@ static const rcContour* findContourFromSet(const rcContourSet& cset, unsigned sh
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
static const int NUM_ADU_PTS = 8;
|
||||
|
||||
void drawArc(duDebugDraw* dd, const float* p0, const float* p1, unsigned int color)
|
||||
@ -477,6 +336,7 @@ void duDebugDrawCross(struct duDebugDraw* dd, const float* p, const float s, con
|
||||
dd->vertex(p[0],p[1]+dy,p[2]+s, color);
|
||||
dd->end();
|
||||
}
|
||||
*/
|
||||
|
||||
void duDebugDrawRegionConnections(duDebugDraw* dd, const rcContourSet& cset, const float alpha)
|
||||
{
|
||||
@ -503,7 +363,7 @@ void duDebugDrawRegionConnections(duDebugDraw* dd, const rcContourSet& cset, con
|
||||
if (cont2)
|
||||
{
|
||||
getContourCenter(cont2, orig, cs, ch, pos2);
|
||||
drawArc(dd, pos, pos2, color);
|
||||
duAppendArc(dd, pos[0],pos[1],pos[2], pos2[0],pos2[1],pos2[2], 0.25f, 0.6f, 0.6f, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,6 +171,15 @@ inline bool checkOverlapBox(const unsigned short amin[3], const unsigned short a
|
||||
return overlap;
|
||||
}
|
||||
|
||||
inline bool overlapBounds(const float* amin, const float* amax, const float* bmin, const float* bmax)
|
||||
{
|
||||
bool overlap = true;
|
||||
overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap;
|
||||
overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap;
|
||||
overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap;
|
||||
return overlap;
|
||||
}
|
||||
|
||||
void closestPtPointTriangle(float* closest, const float* p,
|
||||
const float* a, const float* b, const float* c);
|
||||
|
||||
|
@ -28,34 +28,36 @@ static const int DT_VERTS_PER_POLYGON = 6;
|
||||
static const int DT_NAVMESH_MAGIC = 'DNAV';
|
||||
static const int DT_NAVMESH_VERSION = 2;
|
||||
|
||||
static const unsigned char DT_POLY_OFFMESH_LINK = 1;
|
||||
static const unsigned char DT_POLY_OFFMESH_CONNECTION = 1;
|
||||
|
||||
static const unsigned short DT_EXT_LINK = 0x8000;
|
||||
|
||||
// Structure describing the navigation polygon data.
|
||||
struct dtPoly
|
||||
{
|
||||
unsigned short v[DT_VERTS_PER_POLYGON]; // Indices to vertices of the poly.
|
||||
unsigned short n[DT_VERTS_PER_POLYGON]; // Refs to neighbours of the poly.
|
||||
unsigned short links; // Base index to header 'links' array.
|
||||
unsigned char nlinks; // Number of links for
|
||||
unsigned char nv; // Number of vertices.
|
||||
unsigned short verts[DT_VERTS_PER_POLYGON]; // Indices to vertices of the poly.
|
||||
unsigned short neis[DT_VERTS_PER_POLYGON]; // Refs to neighbours of the poly.
|
||||
unsigned short linkBase; // Base index to header 'links' array.
|
||||
unsigned char linkCount; // Number of links for
|
||||
unsigned char vertCount; // Number of vertices.
|
||||
unsigned char flags; // Flags.
|
||||
};
|
||||
|
||||
// Stucture describing polygon detail triangles.
|
||||
struct dtPolyDetail
|
||||
{
|
||||
unsigned short vbase; // Offset to detail vertex array.
|
||||
unsigned short nverts; // Number of vertices in the detail mesh.
|
||||
unsigned short tbase; // Offset to detail triangle array.
|
||||
unsigned short ntris; // Number of triangles.
|
||||
unsigned short vertBase; // Offset to detail vertex array.
|
||||
unsigned short vertCount; // Number of vertices in the detail mesh.
|
||||
unsigned short triBase; // Offset to detail triangle array.
|
||||
unsigned short triCount; // Number of triangles.
|
||||
};
|
||||
|
||||
// Stucture describing a link to another polygon.
|
||||
struct dtLink
|
||||
{
|
||||
dtPolyRef ref; // Neighbour reference.
|
||||
unsigned short p; // Index to polygon which owns this link.
|
||||
unsigned char e; // Index to polygon edge which owns this link.
|
||||
unsigned short poly; // Index to polygon which owns this link.
|
||||
unsigned char edge; // Index to polygon edge which owns this link.
|
||||
unsigned char side; // If boundary link, defines on which side the link is.
|
||||
unsigned char bmin, bmax; // If boundary link, defines the sub edge area.
|
||||
};
|
||||
@ -66,37 +68,43 @@ struct dtBVNode
|
||||
int i; // Index to item or if negative, escape index.
|
||||
};
|
||||
|
||||
struct dtOffMeshLink
|
||||
struct dtOffMeshConnection
|
||||
{
|
||||
dtPolyRef ref[2]; // Endpoint polys.
|
||||
unsigned short p; // Poly Id
|
||||
unsigned char side; // TODO
|
||||
float pos[6]; // Both end point locations.
|
||||
float rad; // Link connection radius.
|
||||
dtPolyRef ref[2]; // End point polys.
|
||||
unsigned short poly; // Poly Id
|
||||
unsigned char flags; // Link flags
|
||||
};
|
||||
|
||||
struct dtMeshHeader
|
||||
{
|
||||
int magic; // Magic number, used to identify the data.
|
||||
int version; // Data version number.
|
||||
int npolys; // Number of polygons in the tile.
|
||||
int nverts; // Number of vertices in the tile.
|
||||
int nlinks; // Number of links in the tile (will be updated when tile is added).
|
||||
int maxlinks; // Number of allocated links.
|
||||
int ndmeshes; // Number of detail meshes.
|
||||
int ndverts; // Number of detail vertices.
|
||||
int ndtris; // Number of detail triangles.
|
||||
int nbvtree; // Number of BVtree nodes.
|
||||
int nomlinks; // Number of Off-Mesh links.
|
||||
int nombase; // Index to first polygon which is Off-Mesh link.
|
||||
|
||||
int polyCount; // Number of polygons in the tile.
|
||||
int vertCount; // Number of vertices in the tile.
|
||||
int linkCount; // Number of links in the tile (will be updated when tile is added).
|
||||
int maxLinkCount; // Number of allocated links.
|
||||
int detailMeshCount; // Number of detail meshes.
|
||||
int detailVertCount; // Number of detail vertices.
|
||||
int detailTriCount; // Number of detail triangles.
|
||||
int bvNodeCount; // Number of BVtree nodes.
|
||||
int offMeshConCount; // Number of Off-Mesh links.
|
||||
int offMeshBase; // Index to first polygon which is Off-Mesh link.
|
||||
float walkableHeight;
|
||||
float walkableRadius;
|
||||
float walkableClimb;
|
||||
float bmin[3], bmax[3]; // Bounding box of the tile.
|
||||
float bvquant; // BVtree quantization factor (world to bvnode coords)
|
||||
float bvQuantFactor; // BVtree quantization factor (world to bvnode coords)
|
||||
dtPoly* polys; // Pointer to the polygons (will be updated when tile is added).
|
||||
float* verts; // Pointer to the vertices (will be updated when tile added).
|
||||
dtLink* links; // Pointer to the links (will be updated when tile added).
|
||||
dtPolyDetail* dmeshes; // Pointer to detail meshes (will be updated when tile added).
|
||||
float* dverts; // Pointer to detail vertices (will be updated when tile added).
|
||||
unsigned char* dtris; // Pointer to detail triangles (will be updated when tile added).
|
||||
dtBVNode* bvtree; // Pointer to BVtree nodes (will be updated when tile added).
|
||||
dtOffMeshLink* omlinks; // Pointer to Off-Mesh links. (will be updated when tile added).
|
||||
dtPolyDetail* detailMeshes; // Pointer to detail meshes (will be updated when tile added).
|
||||
float* detailVerts; // Pointer to detail vertices (will be updated when tile added).
|
||||
unsigned char* detailTris; // Pointer to detail triangles (will be updated when tile added).
|
||||
dtBVNode* bvTree; // Pointer to BVtree nodes (will be updated when tile added).
|
||||
dtOffMeshConnection* offMeshCons; // Pointer to Off-Mesh links. (will be updated when tile added).
|
||||
};
|
||||
|
||||
struct dtMeshTile
|
||||
@ -115,7 +123,7 @@ enum dtStraightPathFlags
|
||||
{
|
||||
DT_STRAIGHTPATH_START = 0x01, // The vertex is the start position.
|
||||
DT_STRAIGHTPATH_END = 0x02, // The vertex is the end position.
|
||||
DT_STRAIGHTPATH_OFFMESH_LINK = 0x04, // The vertex is start of an off-mesh link.
|
||||
DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, // The vertex is start of an off-mesh link.
|
||||
};
|
||||
|
||||
class dtNavMesh
|
||||
@ -129,13 +137,12 @@ public:
|
||||
// orig - (in) origin of the nav mesh tile space.
|
||||
// tileWidth - (in) width of each tile.
|
||||
// tileHeight - (in) height of each tile.
|
||||
// portalheight - (in) height of the portal region between tiles.
|
||||
// maxTiles - (in) maximum number of tiles the navmesh can contain*.
|
||||
// maxPolys - (in) maximum number of polygons each tile can contain*.
|
||||
// maxNodes - (in) maximum number of A* nodes to use*.
|
||||
// *) Will be rounded to next power of two.
|
||||
// Returns: True if succeed, else false.
|
||||
bool init(const float* orig, float tileWidth, float tileHeight, float portalHeight,
|
||||
bool init(const float* orig, float tileWidth, float tileHeight,
|
||||
int maxTiles, int maxPolys, int maxNodes);
|
||||
|
||||
// Initializes the nav mesh for single tile use.
|
||||
@ -197,8 +204,9 @@ public:
|
||||
// Params:
|
||||
// center - (in) The center of the search box.
|
||||
// extents - (in) The extents of the search box.
|
||||
// nearestPt - (out, opt) The nearest point on found polygon, null if not needed.
|
||||
// Returns: Reference identifier for the polygon, or 0 if no polygons found.
|
||||
dtPolyRef findNearestPoly(const float* center, const float* extents);
|
||||
dtPolyRef findNearestPoly(const float* center, const float* extents, float* nearestPt);
|
||||
|
||||
// Returns polygons which touch the query box.
|
||||
// Params:
|
||||
@ -312,7 +320,7 @@ public:
|
||||
// startPos - (out) start point of the link.
|
||||
// endPos - (out) end point of the link.
|
||||
// Returns: true if link is found.
|
||||
bool getOffMeshLinkPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const;
|
||||
bool getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const;
|
||||
|
||||
// Returns height of the polygon at specified location.
|
||||
// Params:
|
||||
@ -379,7 +387,6 @@ private:
|
||||
|
||||
float m_orig[3]; // Origin of the tile (0,0)
|
||||
float m_tileWidth, m_tileHeight; // Dimensions of each tile.
|
||||
float m_portalHeight; // Extra height value used to connect portals.
|
||||
int m_maxTiles; // Max number of tiles.
|
||||
int m_tileLutSize; // Tile hash lookup size (must be pot).
|
||||
int m_tileLutMask; // Tile hash lookup mask.
|
||||
|
@ -19,12 +19,36 @@
|
||||
#ifndef DETOURNAVMESHBUILDER_H
|
||||
#define DETOURNAVMESHBUILDER_H
|
||||
|
||||
bool dtCreateNavMeshData(const unsigned short* verts, const int nverts,
|
||||
const unsigned short* polys, const int npolys, const int nvp,
|
||||
const unsigned short* dmeshes, const float* dverts, const int ndverts,
|
||||
const unsigned char* dtris, const int ndtris,
|
||||
const float* omverts, const int nomlinks,
|
||||
const float* bmin, const float* bmax, float cs, float ch, int tileSize, int walkableClimb,
|
||||
unsigned char** outData, int* outDataSize);
|
||||
struct dtNavMeshCreateParams
|
||||
{
|
||||
// Navmesh vertices.
|
||||
const unsigned short* verts;
|
||||
int vertCount;
|
||||
// Navmesh polygons
|
||||
const unsigned short* polys;
|
||||
int polyCount;
|
||||
int nvp;
|
||||
// Navmesh Detail
|
||||
const unsigned short* detailMeshes;
|
||||
const float* detailVerts;
|
||||
int detailVertsCount;
|
||||
const unsigned char* detailTris;
|
||||
int detailTriCount;
|
||||
// Off-Mesh Connections.
|
||||
const float* offMeshConVerts;
|
||||
const float* offMeshConRad;
|
||||
const unsigned char* offMeshConDir;
|
||||
int offMeshConCount;
|
||||
// Settings
|
||||
float walkableHeight;
|
||||
float walkableRadius;
|
||||
float walkableClimb;
|
||||
float bmin[3], bmax[3];
|
||||
float cs;
|
||||
float ch;
|
||||
int tileSize;
|
||||
};
|
||||
|
||||
bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, int* outDataSize);
|
||||
|
||||
#endif // DETOURNAVMESHBUILDER_H
|
||||
|
@ -25,8 +25,6 @@
|
||||
#include "DetourCommon.h"
|
||||
|
||||
|
||||
static const unsigned short EXT_LINK = 0x8000;
|
||||
|
||||
inline int opposite(int side) { return (side+2) & 0x3; }
|
||||
|
||||
inline bool overlapBoxes(const float* amin, const float* amax,
|
||||
@ -82,7 +80,6 @@ inline int computeTileHash(int x, int y, const int mask)
|
||||
dtNavMesh::dtNavMesh() :
|
||||
m_tileWidth(0),
|
||||
m_tileHeight(0),
|
||||
m_portalHeight(0),
|
||||
m_maxTiles(0),
|
||||
m_tileLutSize(0),
|
||||
m_tileLutMask(0),
|
||||
@ -120,13 +117,12 @@ dtNavMesh::~dtNavMesh()
|
||||
delete [] m_tiles;
|
||||
}
|
||||
|
||||
bool dtNavMesh::init(const float* orig, float tileWidth, float tileHeight, float portalHeight,
|
||||
bool dtNavMesh::init(const float* orig, float tileWidth, float tileHeight,
|
||||
int maxTiles, int maxPolys, int maxNodes)
|
||||
{
|
||||
vcopy(m_orig, orig);
|
||||
m_tileWidth = tileWidth;
|
||||
m_tileHeight = tileHeight;
|
||||
m_portalHeight = portalHeight;
|
||||
|
||||
// Init tiles
|
||||
m_maxTiles = maxTiles;
|
||||
@ -184,7 +180,7 @@ bool dtNavMesh::init(unsigned char* data, int dataSize, bool ownsData, int maxNo
|
||||
|
||||
const float w = header->bmax[0] - header->bmin[0];
|
||||
const float h = header->bmax[2] - header->bmin[2];
|
||||
if (!init(header->bmin, w, h, 0, 1, header->npolys, maxNodes))
|
||||
if (!init(header->bmin, w, h, 1, header->polyCount, maxNodes))
|
||||
return false;
|
||||
|
||||
return addTileAt(0,0, data, dataSize, ownsData);
|
||||
@ -199,26 +195,27 @@ int dtNavMesh::findConnectingPolys(const float* va, const float* vb,
|
||||
dtMeshHeader* h = tile->header;
|
||||
|
||||
float amin[2], amax[2];
|
||||
calcRect(va,vb, amin,amax, side, 0.01f, m_portalHeight);
|
||||
calcRect(va,vb, amin,amax, side, 0.01f, h->walkableClimb);
|
||||
|
||||
// Remove links pointing to 'side' and compact the links array.
|
||||
float bmin[2], bmax[2];
|
||||
unsigned short m = EXT_LINK | (unsigned short)side;
|
||||
unsigned short m = DT_EXT_LINK | (unsigned short)side;
|
||||
int n = 0;
|
||||
|
||||
dtPolyRef base = getTileId(tile);
|
||||
|
||||
for (int i = 0; i < h->npolys; ++i)
|
||||
for (int i = 0; i < h->polyCount; ++i)
|
||||
{
|
||||
dtPoly* poly = &h->polys[i];
|
||||
for (int j = 0; j < poly->nv; ++j)
|
||||
const int nv = poly->vertCount;
|
||||
for (int j = 0; j < nv; ++j)
|
||||
{
|
||||
// Skip edges which do not point to the right side.
|
||||
if (poly->n[j] != m) continue;
|
||||
if (poly->neis[j] != m) continue;
|
||||
// Check if the segments touch.
|
||||
const float* vc = &h->verts[poly->v[j]*3];
|
||||
const float* vd = &h->verts[poly->v[(j+1) % (int)poly->nv]*3];
|
||||
calcRect(vc,vd, bmin,bmax, side, 0.01f, m_portalHeight);
|
||||
const float* vc = &h->verts[poly->verts[j]*3];
|
||||
const float* vd = &h->verts[poly->verts[(j+1) % nv]*3];
|
||||
calcRect(vc,vd, bmin,bmax, side, 0.01f, h->walkableClimb);
|
||||
if (!overlapRects(amin,amax, bmin,bmax)) continue;
|
||||
// Add return value.
|
||||
if (n < maxcon)
|
||||
@ -242,17 +239,17 @@ void dtNavMesh::removeExtLinks(dtMeshTile* tile, int side)
|
||||
// Remove links pointing to 'side' and compact the links array.
|
||||
dtLink* pool = m_tmpLinks;
|
||||
int nlinks = 0;
|
||||
for (int i = 0; i < h->npolys; ++i)
|
||||
for (int i = 0; i < h->polyCount; ++i)
|
||||
{
|
||||
dtPoly* poly = &h->polys[i];
|
||||
int plinks = nlinks;
|
||||
int nplinks = 0;
|
||||
for (int j = 0; j < poly->nlinks; ++j)
|
||||
for (int j = 0; j < poly->linkCount; ++j)
|
||||
{
|
||||
dtLink* link = &h->links[poly->links+j];
|
||||
dtLink* link = &h->links[poly->linkBase+j];
|
||||
if ((int)link->side != side)
|
||||
{
|
||||
if (nlinks < h->maxlinks)
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* dst = &pool[nlinks++];
|
||||
memcpy(dst, link, sizeof(dtLink));
|
||||
@ -260,11 +257,11 @@ void dtNavMesh::removeExtLinks(dtMeshTile* tile, int side)
|
||||
}
|
||||
}
|
||||
}
|
||||
poly->links = plinks;
|
||||
poly->nlinks = nplinks;
|
||||
poly->linkBase = plinks;
|
||||
poly->linkCount = nplinks;
|
||||
}
|
||||
h->nlinks = nlinks;
|
||||
if (h->nlinks)
|
||||
h->linkCount = nlinks;
|
||||
if (h->linkCount)
|
||||
memcpy(h->links, m_tmpLinks, sizeof(dtLink)*nlinks);
|
||||
}
|
||||
|
||||
@ -276,18 +273,18 @@ void dtNavMesh::buildExtLinks(dtMeshTile* tile, dtMeshTile* target, int side)
|
||||
// Remove links pointing to 'side' and compact the links array.
|
||||
dtLink* pool = m_tmpLinks;
|
||||
int nlinks = 0;
|
||||
for (int i = 0; i < h->npolys; ++i)
|
||||
for (int i = 0; i < h->polyCount; ++i)
|
||||
{
|
||||
dtPoly* poly = &h->polys[i];
|
||||
int plinks = nlinks;
|
||||
int nplinks = 0;
|
||||
// Copy internal and other external links.
|
||||
for (int j = 0; j < poly->nlinks; ++j)
|
||||
for (int j = 0; j < poly->linkCount; ++j)
|
||||
{
|
||||
dtLink* link = &h->links[poly->links+j];
|
||||
dtLink* link = &h->links[poly->linkBase+j];
|
||||
if ((int)link->side != side)
|
||||
{
|
||||
if (nlinks < h->maxlinks)
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* dst = &pool[nlinks++];
|
||||
memcpy(dst, link, sizeof(dtLink));
|
||||
@ -296,26 +293,27 @@ void dtNavMesh::buildExtLinks(dtMeshTile* tile, dtMeshTile* target, int side)
|
||||
}
|
||||
}
|
||||
// Create new links.
|
||||
unsigned short m = EXT_LINK | (unsigned short)side;
|
||||
for (int j = 0; j < poly->nv; ++j)
|
||||
unsigned short m = DT_EXT_LINK | (unsigned short)side;
|
||||
const int nv = poly->vertCount;
|
||||
for (int j = 0; j < nv; ++j)
|
||||
{
|
||||
// Skip edges which do not point to the right side.
|
||||
if (poly->n[j] != m) continue;
|
||||
if (poly->neis[j] != m) continue;
|
||||
|
||||
// Create new links
|
||||
const float* va = &h->verts[poly->v[j]*3];
|
||||
const float* vb = &h->verts[poly->v[(j+1)%(int)poly->nv]*3];
|
||||
const float* va = &h->verts[poly->verts[j]*3];
|
||||
const float* vb = &h->verts[poly->verts[(j+1) % nv]*3];
|
||||
dtPolyRef nei[4];
|
||||
float neia[4*2];
|
||||
int nnei = findConnectingPolys(va,vb, target, opposite(side), nei,neia,4);
|
||||
for (int k = 0; k < nnei; ++k)
|
||||
{
|
||||
if (nlinks < h->maxlinks)
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* link = &pool[nlinks++];
|
||||
link->ref = nei[k];
|
||||
link->p = (unsigned short)i;
|
||||
link->e = (unsigned char)j;
|
||||
link->poly = (unsigned short)i;
|
||||
link->edge = (unsigned char)j;
|
||||
link->side = (unsigned char)side;
|
||||
|
||||
// Compress portal limits to a byte value.
|
||||
@ -338,11 +336,11 @@ void dtNavMesh::buildExtLinks(dtMeshTile* tile, dtMeshTile* target, int side)
|
||||
}
|
||||
}
|
||||
|
||||
poly->links = plinks;
|
||||
poly->nlinks = nplinks;
|
||||
poly->linkBase = plinks;
|
||||
poly->linkCount = nplinks;
|
||||
}
|
||||
h->nlinks = nlinks;
|
||||
if (h->nlinks)
|
||||
h->linkCount = nlinks;
|
||||
if (h->linkCount)
|
||||
memcpy(h->links, m_tmpLinks, sizeof(dtLink)*nlinks);
|
||||
}
|
||||
|
||||
@ -358,95 +356,103 @@ void dtNavMesh::buildIntLinks(dtMeshTile* tile)
|
||||
unsigned int salt, it, ip, tileIdx;
|
||||
dtDecodePolyId(base, salt, tileIdx, ip);
|
||||
|
||||
// Find Off-mesh link end points.
|
||||
for (int i = 0; i < h->nomlinks; ++i)
|
||||
// Find Off-mesh connection end points.
|
||||
for (int i = 0; i < h->offMeshConCount; ++i)
|
||||
{
|
||||
dtOffMeshLink* link = &h->omlinks[i];
|
||||
dtPoly* poly = &h->polys[link->p];
|
||||
dtOffMeshConnection* con = &h->offMeshCons[i];
|
||||
dtPoly* poly = &h->polys[con->poly];
|
||||
|
||||
link->ref[0] = 0;
|
||||
link->ref[1] = 0;
|
||||
con->ref[0] = 0;
|
||||
con->ref[1] = 0;
|
||||
|
||||
const float ext[3] = { 0.1f, 0.3f, 0.1f }; //m_portalHeight }; // TODO: save agent size with mesh.
|
||||
const float ext[3] = { con->rad, h->walkableClimb, con->rad };
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
const float* v = &h->verts[poly->v[j]*3];
|
||||
dtPolyRef ref = findNearestPoly(v, ext);
|
||||
// Make sure the location is on current mesh.
|
||||
// Find polygon to connect to.
|
||||
const float* p = &con->pos[j*3];
|
||||
float nearestPt[3];
|
||||
dtPolyRef ref = findNearestPoly(p, ext, nearestPt);
|
||||
// findNearestPoly may return too optimistic results, further check to make sure.
|
||||
if (sqr(nearestPt[0]-p[0])+sqr(nearestPt[2]-p[2]) > sqr(con->rad))
|
||||
continue;
|
||||
|
||||
// TODO: Handle cross tile links.
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
if (it != tileIdx)
|
||||
continue;
|
||||
|
||||
link->ref[j] = ref;
|
||||
// Make sure the location is on current mesh.
|
||||
float* v = &h->verts[poly->verts[j]*3];
|
||||
vcopy(v, nearestPt);
|
||||
con->ref[j] = ref;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < h->npolys; ++i)
|
||||
for (int i = 0; i < h->polyCount; ++i)
|
||||
{
|
||||
dtPoly* poly = &h->polys[i];
|
||||
poly->links = nlinks;
|
||||
poly->nlinks = 0;
|
||||
poly->linkBase = nlinks;
|
||||
poly->linkCount = 0;
|
||||
|
||||
if (poly->flags & DT_POLY_OFFMESH_LINK)
|
||||
if (poly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
// Find Off-Mesh link and fill in information.
|
||||
dtOffMeshLink& omlink = h->omlinks[i - h->nombase];
|
||||
dtOffMeshConnection* con = &h->offMeshCons[i - h->offMeshBase];
|
||||
// Connect both ends.
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (nlinks < h->maxlinks)
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* link = &pool[nlinks++];
|
||||
link->ref = omlink.ref[j];
|
||||
link->p = (unsigned short)i;
|
||||
link->e = (unsigned char)j;
|
||||
link->ref = con->ref[j];
|
||||
link->poly = (unsigned short)i;
|
||||
link->edge = (unsigned char)j;
|
||||
link->side = 0xff;
|
||||
link->bmin = link->bmax = 0;
|
||||
poly->nlinks++;
|
||||
poly->linkCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Polygon edges.
|
||||
for (int j = 0; j < poly->nv; ++j)
|
||||
for (int j = 0; j < poly->vertCount; ++j)
|
||||
{
|
||||
// Skip hard and non-internal edges.
|
||||
if (poly->n[j] == 0 || (poly->n[j] & EXT_LINK)) continue;
|
||||
if (poly->neis[j] == 0 || (poly->neis[j] & DT_EXT_LINK)) continue;
|
||||
|
||||
if (nlinks < h->maxlinks)
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* link = &pool[nlinks++];
|
||||
link->ref = base | (unsigned int)(poly->n[j]-1);
|
||||
link->p = (unsigned short)i;
|
||||
link->e = (unsigned char)j;
|
||||
link->ref = base | (unsigned int)(poly->neis[j]-1);
|
||||
link->poly = (unsigned short)i;
|
||||
link->edge = (unsigned char)j;
|
||||
link->side = 0xff;
|
||||
link->bmin = link->bmax = 0;
|
||||
poly->nlinks++;
|
||||
poly->linkCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Check this polygon is Off-Mesh link target and connect.
|
||||
// TODO: Speed this up.
|
||||
dtPolyRef curRef = base | (unsigned int)i;
|
||||
for (int j = 0; j < h->nomlinks; ++j)
|
||||
for (int j = 0; j < h->offMeshConCount; ++j)
|
||||
{
|
||||
const dtOffMeshLink* omlink = &h->omlinks[j];
|
||||
const dtOffMeshConnection* con = &h->offMeshCons[j];
|
||||
// Test both end points.
|
||||
for (int k = 0; k < 2; ++k)
|
||||
{
|
||||
if (omlink->ref[k] == curRef)
|
||||
if (con->ref[k] == curRef)
|
||||
{
|
||||
if (nlinks < h->maxlinks)
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* link = &pool[nlinks++];
|
||||
link->ref = base | (dtPolyRef)omlink->p;
|
||||
link->p = (unsigned short)i;
|
||||
link->e = 0;
|
||||
link->ref = base | (dtPolyRef)con->poly;
|
||||
link->poly = (unsigned short)i;
|
||||
link->edge = 0;
|
||||
link->side = 0xff;
|
||||
link->bmin = link->bmax = 0;
|
||||
poly->nlinks++;
|
||||
poly->linkCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -455,7 +461,7 @@ void dtNavMesh::buildIntLinks(dtMeshTile* tile)
|
||||
}
|
||||
}
|
||||
|
||||
h->nlinks = nlinks;
|
||||
h->linkCount = nlinks;
|
||||
}
|
||||
|
||||
bool dtNavMesh::addTileAt(int x, int y, unsigned char* data, int dataSize, bool ownsData)
|
||||
@ -473,9 +479,9 @@ bool dtNavMesh::addTileAt(int x, int y, unsigned char* data, int dataSize, bool
|
||||
return false;
|
||||
|
||||
// Make sure the tmp link array is large enough.
|
||||
if (header->maxlinks > m_ntmpLinks)
|
||||
if (header->maxLinkCount > m_ntmpLinks)
|
||||
{
|
||||
m_ntmpLinks = header->maxlinks;
|
||||
m_ntmpLinks = header->maxLinkCount;
|
||||
delete [] m_tmpLinks;
|
||||
m_tmpLinks = 0;
|
||||
m_tmpLinks = new dtLink[m_ntmpLinks];
|
||||
@ -495,24 +501,24 @@ bool dtNavMesh::addTileAt(int x, int y, unsigned char* data, int dataSize, bool
|
||||
|
||||
// Patch header pointers.
|
||||
const int headerSize = align4(sizeof(dtMeshHeader));
|
||||
const int vertsSize = align4(sizeof(float)*3*header->nverts);
|
||||
const int polysSize = align4(sizeof(dtPoly)*header->npolys);
|
||||
const int linksSize = align4(sizeof(dtLink)*(header->maxlinks));
|
||||
const int detailMeshesSize = align4(sizeof(dtPolyDetail)*header->ndmeshes);
|
||||
const int detailVertsSize = align4(sizeof(float)*3*header->ndverts);
|
||||
const int detailTrisSize = align4(sizeof(unsigned char)*4*header->ndtris);
|
||||
const int bvtreeSize = header->nbvtree ? align4(sizeof(dtBVNode)*header->npolys*2) : 0;
|
||||
const int offMeshLinksSize = align4(sizeof(dtOffMeshLink)*header->nomlinks);
|
||||
const int vertsSize = align4(sizeof(float)*3*header->vertCount);
|
||||
const int polysSize = align4(sizeof(dtPoly)*header->polyCount);
|
||||
const int linksSize = align4(sizeof(dtLink)*(header->maxLinkCount));
|
||||
const int detailMeshesSize = align4(sizeof(dtPolyDetail)*header->detailMeshCount);
|
||||
const int detailVertsSize = align4(sizeof(float)*3*header->detailVertCount);
|
||||
const int detailTrisSize = align4(sizeof(unsigned char)*4*header->detailTriCount);
|
||||
const int bvtreeSize = header->bvNodeCount ? align4(sizeof(dtBVNode)*header->polyCount*2) : 0;
|
||||
const int offMeshLinksSize = align4(sizeof(dtOffMeshConnection)*header->offMeshConCount);
|
||||
|
||||
unsigned char* d = data + headerSize;
|
||||
header->verts = (float*)d; d += vertsSize;
|
||||
header->polys = (dtPoly*)d; d += polysSize;
|
||||
header->links = (dtLink*)d; d += linksSize;
|
||||
header->dmeshes = (dtPolyDetail*)d; d += detailMeshesSize;
|
||||
header->dverts = (float*)d; d += detailVertsSize;
|
||||
header->dtris = (unsigned char*)d; d += detailTrisSize;
|
||||
header->omlinks = (dtOffMeshLink*)d; d += offMeshLinksSize;
|
||||
header->bvtree = header->nbvtree ? (dtBVNode*)d : 0; d += bvtreeSize;
|
||||
header->detailMeshes = (dtPolyDetail*)d; d += detailMeshesSize;
|
||||
header->detailVerts = (float*)d; d += detailVertsSize;
|
||||
header->detailTris = (unsigned char*)d; d += detailTrisSize;
|
||||
header->offMeshCons = (dtOffMeshConnection*)d; d += offMeshLinksSize;
|
||||
header->bvTree = header->bvNodeCount ? (dtBVNode*)d : 0; d += bvtreeSize;
|
||||
|
||||
// Init tile.
|
||||
tile->header = header;
|
||||
@ -573,7 +579,7 @@ const dtMeshTile* dtNavMesh::getTileByRef(dtPolyRef ref, int* polyIndex) const
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return 0;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->npolys) return 0;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return 0;
|
||||
if (polyIndex) *polyIndex = (int)ip;
|
||||
return &m_tiles[it];
|
||||
}
|
||||
@ -663,22 +669,22 @@ bool dtNavMesh::closestPointOnPoly(dtPolyRef ref, const float* pos, float* close
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false;
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
|
||||
if (ip >= (unsigned int)header->npolys) return false;
|
||||
if (ip >= (unsigned int)header->polyCount) return false;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
float closestDistSqr = FLT_MAX;
|
||||
const dtPolyDetail* pd = &header->dmeshes[ip];
|
||||
const dtPolyDetail* pd = &header->detailMeshes[ip];
|
||||
|
||||
for (int j = 0; j < pd->ntris; ++j)
|
||||
for (int j = 0; j < pd->triCount; ++j)
|
||||
{
|
||||
const unsigned char* t = &header->dtris[(pd->tbase+j)*4];
|
||||
const unsigned char* t = &header->detailTris[(pd->triBase+j)*4];
|
||||
const float* v[3];
|
||||
for (int k = 0; k < 3; ++k)
|
||||
{
|
||||
if (t[k] < poly->nv)
|
||||
v[k] = &header->verts[poly->v[t[k]]*3];
|
||||
if (t[k] < poly->vertCount)
|
||||
v[k] = &header->verts[poly->verts[t[k]]*3];
|
||||
else
|
||||
v[k] = &header->dverts[(pd->vbase+(t[k]-poly->nv))*3];
|
||||
v[k] = &header->detailVerts[(pd->vertBase+(t[k]-poly->vertCount))*3];
|
||||
}
|
||||
float pt[3];
|
||||
closestPtPointTriangle(pt, pos, v[0], v[1], v[2]);
|
||||
@ -701,7 +707,7 @@ bool dtNavMesh::closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, floa
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false;
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
|
||||
if (ip >= (unsigned int)header->npolys) return false;
|
||||
if (ip >= (unsigned int)header->polyCount) return false;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
// Collect vertices.
|
||||
@ -709,9 +715,9 @@ bool dtNavMesh::closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, floa
|
||||
float edged[DT_VERTS_PER_POLYGON];
|
||||
float edget[DT_VERTS_PER_POLYGON];
|
||||
int nv = 0;
|
||||
for (int i = 0; i < (int)poly->nv; ++i)
|
||||
for (int i = 0; i < (int)poly->vertCount; ++i)
|
||||
{
|
||||
vcopy(&verts[nv*3], &header->verts[poly->v[i]*3]);
|
||||
vcopy(&verts[nv*3], &header->verts[poly->verts[i]*3]);
|
||||
nv++;
|
||||
}
|
||||
|
||||
@ -743,7 +749,7 @@ bool dtNavMesh::closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, floa
|
||||
}
|
||||
|
||||
// Returns start and end location of an off-mesh link polygon.
|
||||
bool dtNavMesh::getOffMeshLinkPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const
|
||||
bool dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
|
||||
@ -752,7 +758,7 @@ bool dtNavMesh::getOffMeshLinkPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef
|
||||
if (it >= (unsigned int)m_maxTiles) return false;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false;
|
||||
const dtMeshHeader* prevHeader = m_tiles[it].header;
|
||||
if (ip >= (unsigned int)prevHeader->npolys) return false;
|
||||
if (ip >= (unsigned int)prevHeader->polyCount) return false;
|
||||
const dtPoly* prevPoly = &prevHeader->polys[ip];
|
||||
|
||||
// Get current polygon
|
||||
@ -760,23 +766,23 @@ bool dtNavMesh::getOffMeshLinkPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef
|
||||
if (it >= (unsigned int)m_maxTiles) return false;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false;
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
if (ip >= (unsigned int)header->npolys) return false;
|
||||
if (ip >= (unsigned int)header->polyCount) return false;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
// Make sure that the current poly is indeed off-mesh link.
|
||||
if ((poly->flags & DT_POLY_OFFMESH_LINK) == 0)
|
||||
if ((poly->flags & DT_POLY_OFFMESH_CONNECTION) == 0)
|
||||
return false;
|
||||
|
||||
// Figure out which way to hand out the vertices.
|
||||
int idx0 = 0, idx1 = 1;
|
||||
|
||||
for (int i = 0; i < prevPoly->nlinks; ++i)
|
||||
for (int i = 0; i < prevPoly->linkCount; ++i)
|
||||
{
|
||||
const dtLink* link = &prevHeader->links[prevPoly->links+i];
|
||||
const dtLink* link = &prevHeader->links[prevPoly->linkBase+i];
|
||||
if (link->ref != polyRef)
|
||||
continue;
|
||||
// If first link does not point to the prev, then we need to reverse the order.
|
||||
if (header->links[poly->links+0].ref != prevRef)
|
||||
if (header->links[poly->linkBase+0].ref != prevRef)
|
||||
{
|
||||
idx0 = 1;
|
||||
idx1 = 0;
|
||||
@ -784,8 +790,8 @@ bool dtNavMesh::getOffMeshLinkPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef
|
||||
}
|
||||
}
|
||||
|
||||
vcopy(startPos, &header->verts[poly->v[idx0]*3]);
|
||||
vcopy(endPos, &header->verts[poly->v[idx1]*3]);
|
||||
vcopy(startPos, &header->verts[poly->verts[idx0]*3]);
|
||||
vcopy(endPos, &header->verts[poly->verts[idx1]*3]);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -799,13 +805,13 @@ bool dtNavMesh::getPolyHeight(dtPolyRef ref, const float* pos, float* height) co
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false;
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
|
||||
if (ip >= (unsigned int)header->npolys) return false;
|
||||
if (ip >= (unsigned int)header->polyCount) return false;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
if (poly->flags & DT_POLY_OFFMESH_LINK)
|
||||
if (poly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
const float* v0 = &header->verts[poly->v[0]*3];
|
||||
const float* v1 = &header->verts[poly->v[1]*3];
|
||||
const float* v0 = &header->verts[poly->verts[0]*3];
|
||||
const float* v1 = &header->verts[poly->verts[1]*3];
|
||||
const float d0 = vdist(pos, v0);
|
||||
const float d1 = vdist(pos, v1);
|
||||
const float u = d0 / (d0+d1);
|
||||
@ -815,17 +821,17 @@ bool dtNavMesh::getPolyHeight(dtPolyRef ref, const float* pos, float* height) co
|
||||
}
|
||||
else
|
||||
{
|
||||
const dtPolyDetail* pd = &header->dmeshes[ip];
|
||||
for (int j = 0; j < pd->ntris; ++j)
|
||||
const dtPolyDetail* pd = &header->detailMeshes[ip];
|
||||
for (int j = 0; j < pd->triCount; ++j)
|
||||
{
|
||||
const unsigned char* t = &header->dtris[(pd->tbase+j)*4];
|
||||
const unsigned char* t = &header->detailTris[(pd->triBase+j)*4];
|
||||
const float* v[3];
|
||||
for (int k = 0; k < 3; ++k)
|
||||
{
|
||||
if (t[k] < poly->nv)
|
||||
v[k] = &header->verts[poly->v[t[k]]*3];
|
||||
if (t[k] < poly->vertCount)
|
||||
v[k] = &header->verts[poly->verts[t[k]]*3];
|
||||
else
|
||||
v[k] = &header->dverts[(pd->vbase+(t[k]-poly->nv))*3];
|
||||
v[k] = &header->detailVerts[(pd->vertBase+(t[k]-poly->vertCount))*3];
|
||||
}
|
||||
float h;
|
||||
if (closestHeightPointTriangle(pos, v[0], v[1], v[2], h))
|
||||
@ -841,24 +847,26 @@ bool dtNavMesh::getPolyHeight(dtPolyRef ref, const float* pos, float* height) co
|
||||
}
|
||||
|
||||
|
||||
dtPolyRef dtNavMesh::findNearestPoly(const float* center, const float* extents)
|
||||
dtPolyRef dtNavMesh::findNearestPoly(const float* center, const float* extents, float* nearestPt)
|
||||
{
|
||||
// Get nearby polygons from proximity grid.
|
||||
dtPolyRef polys[128];
|
||||
int npolys = queryPolygons(center, extents, polys, 128);
|
||||
int polyCount = queryPolygons(center, extents, polys, 128);
|
||||
|
||||
// Find nearest polygon amongst the nearby polygons.
|
||||
dtPolyRef nearest = 0;
|
||||
float nearestDistanceSqr = FLT_MAX;
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
for (int i = 0; i < polyCount; ++i)
|
||||
{
|
||||
dtPolyRef ref = polys[i];
|
||||
float closest[3];
|
||||
if (!closestPointOnPoly(ref, center, closest))
|
||||
float closestPtPoly[3];
|
||||
if (!closestPointOnPoly(ref, center, closestPtPoly))
|
||||
continue;
|
||||
float d = vdistSqr(center, closest);
|
||||
float d = vdistSqr(center, closestPtPoly);
|
||||
if (d < nearestDistanceSqr)
|
||||
{
|
||||
if (nearestPt)
|
||||
vcopy(nearestPt, closestPtPoly);
|
||||
nearestDistanceSqr = d;
|
||||
nearest = ref;
|
||||
}
|
||||
@ -872,10 +880,10 @@ int dtNavMesh::queryTilePolygons(dtMeshTile* tile,
|
||||
dtPolyRef* polys, const int maxPolys)
|
||||
{
|
||||
const dtMeshHeader* header = tile->header;
|
||||
if (header->bvtree)
|
||||
if (header->bvTree)
|
||||
{
|
||||
const dtBVNode* node = &header->bvtree[0];
|
||||
const dtBVNode* end = &header->bvtree[header->nbvtree];
|
||||
const dtBVNode* node = &header->bvTree[0];
|
||||
const dtBVNode* end = &header->bvTree[header->bvNodeCount];
|
||||
|
||||
// Calculate quantized box
|
||||
unsigned short bmin[3], bmax[3];
|
||||
@ -887,12 +895,12 @@ int dtNavMesh::queryTilePolygons(dtMeshTile* tile,
|
||||
float maxy = clamp(qmax[1], header->bmin[1], header->bmax[1]) - header->bmin[1];
|
||||
float maxz = clamp(qmax[2], header->bmin[2], header->bmax[2]) - header->bmin[2];
|
||||
// Quantize
|
||||
bmin[0] = (unsigned short)(header->bvquant * minx) & 0xfffe;
|
||||
bmin[1] = (unsigned short)(header->bvquant * miny) & 0xfffe;
|
||||
bmin[2] = (unsigned short)(header->bvquant * minz) & 0xfffe;
|
||||
bmax[0] = (unsigned short)(header->bvquant * maxx + 1) | 1;
|
||||
bmax[1] = (unsigned short)(header->bvquant * maxy + 1) | 1;
|
||||
bmax[2] = (unsigned short)(header->bvquant * maxz + 1) | 1;
|
||||
bmin[0] = (unsigned short)(header->bvQuantFactor * minx) & 0xfffe;
|
||||
bmin[1] = (unsigned short)(header->bvQuantFactor * miny) & 0xfffe;
|
||||
bmin[2] = (unsigned short)(header->bvQuantFactor * minz) & 0xfffe;
|
||||
bmax[0] = (unsigned short)(header->bvQuantFactor * maxx + 1) | 1;
|
||||
bmax[1] = (unsigned short)(header->bvQuantFactor * maxy + 1) | 1;
|
||||
bmax[2] = (unsigned short)(header->bvQuantFactor * maxz + 1) | 1;
|
||||
|
||||
// Traverse tree
|
||||
dtPolyRef base = getTileId(tile);
|
||||
@ -925,16 +933,16 @@ int dtNavMesh::queryTilePolygons(dtMeshTile* tile,
|
||||
const dtMeshHeader* header = tile->header;
|
||||
int n = 0;
|
||||
dtPolyRef base = getTileId(tile);
|
||||
for (int i = 0; i < header->npolys; ++i)
|
||||
for (int i = 0; i < header->polyCount; ++i)
|
||||
{
|
||||
// Calc polygon bounds.
|
||||
dtPoly* p = &header->polys[i];
|
||||
const float* v = &header->verts[p->v[0]*3];
|
||||
const float* v = &header->verts[p->verts[0]*3];
|
||||
vcopy(bmin, v);
|
||||
vcopy(bmax, v);
|
||||
for (int j = 1; j < p->nv; ++j)
|
||||
for (int j = 1; j < p->vertCount; ++j)
|
||||
{
|
||||
v = &header->verts[p->v[j]*3];
|
||||
v = &header->verts[p->verts[j]*3];
|
||||
vmin(bmin, v);
|
||||
vmax(bmax, v);
|
||||
}
|
||||
@ -1036,9 +1044,9 @@ int dtNavMesh::findPath(dtPolyRef startRef, dtPolyRef endRef,
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
for (int i = 0; i < poly->nlinks; ++i)
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
{
|
||||
dtPolyRef neighbour = header->links[poly->links+i].ref;
|
||||
dtPolyRef neighbour = header->links[poly->linkBase+i].ref;
|
||||
if (neighbour)
|
||||
{
|
||||
// Skip parent node.
|
||||
@ -1228,7 +1236,7 @@ int dtNavMesh::findStraightPath(const float* startPos, const float* endPos,
|
||||
vcopy(portalApex, portalLeft);
|
||||
apexIndex = leftIndex;
|
||||
|
||||
unsigned char flags = (leftPolyFlags & DT_POLY_OFFMESH_LINK) ? DT_STRAIGHTPATH_OFFMESH_LINK : 0;
|
||||
unsigned char flags = (leftPolyFlags & DT_POLY_OFFMESH_CONNECTION) ? DT_STRAIGHTPATH_OFFMESH_CONNECTION : 0;
|
||||
dtPolyRef ref = leftPolyRef;
|
||||
|
||||
if (!vequal(&straightPath[(straightPathSize-1)*3], portalApex))
|
||||
@ -1289,7 +1297,7 @@ int dtNavMesh::findStraightPath(const float* startPos, const float* endPos,
|
||||
vcopy(portalApex, portalRight);
|
||||
apexIndex = rightIndex;
|
||||
|
||||
unsigned char flags = (rightPolyFlags & DT_POLY_OFFMESH_LINK) ? DT_STRAIGHTPATH_OFFMESH_LINK : 0;
|
||||
unsigned char flags = (rightPolyFlags & DT_POLY_OFFMESH_CONNECTION) ? DT_STRAIGHTPATH_OFFMESH_CONNECTION : 0;
|
||||
dtPolyRef ref = rightPolyRef;
|
||||
|
||||
if (!vequal(&straightPath[(straightPathSize-1)*3], portalApex))
|
||||
@ -1364,12 +1372,12 @@ int dtNavMesh::moveAlongPathCorridor(const float* startPos, const float* endPos,
|
||||
dtDecodePolyId(path[n], salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return n;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return n;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->npolys) return n;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return n;
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
// In case of Off-Mesh link, just snap to the end location and advance over it.
|
||||
if (poly->flags & DT_POLY_OFFMESH_LINK)
|
||||
if (poly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
if (n+1 < pathSize)
|
||||
{
|
||||
@ -1384,9 +1392,9 @@ int dtNavMesh::moveAlongPathCorridor(const float* startPos, const float* endPos,
|
||||
|
||||
// Collect vertices.
|
||||
int nv = 0;
|
||||
for (int i = 0; i < (int)poly->nv; ++i)
|
||||
for (int i = 0; i < (int)poly->vertCount; ++i)
|
||||
{
|
||||
vcopy(&verts[nv*3], &header->verts[poly->v[i]*3]);
|
||||
vcopy(&verts[nv*3], &header->verts[poly->verts[i]*3]);
|
||||
nv++;
|
||||
}
|
||||
|
||||
@ -1441,44 +1449,44 @@ bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float
|
||||
dtDecodePolyId(from, salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return false;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->npolys) return false;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return false;
|
||||
const dtMeshHeader* fromHeader = m_tiles[it].header;
|
||||
const dtPoly* fromPoly = &fromHeader->polys[ip];
|
||||
fromFlags = fromPoly->flags;
|
||||
|
||||
for (int i = 0; i < fromPoly->nlinks; ++i)
|
||||
for (int i = 0; i < fromPoly->linkCount; ++i)
|
||||
{
|
||||
const dtLink* link = &fromHeader->links[fromPoly->links+i];
|
||||
const dtLink* link = &fromHeader->links[fromPoly->linkBase+i];
|
||||
if (link->ref != to)
|
||||
continue;
|
||||
|
||||
dtDecodePolyId(to, salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return false;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->npolys) return false;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return false;
|
||||
const dtMeshHeader* toHeader = m_tiles[it].header;
|
||||
const dtPoly* toPoly = &toHeader->polys[ip];
|
||||
toFlags = toPoly->flags;
|
||||
|
||||
if (fromPoly->flags & DT_POLY_OFFMESH_LINK)
|
||||
if (fromPoly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
const int v = fromHeader->links[fromPoly->links+0].ref == to ? 0 : 1;
|
||||
vcopy(left, &fromHeader->verts[fromPoly->v[v]*3]);
|
||||
vcopy(right, &fromHeader->verts[fromPoly->v[v]*3]);
|
||||
const int v = fromHeader->links[fromPoly->linkBase+0].ref == to ? 0 : 1;
|
||||
vcopy(left, &fromHeader->verts[fromPoly->verts[v]*3]);
|
||||
vcopy(right, &fromHeader->verts[fromPoly->verts[v]*3]);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (toPoly->flags & DT_POLY_OFFMESH_LINK)
|
||||
if (toPoly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
const int v = toHeader->links[toPoly->links+0].ref == from ? 0 : 1;
|
||||
vcopy(left, &toHeader->verts[toPoly->v[v]*3]);
|
||||
vcopy(right, &toHeader->verts[toPoly->v[v]*3]);
|
||||
const int v = toHeader->links[toPoly->linkBase+0].ref == from ? 0 : 1;
|
||||
vcopy(left, &toHeader->verts[toPoly->verts[v]*3]);
|
||||
vcopy(right, &toHeader->verts[toPoly->verts[v]*3]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Find portal vertices.
|
||||
const int v0 = fromPoly->v[link->e];
|
||||
const int v1 = fromPoly->v[(link->e+1) % fromPoly->nv];
|
||||
const int v0 = fromPoly->verts[link->edge];
|
||||
const int v1 = fromPoly->verts[(link->edge+1) % (int)fromPoly->vertCount];
|
||||
vcopy(left, &fromHeader->verts[v0*3]);
|
||||
vcopy(right, &fromHeader->verts[v1*3]);
|
||||
// If the link is at tile boundary, clamp the vertices to
|
||||
@ -1554,9 +1562,9 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
|
||||
// Collect vertices.
|
||||
int nv = 0;
|
||||
for (int i = 0; i < (int)poly->nv; ++i)
|
||||
for (int i = 0; i < (int)poly->vertCount; ++i)
|
||||
{
|
||||
vcopy(&verts[nv*3], &header->verts[poly->v[i]*3]);
|
||||
vcopy(&verts[nv*3], &header->verts[poly->verts[i]*3]);
|
||||
nv++;
|
||||
}
|
||||
|
||||
@ -1576,10 +1584,10 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
|
||||
// Follow neighbours.
|
||||
dtPolyRef nextRef = 0;
|
||||
for (int i = 0; i < poly->nlinks; ++i)
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
{
|
||||
const dtLink* link = &header->links[poly->links+i];
|
||||
if ((int)link->e == segMax)
|
||||
const dtLink* link = &header->links[poly->linkBase+i];
|
||||
if ((int)link->edge == segMax)
|
||||
{
|
||||
// If the link is internal, just return the ref.
|
||||
if (link->side == 0xff)
|
||||
@ -1589,8 +1597,8 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
}
|
||||
|
||||
// If the link is at tile boundary,
|
||||
const int v0 = poly->v[link->e];
|
||||
const int v1 = poly->v[(link->e+1) % poly->nv];
|
||||
const int v0 = poly->verts[link->edge];
|
||||
const int v1 = poly->verts[(link->edge+1) % poly->vertCount];
|
||||
const float* left = &header->verts[v0*3];
|
||||
const float* right = &header->verts[v1*3];
|
||||
|
||||
@ -1700,9 +1708,9 @@ int dtNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos, floa
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
for (int i = 0; i < poly->nlinks; ++i)
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
{
|
||||
const dtLink* link = &header->links[poly->links+i];
|
||||
const dtLink* link = &header->links[poly->linkBase+i];
|
||||
dtPolyRef neighbour = link->ref;
|
||||
if (neighbour)
|
||||
{
|
||||
@ -1711,8 +1719,8 @@ int dtNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos, floa
|
||||
continue;
|
||||
|
||||
// Calc distance to the edge.
|
||||
const float* va = &header->verts[poly->v[link->e]*3];
|
||||
const float* vb = &header->verts[poly->v[(link->e+1)%poly->nv]*3];
|
||||
const float* va = &header->verts[poly->verts[link->edge]*3];
|
||||
const float* vb = &header->verts[poly->verts[(link->edge+1) % poly->vertCount]*3];
|
||||
float tseg;
|
||||
float distSqr = distancePtSegSqr2D(centerPos, va, vb, tseg);
|
||||
|
||||
@ -1804,17 +1812,17 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
// Hit test walls.
|
||||
for (int i = 0, j = (int)poly->nv-1; i < (int)poly->nv; j = i++)
|
||||
for (int i = 0, j = (int)poly->vertCount-1; i < (int)poly->vertCount; j = i++)
|
||||
{
|
||||
// Skip non-solid edges.
|
||||
if (poly->n[j] & EXT_LINK)
|
||||
if (poly->neis[j] & DT_EXT_LINK)
|
||||
{
|
||||
// Tile border.
|
||||
bool solid = true;
|
||||
for (int i = 0; i < poly->nlinks; ++i)
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
{
|
||||
const dtLink* link = &header->links[poly->links+i];
|
||||
if (link->e == j && link->ref != 0)
|
||||
const dtLink* link = &header->links[poly->linkBase+i];
|
||||
if (link->edge == j && link->ref != 0)
|
||||
{
|
||||
solid = false;
|
||||
break;
|
||||
@ -1822,15 +1830,15 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
}
|
||||
if (!solid) continue;
|
||||
}
|
||||
else if (poly->n[j])
|
||||
else if (poly->neis[j])
|
||||
{
|
||||
// Internal edge
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calc distance to the edge.
|
||||
const float* vj = &header->verts[poly->v[j]*3];
|
||||
const float* vi = &header->verts[poly->v[i]*3];
|
||||
const float* vj = &header->verts[poly->verts[j]*3];
|
||||
const float* vi = &header->verts[poly->verts[i]*3];
|
||||
float tseg;
|
||||
float distSqr = distancePtSegSqr2D(centerPos, vj, vi, tseg);
|
||||
|
||||
@ -1846,9 +1854,9 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
hitPos[2] = vj[2] + (vi[2] - vj[2])*tseg;
|
||||
}
|
||||
|
||||
for (int i = 0; i < poly->nlinks; ++i)
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
{
|
||||
const dtLink* link = &header->links[poly->links+i];
|
||||
const dtLink* link = &header->links[poly->linkBase+i];
|
||||
dtPolyRef neighbour = link->ref;
|
||||
if (neighbour)
|
||||
{
|
||||
@ -1857,8 +1865,8 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
continue;
|
||||
|
||||
// Calc distance to the edge.
|
||||
const float* va = &header->verts[poly->v[link->e]*3];
|
||||
const float* vb = &header->verts[poly->v[(link->e+1)%poly->nv]*3];
|
||||
const float* va = &header->verts[poly->verts[link->edge]*3];
|
||||
const float* vb = &header->verts[poly->verts[(link->edge+1) % poly->vertCount]*3];
|
||||
float tseg;
|
||||
float distSqr = distancePtSegSqr2D(centerPos, va, vb, tseg);
|
||||
|
||||
@ -1917,7 +1925,7 @@ const dtPoly* dtNavMesh::getPolyByRef(dtPolyRef ref) const
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return 0;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->npolys) return 0;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return 0;
|
||||
return &m_tiles[it].header->polys[ip];
|
||||
}
|
||||
|
||||
@ -1927,7 +1935,7 @@ const float* dtNavMesh::getPolyVertsByRef(dtPolyRef ref) const
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return 0;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->npolys) return 0;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return 0;
|
||||
return m_tiles[it].header->verts;
|
||||
}
|
||||
|
||||
@ -1937,7 +1945,7 @@ const dtLink* dtNavMesh::getPolyLinksByRef(dtPolyRef ref) const
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
if (it >= (unsigned int)m_maxTiles) return 0;
|
||||
if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return 0;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->npolys) return 0;
|
||||
if (ip >= (unsigned int)m_tiles[it].header->polyCount) return 0;
|
||||
return m_tiles[it].header->links;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <string.h>
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "DetourNavMeshBuilder.h"
|
||||
|
||||
|
||||
|
||||
@ -337,71 +338,64 @@ unsigned short findNearestPoly(dtMeshHeader* header, const float* center, const
|
||||
}
|
||||
*/
|
||||
|
||||
bool dtCreateNavMeshData(const unsigned short* verts, const int nverts,
|
||||
const unsigned short* polys, const int npolys, const int nvp,
|
||||
const unsigned short* dmeshes, const float* dverts, const int ndverts,
|
||||
const unsigned char* dtris, const int ndtris,
|
||||
const float* omverts, const int nomlinks,
|
||||
const float* bmin, const float* bmax, float cs, float ch, int tileSize, int walkableClimb,
|
||||
unsigned char** outData, int* outDataSize)
|
||||
bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, int* outDataSize)
|
||||
{
|
||||
if (nvp != DT_VERTS_PER_POLYGON)
|
||||
if (params->nvp > DT_VERTS_PER_POLYGON)
|
||||
return false;
|
||||
if (nverts >= 0xffff)
|
||||
if (params->vertCount >= 0xffff)
|
||||
return false;
|
||||
if (!params->vertCount || !params->verts)
|
||||
return false;
|
||||
if (!params->polyCount || !params->polys)
|
||||
return false;
|
||||
if (!params->detailMeshes || !params->detailVerts || !params->detailTris)
|
||||
return false;
|
||||
|
||||
if (!nverts)
|
||||
return false;
|
||||
if (!npolys)
|
||||
return false;
|
||||
if (!dmeshes || !dverts || ! dtris)
|
||||
return false;
|
||||
const int nvp = params->nvp;
|
||||
|
||||
// Off-mesh links are stored as polygons, adjust values.
|
||||
const int totpolys = npolys + nomlinks;
|
||||
const int totverts = nverts + nomlinks*2;
|
||||
// Off-mesh connectionss are stored as polygons, adjust values.
|
||||
const int totPolyCount = params->polyCount + params->offMeshConCount;
|
||||
const int totVertCount = params->vertCount + params->offMeshConCount*2;
|
||||
|
||||
// Find portal edges which are at tile borders.
|
||||
int nedges = 0;
|
||||
int nportals = 0;
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
int edgeCount = 0;
|
||||
int portalCount = 0;
|
||||
for (int i = 0; i < params->polyCount; ++i)
|
||||
{
|
||||
const unsigned short* p = &polys[i*2*nvp];
|
||||
const unsigned short* p = ¶ms->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];
|
||||
const unsigned short* va = ¶ms->verts[p[j]*3];
|
||||
const unsigned short* vb = ¶ms->verts[p[nj]*3];
|
||||
|
||||
nedges++;
|
||||
edgeCount++;
|
||||
|
||||
if (tileSize > 0)
|
||||
if (params->tileSize > 0)
|
||||
{
|
||||
if (va[0] == tileSize && vb[0] == tileSize)
|
||||
nportals++; // x+
|
||||
else if (va[2] == tileSize && vb[2] == tileSize)
|
||||
nportals++; // z+
|
||||
if (va[0] == params->tileSize && vb[0] == params->tileSize)
|
||||
portalCount++; // x+
|
||||
else if (va[2] == params->tileSize && vb[2] == params->tileSize)
|
||||
portalCount++; // z+
|
||||
else if (va[0] == 0 && vb[0] == 0)
|
||||
nportals++; // x-
|
||||
portalCount++; // x-
|
||||
else if (va[2] == 0 && vb[2] == 0)
|
||||
nportals++; // z-
|
||||
portalCount++; // z-
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int maxLinks = nedges + nportals*2 + nomlinks*4;
|
||||
const int maxLinkCount = edgeCount + portalCount*2 + params->offMeshConCount*4;
|
||||
|
||||
|
||||
// Find unique detail vertices.
|
||||
int uniqueDetailVerts = 0;
|
||||
if (dmeshes)
|
||||
int uniqueDetailVertCount = 0;
|
||||
for (int i = 0; i < params->polyCount; ++i)
|
||||
{
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
{
|
||||
const unsigned short* p = &polys[i*nvp*2];
|
||||
int ndv = dmeshes[i*4+1];
|
||||
const unsigned short* p = ¶ms->polys[i*nvp*2];
|
||||
int ndv = params->detailMeshes[i*4+1];
|
||||
int nv = 0;
|
||||
for (int j = 0; j < nvp; ++j)
|
||||
{
|
||||
@ -409,24 +403,23 @@ bool dtCreateNavMeshData(const unsigned short* verts, const int nverts,
|
||||
nv++;
|
||||
}
|
||||
ndv -= nv;
|
||||
uniqueDetailVerts += ndv;
|
||||
}
|
||||
uniqueDetailVertCount += ndv;
|
||||
}
|
||||
|
||||
// Calculate data size
|
||||
const int headerSize = align4(sizeof(dtMeshHeader));
|
||||
const int vertsSize = align4(sizeof(float)*3*totverts);
|
||||
const int polysSize = align4(sizeof(dtPoly)*totpolys);
|
||||
const int linksSize = align4(sizeof(dtLink)*maxLinks);
|
||||
const int detailMeshesSize = align4(sizeof(dtPolyDetail)*npolys);
|
||||
const int detailVertsSize = align4(sizeof(float)*3*uniqueDetailVerts);
|
||||
const int detailTrisSize = align4(sizeof(unsigned char)*4*ndtris);
|
||||
const int bvtreeSize = align4(sizeof(dtBVNode)*npolys*2);
|
||||
const int offMeshLinksSize = align4(sizeof(dtOffMeshLink)*nomlinks);
|
||||
const int vertsSize = align4(sizeof(float)*3*totVertCount);
|
||||
const int polysSize = align4(sizeof(dtPoly)*totPolyCount);
|
||||
const int linksSize = align4(sizeof(dtLink)*maxLinkCount);
|
||||
const int detailMeshesSize = align4(sizeof(dtPolyDetail)*params->polyCount);
|
||||
const int detailVertsSize = align4(sizeof(float)*3*uniqueDetailVertCount);
|
||||
const int detailTrisSize = align4(sizeof(unsigned char)*4*params->detailTriCount);
|
||||
const int bvTreeSize = align4(sizeof(dtBVNode)*params->polyCount*2);
|
||||
const int offMeshConsSize = align4(sizeof(dtOffMeshConnection)*params->offMeshConCount);
|
||||
|
||||
const int dataSize = headerSize + vertsSize + polysSize + linksSize +
|
||||
detailMeshesSize + detailVertsSize + detailTrisSize +
|
||||
bvtreeSize + offMeshLinksSize;
|
||||
bvTreeSize + offMeshConsSize;
|
||||
|
||||
unsigned char* data = new unsigned char[dataSize];
|
||||
if (!data)
|
||||
@ -441,98 +434,99 @@ bool dtCreateNavMeshData(const unsigned short* verts, const int nverts,
|
||||
dtPolyDetail* navDMeshes = (dtPolyDetail*)d; d += detailMeshesSize;
|
||||
float* navDVerts = (float*)d; d += detailVertsSize;
|
||||
unsigned char* navDTris = (unsigned char*)d; d += detailTrisSize;
|
||||
dtOffMeshLink* offMeshLinks = (dtOffMeshLink*)d; d += offMeshLinksSize;
|
||||
dtBVNode* navBvtree = (dtBVNode*)d; d += bvtreeSize;
|
||||
dtOffMeshConnection* offMeshCons = (dtOffMeshConnection*)d; d += offMeshConsSize;
|
||||
dtBVNode* navBvtree = (dtBVNode*)d; d += bvTreeSize;
|
||||
|
||||
|
||||
// Store header
|
||||
header->magic = DT_NAVMESH_MAGIC;
|
||||
header->version = DT_NAVMESH_VERSION;
|
||||
header->npolys = totpolys;
|
||||
header->nverts = totverts;
|
||||
header->maxlinks = maxLinks;
|
||||
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];
|
||||
header->ndmeshes = npolys;
|
||||
header->ndverts = uniqueDetailVerts;
|
||||
header->ndtris = ndtris;
|
||||
header->bvquant = 1.0f/cs;
|
||||
header->nombase = npolys;
|
||||
header->nomlinks = nomlinks;
|
||||
header->nbvtree = npolys*2;
|
||||
header->polyCount = totPolyCount;
|
||||
header->vertCount = totVertCount;
|
||||
header->maxLinkCount = maxLinkCount;
|
||||
vcopy(header->bmin, params->bmin);
|
||||
vcopy(header->bmax, params->bmax);
|
||||
header->detailMeshCount = params->polyCount;
|
||||
header->detailVertCount = uniqueDetailVertCount;
|
||||
header->detailTriCount = params->detailTriCount;
|
||||
header->bvQuantFactor = 1.0f / params->cs;
|
||||
header->offMeshBase = params->polyCount;
|
||||
header->walkableHeight = params->walkableHeight;
|
||||
header->walkableRadius = params->walkableRadius;
|
||||
header->walkableClimb = params->walkableClimb;
|
||||
header->offMeshConCount = params->offMeshConCount;
|
||||
header->bvNodeCount = params->polyCount*2;
|
||||
|
||||
const int offMeshVertsBase = params->vertCount;
|
||||
const int offMeshPolyBase = params->polyCount;
|
||||
|
||||
// Store vertices
|
||||
// Mesh vertices
|
||||
for (int i = 0; i < nverts; ++i)
|
||||
for (int i = 0; i < params->vertCount; ++i)
|
||||
{
|
||||
const unsigned short* iv = &verts[i*3];
|
||||
const unsigned short* iv = ¶ms->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;
|
||||
v[0] = params->bmin[0] + iv[0] * params->cs;
|
||||
v[1] = params->bmin[1] + iv[1] * params->ch;
|
||||
v[2] = params->bmin[2] + iv[2] * params->cs;
|
||||
}
|
||||
// Off-mesh link vertices.
|
||||
for (int i = 0; i < nomlinks; ++i)
|
||||
for (int i = 0; i < params->offMeshConCount; ++i)
|
||||
{
|
||||
const float* linkv = &omverts[i*2*3];
|
||||
float* v = &navVerts[(nverts+i*2)*3];
|
||||
const float* linkv = ¶ms->offMeshConVerts[i*2*3];
|
||||
float* v = &navVerts[(offMeshVertsBase + i*2)*3];
|
||||
vcopy(&v[0], &linkv[0]);
|
||||
vcopy(&v[3], &linkv[3]);
|
||||
}
|
||||
|
||||
// Store polygons
|
||||
// Mesh polys
|
||||
const unsigned short* src = polys;
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
const unsigned short* src = params->polys;
|
||||
for (int i = 0; i < params->polyCount; ++i)
|
||||
{
|
||||
dtPoly* p = &navPolys[i];
|
||||
p->nv = 0;
|
||||
p->vertCount = 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++;
|
||||
p->verts[j] = src[j];
|
||||
p->neis[j] = (src[nvp+j]+1) & 0xffff;
|
||||
p->vertCount++;
|
||||
}
|
||||
src += nvp*2;
|
||||
}
|
||||
// Off-mesh link vertices.
|
||||
const int omvbase = nverts; // first off-mesh link vertex.
|
||||
for (int i = 0; i < nomlinks; ++i)
|
||||
// Off-mesh connection vertices.
|
||||
for (int i = 0; i < params->offMeshConCount; ++i)
|
||||
{
|
||||
dtPoly* p = &navPolys[npolys+i];
|
||||
p->nv = 2;
|
||||
p->v[0] = (unsigned short)(omvbase + i*2+0);
|
||||
p->v[1] = (unsigned short)(omvbase + i*2+1);
|
||||
p->flags = DT_POLY_OFFMESH_LINK; // Off-mesh link poly.
|
||||
dtPoly* p = &navPolys[offMeshPolyBase+i];
|
||||
p->vertCount = 2;
|
||||
p->verts[0] = (unsigned short)(offMeshVertsBase + i*2+0);
|
||||
p->verts[1] = (unsigned short)(offMeshVertsBase + i*2+1);
|
||||
p->flags = DT_POLY_OFFMESH_CONNECTION; // Off-mesh link poly.
|
||||
}
|
||||
|
||||
// Store portal edges.
|
||||
if (tileSize > 0)
|
||||
if (params->tileSize > 0)
|
||||
{
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
for (int i = 0; i < params->polyCount; ++i)
|
||||
{
|
||||
dtPoly* poly = &navPolys[i];
|
||||
for (int j = 0; j < poly->nv; ++j)
|
||||
for (int j = 0; j < poly->vertCount; ++j)
|
||||
{
|
||||
int nj = j+1;
|
||||
if (nj >= poly->nv) nj = 0;
|
||||
if (nj >= poly->vertCount) nj = 0;
|
||||
|
||||
const unsigned short* va = &verts[poly->v[j]*3];
|
||||
const unsigned short* vb = &verts[poly->v[nj]*3];
|
||||
const unsigned short* va = ¶ms->verts[poly->verts[j]*3];
|
||||
const unsigned short* vb = ¶ms->verts[poly->verts[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;
|
||||
if (va[0] == params->tileSize && vb[0] == params->tileSize) // x+
|
||||
poly->neis[j] = DT_EXT_LINK | 0;
|
||||
else if (va[2] == params->tileSize && vb[2] == params->tileSize) // z+
|
||||
poly->neis[j] = DT_EXT_LINK | 1;
|
||||
else if (va[0] == 0 && vb[0] == 0) // x-
|
||||
poly->n[j] = 0x8000 | 2;
|
||||
poly->neis[j] = DT_EXT_LINK | 2;
|
||||
else if (va[2] == 0 && vb[2] == 0) // z-
|
||||
poly->n[j] = 0x8000 | 3;
|
||||
poly->neis[j] = DT_EXT_LINK | 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -541,35 +535,42 @@ bool dtCreateNavMeshData(const unsigned short* verts, const int nverts,
|
||||
// The nav polygon vertices are stored as the first vertices on each mesh.
|
||||
// We compress the mesh data by skipping them and using the navmesh coordinates.
|
||||
unsigned short vbase = 0;
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
for (int i = 0; i < params->polyCount; ++i)
|
||||
{
|
||||
dtPolyDetail& dtl = navDMeshes[i];
|
||||
const int vb = dmeshes[i*4+0];
|
||||
const int ndv = dmeshes[i*4+1];
|
||||
const int nv = navPolys[i].nv;
|
||||
dtl.vbase = vbase;
|
||||
dtl.nverts = ndv-nv;
|
||||
dtl.tbase = dmeshes[i*4+2];
|
||||
dtl.ntris = dmeshes[i*4+3];
|
||||
const int vb = params->detailMeshes[i*4+0];
|
||||
const int ndv = params->detailMeshes[i*4+1];
|
||||
const int nv = navPolys[i].vertCount;
|
||||
dtl.vertBase = vbase;
|
||||
dtl.vertCount = ndv-nv;
|
||||
dtl.triBase = params->detailMeshes[i*4+2];
|
||||
dtl.triCount = params->detailMeshes[i*4+3];
|
||||
// Copy vertices except the first 'nv' verts which are equal to nav poly verts.
|
||||
if (ndv-nv)
|
||||
{
|
||||
memcpy(&navDVerts[vbase*3], &dverts[(vb+nv)*3], sizeof(float)*3*(ndv-nv));
|
||||
memcpy(&navDVerts[vbase*3], ¶ms->detailVerts[(vb+nv)*3], sizeof(float)*3*(ndv-nv));
|
||||
vbase += ndv-nv;
|
||||
}
|
||||
}
|
||||
// Store triangles.
|
||||
memcpy(navDTris, dtris, sizeof(unsigned char)*4*ndtris);
|
||||
memcpy(navDTris, params->detailTris, sizeof(unsigned char)*4*params->detailTriCount);
|
||||
|
||||
// Store and create BVtree.
|
||||
// TODO: take detail mesh into account! use byte per bbox extent?
|
||||
createBVTree(verts, nverts, polys, npolys, nvp, cs, ch, npolys*2, navBvtree);
|
||||
createBVTree(params->verts, params->vertCount, params->polys, params->polyCount,
|
||||
nvp, params->cs, params->ch, params->polyCount*2, navBvtree);
|
||||
|
||||
// Store Off-Mesh links.
|
||||
for (int i = 0; i < nomlinks; ++i)
|
||||
// Store Off-Mesh connections.
|
||||
for (int i = 0; i < params->offMeshConCount; ++i)
|
||||
{
|
||||
dtOffMeshLink* link = &offMeshLinks[i];
|
||||
link->p = npolys + i;
|
||||
dtOffMeshConnection* con = &offMeshCons[i];
|
||||
con->poly = offMeshPolyBase + i;
|
||||
// Copy connection end-points.
|
||||
const float* endPts = ¶ms->offMeshConVerts[i*2*3];
|
||||
vcopy(&con->pos[0], &endPts[0]);
|
||||
vcopy(&con->pos[3], &endPts[3]);
|
||||
con->rad = params->offMeshConRad[i];
|
||||
con->flags = params->offMeshConDir[i];
|
||||
}
|
||||
|
||||
*outData = data;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -281,14 +281,13 @@
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
|
||||
<array>
|
||||
<array>
|
||||
<integer>14</integer>
|
||||
<integer>12</integer>
|
||||
<integer>60</integer>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</array>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
|
||||
<string>{{0, 98}, {282, 643}}</string>
|
||||
<string>{{0, 584}, {282, 643}}</string>
|
||||
</dict>
|
||||
<key>PBXTopSmartGroupGIDs</key>
|
||||
<array/>
|
||||
@ -323,7 +322,7 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>6B8632A30F78115100E2684A</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>DetourNavMesh.cpp</string>
|
||||
<string>InputGeom.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
@ -331,15 +330,14 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>6B8632A40F78115100E2684A</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>DetourNavMesh.cpp</string>
|
||||
<string>InputGeom.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>6BE7322310FE72B300C1B074</string>
|
||||
<string>6BCF348D1105F58E009445BF</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>6B57D358108C66B200DDD053</string>
|
||||
<string>6B7FB74D1091EBDE001BA51A</string>
|
||||
<string>6B8DE70D10B01BBF00DF20FB</string>
|
||||
<string>6B8DE76D10B0243500DF20FB</string>
|
||||
<string>6B8DE84910B0584400DF20FB</string>
|
||||
@ -357,35 +355,38 @@
|
||||
<string>6BB7FDC110F37703006DA0A6</string>
|
||||
<string>6BB7FE1010F37CF7006DA0A6</string>
|
||||
<string>6BB7FE3B10F3817A006DA0A6</string>
|
||||
<string>6BB7FEA910F4B5E1006DA0A6</string>
|
||||
<string>6BB7FEAD10F4B5E1006DA0A6</string>
|
||||
<string>6BB7FEDE10F4B779006DA0A6</string>
|
||||
<string>6BB7FF0310F4D699006DA0A6</string>
|
||||
<string>6BB7FF6D10F4E8E2006DA0A6</string>
|
||||
<string>6BB7FF6E10F4E8E2006DA0A6</string>
|
||||
<string>6BB7FF7310F4E8E2006DA0A6</string>
|
||||
<string>6BB7FFBE10F4E9A8006DA0A6</string>
|
||||
<string>6BB7FFD610F4EC73006DA0A6</string>
|
||||
<string>6BB7000610F4F03D006DA0A6</string>
|
||||
<string>6BB7002C10F4F257006DA0A6</string>
|
||||
<string>6BB7003710F4F39B006DA0A6</string>
|
||||
<string>6BB7003810F4F39B006DA0A6</string>
|
||||
<string>6BB7007210FA2B13006DA0A6</string>
|
||||
<string>6BB700BF10FA3AB1006DA0A6</string>
|
||||
<string>6BB35FED10FBD09300A9B4B8</string>
|
||||
<string>6BB3601610FE561F00A9B4B8</string>
|
||||
<string>6BB3601710FE561F00A9B4B8</string>
|
||||
<string>6BB3603D10FE59E200A9B4B8</string>
|
||||
<string>6BB3605210FE5CBD00A9B4B8</string>
|
||||
<string>6BB3605310FE5CBD00A9B4B8</string>
|
||||
<string>6BB3605410FE5CBD00A9B4B8</string>
|
||||
<string>6BB3606210FE5E8F00A9B4B8</string>
|
||||
<string>6BE7320210FE6CEF00C1B074</string>
|
||||
<string>6BE7320C10FE6EBE00C1B074</string>
|
||||
<string>6BE7321210FE70FE00C1B074</string>
|
||||
<string>6BE7321D10FE72B300C1B074</string>
|
||||
<string>6BE7321E10FE72B300C1B074</string>
|
||||
<string>6BE7321F10FE72B300C1B074</string>
|
||||
<string>6B69736710FFBDCA00984788</string>
|
||||
<string>6B69736810FFBDCA00984788</string>
|
||||
<string>6B69739F10FFCA4500984788</string>
|
||||
<string>6BCF325E1104CFE7009445BF</string>
|
||||
<string>6BCF325F1104CFE7009445BF</string>
|
||||
<string>6BCF331811059E23009445BF</string>
|
||||
<string>6BCF331911059E23009445BF</string>
|
||||
<string>6BCF331A11059E23009445BF</string>
|
||||
<string>6BCF332411059EA9009445BF</string>
|
||||
<string>6BCF33351105B2B5009445BF</string>
|
||||
<string>6BCF33651105BBA2009445BF</string>
|
||||
<string>6BCF33671105BBA2009445BF</string>
|
||||
<string>6BCF336A1105BBA2009445BF</string>
|
||||
<string>6BCF33AF1105BE51009445BF</string>
|
||||
<string>6BCF33E21105E5BB009445BF</string>
|
||||
<string>6BCF34031105E98C009445BF</string>
|
||||
<string>6BCF34041105E98C009445BF</string>
|
||||
<string>6BCF341A1105EC43009445BF</string>
|
||||
<string>6BCF34211105EC43009445BF</string>
|
||||
<string>6BCF343A1105ECAB009445BF</string>
|
||||
<string>6BCF343B1105ECAB009445BF</string>
|
||||
<string>6BCF34441105ECEB009445BF</string>
|
||||
<string>6BCF34691105EF2D009445BF</string>
|
||||
<string>6BCF34731105F503009445BF</string>
|
||||
<string>6BCF347A1105F519009445BF</string>
|
||||
<string>6BCF347B1105F519009445BF</string>
|
||||
<string>6BCF34821105F555009445BF</string>
|
||||
<string>6BCF34831105F555009445BF</string>
|
||||
<string>6BCF34841105F555009445BF</string>
|
||||
</array>
|
||||
<key>prevStack</key>
|
||||
<array>
|
||||
@ -407,29 +408,193 @@
|
||||
<string>6BB7FE2210F37CF7006DA0A6</string>
|
||||
<string>6BB7FE2310F37CF7006DA0A6</string>
|
||||
<string>6BB7FE5410F3817A006DA0A6</string>
|
||||
<string>6BB7FE7810F38224006DA0A6</string>
|
||||
<string>6BB7FEB810F4B5E1006DA0A6</string>
|
||||
<string>6BB7FEB910F4B5E1006DA0A6</string>
|
||||
<string>6BB7FECF10F4B5E1006DA0A6</string>
|
||||
<string>6BB7FF1210F4D699006DA0A6</string>
|
||||
<string>6BB7FF2410F4D699006DA0A6</string>
|
||||
<string>6BB7FF7910F4E8E2006DA0A6</string>
|
||||
<string>6BB7FF8910F4E8E2006DA0A6</string>
|
||||
<string>6BB7FF9610F4E8E2006DA0A6</string>
|
||||
<string>6BB7FF9710F4E8E2006DA0A6</string>
|
||||
<string>6BB7007510FA2B13006DA0A6</string>
|
||||
<string>6BB7008C10FA3475006DA0A6</string>
|
||||
<string>6BB7008E10FA3475006DA0A6</string>
|
||||
<string>6BB700C310FA3AB1006DA0A6</string>
|
||||
<string>6BE7320010FE6BDC00C1B074</string>
|
||||
<string>6BE7320610FE6CEF00C1B074</string>
|
||||
<string>6BE7320E10FE6EBE00C1B074</string>
|
||||
<string>6BE7320F10FE6EBE00C1B074</string>
|
||||
<string>6BE7321410FE70FE00C1B074</string>
|
||||
<string>6BE7321810FE712A00C1B074</string>
|
||||
<string>6BE7322010FE72B300C1B074</string>
|
||||
<string>6BE7322110FE72B300C1B074</string>
|
||||
<string>6BE7322210FE72B300C1B074</string>
|
||||
<string>6B69737210FFBDCA00984788</string>
|
||||
<string>6B69739810FFC43600984788</string>
|
||||
<string>6B6973A210FFCA4500984788</string>
|
||||
<string>6BCF31FD1104C9F0009445BF</string>
|
||||
<string>6BCF31FE1104C9F0009445BF</string>
|
||||
<string>6BCF31FF1104C9F0009445BF</string>
|
||||
<string>6BCF32001104C9F0009445BF</string>
|
||||
<string>6BCF32011104C9F0009445BF</string>
|
||||
<string>6BCF32021104C9F0009445BF</string>
|
||||
<string>6BCF32031104C9F0009445BF</string>
|
||||
<string>6BCF32041104C9F0009445BF</string>
|
||||
<string>6BCF32051104C9F0009445BF</string>
|
||||
<string>6BCF32061104C9F0009445BF</string>
|
||||
<string>6BCF32071104C9F0009445BF</string>
|
||||
<string>6BCF32081104C9F0009445BF</string>
|
||||
<string>6BCF32091104C9F0009445BF</string>
|
||||
<string>6BCF320A1104C9F0009445BF</string>
|
||||
<string>6BCF320B1104C9F0009445BF</string>
|
||||
<string>6BCF320C1104C9F0009445BF</string>
|
||||
<string>6BCF320D1104C9F0009445BF</string>
|
||||
<string>6BCF320E1104C9F0009445BF</string>
|
||||
<string>6BCF32111104C9F0009445BF</string>
|
||||
<string>6BCF32121104C9F0009445BF</string>
|
||||
<string>6BCF32151104C9F0009445BF</string>
|
||||
<string>6BCF322E1104CA22009445BF</string>
|
||||
<string>6BCF322F1104CA22009445BF</string>
|
||||
<string>6BCF32441104CDB5009445BF</string>
|
||||
<string>6BCF32451104CDB5009445BF</string>
|
||||
<string>6BCF32461104CDB5009445BF</string>
|
||||
<string>6BCF32471104CDB5009445BF</string>
|
||||
<string>6BCF32481104CDB5009445BF</string>
|
||||
<string>6BCF32491104CDB5009445BF</string>
|
||||
<string>6BCF324A1104CDB5009445BF</string>
|
||||
<string>6BCF324C1104CDB5009445BF</string>
|
||||
<string>6BCF324E1104CDB5009445BF</string>
|
||||
<string>6BCF324F1104CDB5009445BF</string>
|
||||
<string>6BCF32501104CDB5009445BF</string>
|
||||
<string>6BCF32511104CDB5009445BF</string>
|
||||
<string>6BCF32521104CDB5009445BF</string>
|
||||
<string>6BCF32681104CFE7009445BF</string>
|
||||
<string>6BCF32691104CFE7009445BF</string>
|
||||
<string>6BCF326A1104CFE7009445BF</string>
|
||||
<string>6BCF326B1104CFE7009445BF</string>
|
||||
<string>6BCF326C1104CFE7009445BF</string>
|
||||
<string>6BCF326D1104CFE7009445BF</string>
|
||||
<string>6BCF326E1104CFE7009445BF</string>
|
||||
<string>6BCF326F1104CFE7009445BF</string>
|
||||
<string>6BCF32701104CFE7009445BF</string>
|
||||
<string>6BCF32711104CFE7009445BF</string>
|
||||
<string>6BCF32721104CFE7009445BF</string>
|
||||
<string>6BCF32731104CFE7009445BF</string>
|
||||
<string>6BCF32741104CFE7009445BF</string>
|
||||
<string>6BCF32751104CFE7009445BF</string>
|
||||
<string>6BCF32761104CFE7009445BF</string>
|
||||
<string>6BCF32771104CFE7009445BF</string>
|
||||
<string>6BCF32781104CFE7009445BF</string>
|
||||
<string>6BCF32791104CFE7009445BF</string>
|
||||
<string>6BCF327A1104CFE7009445BF</string>
|
||||
<string>6BCF32861104D114009445BF</string>
|
||||
<string>6BCF32871104D114009445BF</string>
|
||||
<string>6BCF32881104D114009445BF</string>
|
||||
<string>6BCF32891104D114009445BF</string>
|
||||
<string>6BCF32A31104D31E009445BF</string>
|
||||
<string>6BCF32A51104D31E009445BF</string>
|
||||
<string>6BCF32A61104D31E009445BF</string>
|
||||
<string>6BCF32B41104D3E5009445BF</string>
|
||||
<string>6BCF32C51104D678009445BF</string>
|
||||
<string>6BCF32ED1104D7F5009445BF</string>
|
||||
<string>6BCF32EE1104D7F5009445BF</string>
|
||||
<string>6BCF32F51104D815009445BF</string>
|
||||
<string>6BCF33021104D891009445BF</string>
|
||||
<string>6BCF33041104D891009445BF</string>
|
||||
<string>6BCF33061104D891009445BF</string>
|
||||
<string>6BCF331611059D39009445BF</string>
|
||||
<string>6BCF331C11059E23009445BF</string>
|
||||
<string>6BCF331D11059E23009445BF</string>
|
||||
<string>6BCF331E11059E23009445BF</string>
|
||||
<string>6BCF331F11059E23009445BF</string>
|
||||
<string>6BCF332611059EA9009445BF</string>
|
||||
<string>6BCF332C1105A59B009445BF</string>
|
||||
<string>6BCF33381105B2B5009445BF</string>
|
||||
<string>6BCF33541105B986009445BF</string>
|
||||
<string>6BCF33551105B986009445BF</string>
|
||||
<string>6BCF33561105B986009445BF</string>
|
||||
<string>6BCF33571105B986009445BF</string>
|
||||
<string>6BCF33581105B986009445BF</string>
|
||||
<string>6BCF33591105B986009445BF</string>
|
||||
<string>6BCF335A1105B986009445BF</string>
|
||||
<string>6BCF336E1105BBA2009445BF</string>
|
||||
<string>6BCF336F1105BBA2009445BF</string>
|
||||
<string>6BCF33701105BBA2009445BF</string>
|
||||
<string>6BCF33711105BBA2009445BF</string>
|
||||
<string>6BCF33721105BBA2009445BF</string>
|
||||
<string>6BCF33731105BBA2009445BF</string>
|
||||
<string>6BCF33741105BBA2009445BF</string>
|
||||
<string>6BCF33751105BBA2009445BF</string>
|
||||
<string>6BCF33761105BBA2009445BF</string>
|
||||
<string>6BCF33781105BBA2009445BF</string>
|
||||
<string>6BCF337A1105BBA2009445BF</string>
|
||||
<string>6BCF337C1105BBA2009445BF</string>
|
||||
<string>6BCF337D1105BBA2009445BF</string>
|
||||
<string>6BCF337E1105BBA2009445BF</string>
|
||||
<string>6BCF337F1105BBA2009445BF</string>
|
||||
<string>6BCF33801105BBA2009445BF</string>
|
||||
<string>6BCF33811105BBA2009445BF</string>
|
||||
<string>6BCF33881105BBC8009445BF</string>
|
||||
<string>6BCF338E1105BCB7009445BF</string>
|
||||
<string>6BCF338F1105BCB7009445BF</string>
|
||||
<string>6BCF339A1105BD0E009445BF</string>
|
||||
<string>6BCF339B1105BD0E009445BF</string>
|
||||
<string>6BCF339C1105BD0E009445BF</string>
|
||||
<string>6BCF339D1105BD0E009445BF</string>
|
||||
<string>6BCF339E1105BD0E009445BF</string>
|
||||
<string>6BCF339F1105BD0E009445BF</string>
|
||||
<string>6BCF33A41105BD41009445BF</string>
|
||||
<string>6BCF33A91105BDAD009445BF</string>
|
||||
<string>6BCF33B21105BE51009445BF</string>
|
||||
<string>6BCF33B31105BE51009445BF</string>
|
||||
<string>6BCF33B41105BE51009445BF</string>
|
||||
<string>6BCF33B51105BE51009445BF</string>
|
||||
<string>6BCF33B61105BE51009445BF</string>
|
||||
<string>6BCF33BD1105BEE9009445BF</string>
|
||||
<string>6BCF33CA1105C466009445BF</string>
|
||||
<string>6BCF33D31105C5EF009445BF</string>
|
||||
<string>6BCF33E41105E5BB009445BF</string>
|
||||
<string>6BCF33E51105E5BB009445BF</string>
|
||||
<string>6BCF33E61105E5BB009445BF</string>
|
||||
<string>6BCF33E71105E5BB009445BF</string>
|
||||
<string>6BCF33E81105E5BB009445BF</string>
|
||||
<string>6BCF33E91105E5BB009445BF</string>
|
||||
<string>6BCF33EA1105E5BB009445BF</string>
|
||||
<string>6BCF33EB1105E5BB009445BF</string>
|
||||
<string>6BCF33EC1105E5BB009445BF</string>
|
||||
<string>6BCF33ED1105E5BB009445BF</string>
|
||||
<string>6BCF33F21105E621009445BF</string>
|
||||
<string>6BCF33F91105E71B009445BF</string>
|
||||
<string>6BCF33FA1105E71B009445BF</string>
|
||||
<string>6BCF340B1105E98C009445BF</string>
|
||||
<string>6BCF340C1105E98C009445BF</string>
|
||||
<string>6BCF340D1105E98C009445BF</string>
|
||||
<string>6BCF340E1105E98C009445BF</string>
|
||||
<string>6BCF340F1105E98C009445BF</string>
|
||||
<string>6BCF34101105E98C009445BF</string>
|
||||
<string>6BCF34111105E98C009445BF</string>
|
||||
<string>6BCF34121105E98C009445BF</string>
|
||||
<string>6BCF34131105E98C009445BF</string>
|
||||
<string>6BCF34141105E98C009445BF</string>
|
||||
<string>6BCF34231105EC43009445BF</string>
|
||||
<string>6BCF34241105EC43009445BF</string>
|
||||
<string>6BCF34251105EC43009445BF</string>
|
||||
<string>6BCF34261105EC43009445BF</string>
|
||||
<string>6BCF34271105EC43009445BF</string>
|
||||
<string>6BCF34281105EC43009445BF</string>
|
||||
<string>6BCF34291105EC43009445BF</string>
|
||||
<string>6BCF342A1105EC43009445BF</string>
|
||||
<string>6BCF342B1105EC43009445BF</string>
|
||||
<string>6BCF342C1105EC43009445BF</string>
|
||||
<string>6BCF342D1105EC43009445BF</string>
|
||||
<string>6BCF342E1105EC43009445BF</string>
|
||||
<string>6BCF342F1105EC43009445BF</string>
|
||||
<string>6BCF34301105EC43009445BF</string>
|
||||
<string>6BCF34311105EC43009445BF</string>
|
||||
<string>6BCF34321105EC43009445BF</string>
|
||||
<string>6BCF34331105EC43009445BF</string>
|
||||
<string>6BCF34341105EC43009445BF</string>
|
||||
<string>6BCF343D1105ECAB009445BF</string>
|
||||
<string>6BCF343E1105ECAB009445BF</string>
|
||||
<string>6BCF343F1105ECAB009445BF</string>
|
||||
<string>6BCF34401105ECAB009445BF</string>
|
||||
<string>6BCF34461105ECEB009445BF</string>
|
||||
<string>6BCF344A1105ED03009445BF</string>
|
||||
<string>6BCF34591105EE81009445BF</string>
|
||||
<string>6BCF345F1105EEA7009445BF</string>
|
||||
<string>6BCF346C1105EF2D009445BF</string>
|
||||
<string>6BCF34751105F503009445BF</string>
|
||||
<string>6BCF34761105F503009445BF</string>
|
||||
<string>6BCF34771105F503009445BF</string>
|
||||
<string>6BCF347D1105F519009445BF</string>
|
||||
<string>6BCF347E1105F519009445BF</string>
|
||||
<string>6BCF34851105F555009445BF</string>
|
||||
<string>6BCF34861105F555009445BF</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
@ -443,18 +608,18 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {952, 572}}</string>
|
||||
<string>{{0, 0}, {952, 501}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>11 76 1256 702 0 0 1280 778 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXNavigatorGroup</string>
|
||||
<key>Proportion</key>
|
||||
<string>572pt</string>
|
||||
<string>501pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Proportion</key>
|
||||
<string>84pt</string>
|
||||
<string>155pt</string>
|
||||
<key>Tabs</key>
|
||||
<array>
|
||||
<dict>
|
||||
@ -468,7 +633,7 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {952, 57}}</string>
|
||||
<string>{{10, 27}, {952, 90}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
@ -484,7 +649,7 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {952, 63}}</string>
|
||||
<string>{{10, 27}, {952, 212}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXProjectFindModule</string>
|
||||
@ -522,7 +687,7 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {952, 57}}</string>
|
||||
<string>{{10, 27}, {952, 128}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>11 76 1256 702 0 0 1280 778 </string>
|
||||
</dict>
|
||||
@ -552,11 +717,11 @@
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>6BE731E710FE67F500C1B074</string>
|
||||
<string>6BCF32211104C9F0009445BF</string>
|
||||
<string>1CA23ED40692098700951B8B</string>
|
||||
<string>6BE731E810FE67F500C1B074</string>
|
||||
<string>6BCF32221104C9F0009445BF</string>
|
||||
<string>6B8632A30F78115100E2684A</string>
|
||||
<string>6BE731E910FE67F500C1B074</string>
|
||||
<string>6BCF32231104C9F0009445BF</string>
|
||||
<string>1CA23EDF0692099D00951B8B</string>
|
||||
<string>1CA23EE00692099D00951B8B</string>
|
||||
<string>1CA23EE10692099D00951B8B</string>
|
||||
@ -705,14 +870,14 @@
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>6BE731EA10FE67F500C1B074</string>
|
||||
<string>6BCF32241104C9F0009445BF</string>
|
||||
<string>1CCC7628064C1048000F2A68</string>
|
||||
<string>1CCC7629064C1048000F2A68</string>
|
||||
<string>6BE731EB10FE67F500C1B074</string>
|
||||
<string>6BE731EC10FE67F500C1B074</string>
|
||||
<string>6BE731ED10FE67F500C1B074</string>
|
||||
<string>6BE731EE10FE67F500C1B074</string>
|
||||
<string>6BE731EF10FE67F500C1B074</string>
|
||||
<string>6BCF32251104C9F0009445BF</string>
|
||||
<string>6BCF32261104C9F0009445BF</string>
|
||||
<string>6BCF32271104C9F0009445BF</string>
|
||||
<string>6BCF32281104C9F0009445BF</string>
|
||||
<string>6BCF32291104C9F0009445BF</string>
|
||||
</array>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
@ -744,6 +909,8 @@
|
||||
<integer>5</integer>
|
||||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>6BCF32991104D1B2009445BF</string>
|
||||
<string>6BCF329A1104D1B2009445BF</string>
|
||||
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
|
@ -36,11 +36,11 @@
|
||||
6BB788170FC0472B003C24DB /* ChunkyTriMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB788160FC0472B003C24DB /* ChunkyTriMesh.cpp */; };
|
||||
6BB7FC0B10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB7FC0A10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp */; };
|
||||
6BB7FDA510F36F0E006DA0A6 /* InputGeom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB7FDA410F36F0E006DA0A6 /* InputGeom.cpp */; };
|
||||
6BB7FE9110F4A192006DA0A6 /* OffMeshLinkTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB7FE9010F4A192006DA0A6 /* OffMeshLinkTool.cpp */; };
|
||||
6BB93C7D10CFE1D500F74F2B /* DebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93C7A10CFE1D500F74F2B /* DebugDraw.cpp */; };
|
||||
6BB93C7E10CFE1D500F74F2B /* DetourDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93C7B10CFE1D500F74F2B /* DetourDebugDraw.cpp */; };
|
||||
6BB93C7F10CFE1D500F74F2B /* RecastDebugDraw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93C7C10CFE1D500F74F2B /* RecastDebugDraw.cpp */; };
|
||||
6BB93CF610CFEC4500F74F2B /* RecastDump.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB93CF510CFEC4500F74F2B /* RecastDump.cpp */; };
|
||||
6BCF32361104CD05009445BF /* OffMeshConnectionTool.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BCF32351104CD05009445BF /* OffMeshConnectionTool.cpp */; };
|
||||
8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
|
||||
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
@ -100,8 +100,6 @@
|
||||
6BB7FC0A10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NavMeshTesterTool.cpp; path = ../../Source/NavMeshTesterTool.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BB7FDA310F36EFC006DA0A6 /* InputGeom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InputGeom.h; path = ../../Include/InputGeom.h; sourceTree = SOURCE_ROOT; };
|
||||
6BB7FDA410F36F0E006DA0A6 /* InputGeom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = InputGeom.cpp; path = ../../Source/InputGeom.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BB7FE8F10F4A192006DA0A6 /* OffMeshLinkTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OffMeshLinkTool.h; path = ../../Include/OffMeshLinkTool.h; sourceTree = SOURCE_ROOT; };
|
||||
6BB7FE9010F4A192006DA0A6 /* OffMeshLinkTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OffMeshLinkTool.cpp; path = ../../Source/OffMeshLinkTool.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BB93C7710CFE1D500F74F2B /* DebugDraw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DebugDraw.h; path = ../../../DebugUtils/Include/DebugDraw.h; sourceTree = SOURCE_ROOT; };
|
||||
6BB93C7810CFE1D500F74F2B /* DetourDebugDraw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DetourDebugDraw.h; path = ../../../DebugUtils/Include/DetourDebugDraw.h; sourceTree = SOURCE_ROOT; };
|
||||
6BB93C7910CFE1D500F74F2B /* RecastDebugDraw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecastDebugDraw.h; path = ../../../DebugUtils/Include/RecastDebugDraw.h; sourceTree = SOURCE_ROOT; };
|
||||
@ -110,6 +108,8 @@
|
||||
6BB93C7C10CFE1D500F74F2B /* RecastDebugDraw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastDebugDraw.cpp; path = ../../../DebugUtils/Source/RecastDebugDraw.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BB93CF410CFEC4500F74F2B /* RecastDump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecastDump.h; path = ../../../DebugUtils/Include/RecastDump.h; sourceTree = SOURCE_ROOT; };
|
||||
6BB93CF510CFEC4500F74F2B /* RecastDump.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastDump.cpp; path = ../../../DebugUtils/Source/RecastDump.cpp; sourceTree = SOURCE_ROOT; };
|
||||
6BCF32341104CD05009445BF /* OffMeshConnectionTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OffMeshConnectionTool.h; path = ../../Include/OffMeshConnectionTool.h; sourceTree = SOURCE_ROOT; };
|
||||
6BCF32351104CD05009445BF /* OffMeshConnectionTool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OffMeshConnectionTool.cpp; path = ../../Source/OffMeshConnectionTool.cpp; sourceTree = SOURCE_ROOT; };
|
||||
8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
8D1107320486CEB800E47090 /* Recast.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Recast.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
@ -259,8 +259,8 @@
|
||||
6BB7FE8E10F4A175006DA0A6 /* Tools */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6BB7FE8F10F4A192006DA0A6 /* OffMeshLinkTool.h */,
|
||||
6BB7FE9010F4A192006DA0A6 /* OffMeshLinkTool.cpp */,
|
||||
6BCF32341104CD05009445BF /* OffMeshConnectionTool.h */,
|
||||
6BCF32351104CD05009445BF /* OffMeshConnectionTool.cpp */,
|
||||
6BB7FC0910EBB6AA006DA0A6 /* NavMeshTesterTool.h */,
|
||||
6BB7FC0A10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp */,
|
||||
);
|
||||
@ -382,7 +382,7 @@
|
||||
6BB93CF610CFEC4500F74F2B /* RecastDump.cpp in Sources */,
|
||||
6BB7FC0B10EBB6AA006DA0A6 /* NavMeshTesterTool.cpp in Sources */,
|
||||
6BB7FDA510F36F0E006DA0A6 /* InputGeom.cpp in Sources */,
|
||||
6BB7FE9110F4A192006DA0A6 /* OffMeshLinkTool.cpp in Sources */,
|
||||
6BCF32361104CD05009445BF /* OffMeshConnectionTool.cpp in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -28,10 +28,12 @@ class InputGeom
|
||||
rcMeshLoaderObj* m_mesh;
|
||||
float m_meshBMin[3], m_meshBMax[3];
|
||||
|
||||
static const int MAX_LINKS = 256;
|
||||
static const int MAX_OFFMESH_CONNECTIONS = 256;
|
||||
|
||||
float m_linkVerts[MAX_LINKS*3*2];
|
||||
int m_nlinks;
|
||||
float m_offMeshConVerts[MAX_OFFMESH_CONNECTIONS*3*2];
|
||||
float m_offMeshConRads[MAX_OFFMESH_CONNECTIONS];
|
||||
unsigned char m_offMeshConDirs[MAX_OFFMESH_CONNECTIONS];
|
||||
int m_offMeshConCount;
|
||||
|
||||
public:
|
||||
InputGeom();
|
||||
@ -47,11 +49,13 @@ public:
|
||||
bool raycastMesh(float* src, float* dst, float& tmin);
|
||||
|
||||
// Extra links
|
||||
int getOffMeshLinkCount() const { return m_nlinks; }
|
||||
const float* getOffMeshLinkVertices() const { return m_linkVerts; }
|
||||
void addOffMeshLink(const float* spos, const float* epos);
|
||||
void deleteOffMeshLink(int i);
|
||||
void drawLinks(struct duDebugDraw* dd, const float s);
|
||||
int getOffMeshConnectionCount() const { return m_offMeshConCount; }
|
||||
const float* getOffMeshConnectionVerts() const { return m_offMeshConVerts; }
|
||||
const float* getOffMeshConnectionRads() const { return m_offMeshConRads; }
|
||||
const unsigned char* getOffMeshConnectionDirs() const { return m_offMeshConDirs; }
|
||||
void addOffMeshConnection(const float* spos, const float* epos, const float rad, unsigned char bidir);
|
||||
void deleteOffMeshConnection(int i);
|
||||
void drawOffMeshConnections(struct duDebugDraw* dd, bool hilight = false);
|
||||
};
|
||||
|
||||
#endif // INPUTGEOM_H
|
||||
|
@ -29,6 +29,7 @@ class NavMeshTesterTool : public SampleTool
|
||||
dtNavMesh* m_navMesh;
|
||||
float m_agentRadius;
|
||||
float m_agentHeight;
|
||||
float m_agentClimb;
|
||||
|
||||
enum ToolMode
|
||||
{
|
||||
|
@ -16,24 +16,25 @@
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef OFFMESHLINKTOOL_H
|
||||
#define OFFMESHLINKTOOL_H
|
||||
#ifndef OFFMESHCONNECTIONTOOL_H
|
||||
#define OFFMESHCONNECTIONTOOL_H
|
||||
|
||||
#include "Sample.h"
|
||||
|
||||
// Tool to create extra links for InputGeom
|
||||
|
||||
class OffMeshLinkTool : public SampleTool
|
||||
class OffMeshConnectionTool : public SampleTool
|
||||
{
|
||||
Sample* m_sample;
|
||||
float m_hitPos[3];
|
||||
bool m_hitPosSet;
|
||||
bool m_bidir;
|
||||
|
||||
public:
|
||||
OffMeshLinkTool();
|
||||
~OffMeshLinkTool();
|
||||
OffMeshConnectionTool();
|
||||
~OffMeshConnectionTool();
|
||||
|
||||
virtual int type() { return TOOL_OFFMESH_LINK; }
|
||||
virtual int type() { return TOOL_OFFMESH_CONNECTION; }
|
||||
virtual void init(Sample* sample);
|
||||
virtual void reset();
|
||||
virtual void handleMenu();
|
||||
@ -42,4 +43,4 @@ public:
|
||||
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
||||
};
|
||||
|
||||
#endif // OFFMESHLINKTOOL_H
|
||||
#endif // OFFMESHCONNECTIONTOOL_H
|
@ -24,6 +24,7 @@
|
||||
|
||||
struct DebugDrawGL : public duDebugDraw
|
||||
{
|
||||
virtual void depthMask(bool state);
|
||||
virtual void begin(duDebugDrawPrimitives prim, float size = 1.0f);
|
||||
virtual void vertex(const float* pos, unsigned int color);
|
||||
virtual void vertex(const float x, const float y, const float z, unsigned int color);
|
||||
@ -35,7 +36,7 @@ enum SampleToolType
|
||||
TOOL_NONE = 0,
|
||||
TOOL_TILE_EDIT,
|
||||
TOOL_NAVMESH_TESTER,
|
||||
TOOL_OFFMESH_LINK,
|
||||
TOOL_OFFMESH_CONNECTION,
|
||||
};
|
||||
|
||||
struct SampleTool
|
||||
@ -56,6 +57,7 @@ class Sample
|
||||
protected:
|
||||
class InputGeom* m_geom;
|
||||
dtNavMesh* m_navMesh;
|
||||
unsigned char m_navMeshDrawFlags;
|
||||
|
||||
float m_cellSize;
|
||||
float m_cellHeight;
|
||||
@ -92,6 +94,10 @@ public:
|
||||
virtual class dtNavMesh* getNavMesh() { return m_navMesh; }
|
||||
virtual float getAgentRadius() { return m_agentRadius; }
|
||||
virtual float getAgentHeight() { return m_agentHeight; }
|
||||
virtual float getAgentClimb() { return m_agentMaxClimb; }
|
||||
|
||||
inline unsigned char getNavMeshDrawFlags() const { return m_navMeshDrawFlags; }
|
||||
inline void setNavMeshDrawFlags(unsigned char flags) { m_navMeshDrawFlags = flags; }
|
||||
|
||||
void resetCommonSettings();
|
||||
void handleCommonSettings();
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "MeshLoaderObj.h"
|
||||
#include "DebugDraw.h"
|
||||
#include "RecastDebugDraw.h"
|
||||
|
||||
#include "DetourNavMesh.h"
|
||||
|
||||
static bool intersectSegmentTriangle(const float* sp, const float* sq,
|
||||
const float* a, const float* b, const float* c,
|
||||
@ -72,7 +72,7 @@ static bool intersectSegmentTriangle(const float* sp, const float* sq,
|
||||
InputGeom::InputGeom() :
|
||||
m_chunkyMesh(0),
|
||||
m_mesh(0),
|
||||
m_nlinks(0)
|
||||
m_offMeshConCount(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -90,8 +90,8 @@ bool InputGeom::loadMesh(const char* filepath)
|
||||
m_chunkyMesh = 0;
|
||||
delete m_mesh;
|
||||
m_mesh = 0;
|
||||
m_nlinks = 0;
|
||||
}
|
||||
m_offMeshConCount = 0;
|
||||
|
||||
m_mesh = new rcMeshLoaderObj;
|
||||
if (!m_mesh)
|
||||
@ -159,31 +159,52 @@ bool InputGeom::raycastMesh(float* src, float* dst, float& tmin)
|
||||
return hit;
|
||||
}
|
||||
|
||||
void InputGeom::addOffMeshLink(const float* spos, const float* epos)
|
||||
void InputGeom::addOffMeshConnection(const float* spos, const float* epos, const float rad, unsigned char bidir)
|
||||
{
|
||||
if (m_nlinks >= MAX_LINKS) return;
|
||||
float* v = &m_linkVerts[m_nlinks*3*2];
|
||||
m_nlinks++;
|
||||
if (m_offMeshConCount >= MAX_OFFMESH_CONNECTIONS) return;
|
||||
float* v = &m_offMeshConVerts[m_offMeshConCount*3*2];
|
||||
m_offMeshConRads[m_offMeshConCount] = rad;
|
||||
m_offMeshConDirs[m_offMeshConCount] = bidir;
|
||||
vcopy(&v[0], spos);
|
||||
vcopy(&v[3], epos);
|
||||
m_offMeshConCount++;
|
||||
}
|
||||
|
||||
void InputGeom::deleteOffMeshLink(int i)
|
||||
void InputGeom::deleteOffMeshConnection(int i)
|
||||
{
|
||||
m_nlinks--;
|
||||
float* src = &m_linkVerts[(m_nlinks-1)*3*2];
|
||||
float* dst = &m_linkVerts[i*3*2];
|
||||
m_offMeshConCount--;
|
||||
float* src = &m_offMeshConVerts[m_offMeshConCount*3*2];
|
||||
float* dst = &m_offMeshConVerts[i*3*2];
|
||||
vcopy(&dst[0], &src[0]);
|
||||
vcopy(&dst[3], &src[3]);
|
||||
m_offMeshConRads[i] = m_offMeshConRads[m_offMeshConCount];
|
||||
m_offMeshConDirs[i] = m_offMeshConDirs[m_offMeshConCount];
|
||||
}
|
||||
|
||||
void InputGeom::drawLinks(duDebugDraw* dd, const float s)
|
||||
void InputGeom::drawOffMeshConnections(duDebugDraw* dd, bool hilight)
|
||||
{
|
||||
for (int i = 0; i < m_nlinks; ++i)
|
||||
unsigned int conColor = duRGBA(192,192,192,hilight?192:64);
|
||||
unsigned int baseColor = duRGBA(0,0,0,hilight?192:64);
|
||||
dd->depthMask(false);
|
||||
|
||||
dd->begin(DU_DRAW_LINES, 2.0f);
|
||||
for (int i = 0; i < m_offMeshConCount; ++i)
|
||||
{
|
||||
float* v = &m_linkVerts[i*3*2];
|
||||
duDebugDrawArc(dd, v[0],v[1],v[2], v[3],v[4],v[5], 0.25f, duRGBA(255,255,255,192), 1.0f);
|
||||
duDebugDrawCross(dd, v[0],v[1]+0.1f,v[2], s, duRGBA(0,0,0,255), 2.0f);
|
||||
duDebugDrawCross(dd, v[3],v[4]+0.1f,v[5], s, duRGBA(0,0,0,255), 2.0f);
|
||||
float* v = &m_offMeshConVerts[i*3*2];
|
||||
|
||||
dd->vertex(v[0],v[1],v[2], baseColor);
|
||||
dd->vertex(v[0],v[1]+0.2f,v[2], baseColor);
|
||||
|
||||
dd->vertex(v[3],v[4],v[5], baseColor);
|
||||
dd->vertex(v[3],v[4]+0.2f,v[5], baseColor);
|
||||
|
||||
duAppendCircle(dd, v[0],v[1]+0.1f,v[2], m_offMeshConRads[i], baseColor);
|
||||
duAppendCircle(dd, v[3],v[4]+0.1f,v[5], m_offMeshConRads[i], baseColor);
|
||||
|
||||
duAppendArc(dd, v[0],v[1],v[2], v[3],v[4],v[5], 0.25f,
|
||||
(m_offMeshConDirs[i]&1) ? 0.6f : 0.0f, 0.6f, conColor);
|
||||
}
|
||||
dd->end();
|
||||
|
||||
dd->depthMask(true);
|
||||
}
|
||||
|
@ -66,6 +66,13 @@ NavMeshTesterTool::NavMeshTesterTool() :
|
||||
|
||||
NavMeshTesterTool::~NavMeshTesterTool()
|
||||
{
|
||||
if (m_sample)
|
||||
{
|
||||
unsigned char flags = DU_DRAWNAVMESH_CLOSEDLIST;
|
||||
if (m_navMesh)
|
||||
flags |= DU_DRAWNAVMESH_OFFMESHCONS;
|
||||
m_sample->setNavMeshDrawFlags(flags);
|
||||
}
|
||||
}
|
||||
|
||||
void NavMeshTesterTool::init(Sample* sample)
|
||||
@ -73,8 +80,18 @@ void NavMeshTesterTool::init(Sample* sample)
|
||||
m_sample = sample;
|
||||
m_agentRadius = sample->getAgentRadius();
|
||||
m_agentHeight = sample->getAgentHeight();
|
||||
m_agentClimb = sample->getAgentClimb();
|
||||
m_navMesh = sample->getNavMesh();
|
||||
recalc();
|
||||
|
||||
if (m_toolMode == TOOLMODE_PATHFIND)
|
||||
{
|
||||
unsigned char flags = DU_DRAWNAVMESH_CLOSEDLIST;
|
||||
if (m_navMesh)
|
||||
flags |= DU_DRAWNAVMESH_OFFMESHCONS;
|
||||
m_sample->setNavMeshDrawFlags(flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NavMeshTesterTool::handleMenu()
|
||||
@ -99,6 +116,21 @@ void NavMeshTesterTool::handleMenu()
|
||||
m_toolMode = TOOLMODE_FIND_POLYS_AROUND;
|
||||
recalc();
|
||||
}
|
||||
|
||||
if (m_toolMode == TOOLMODE_PATHFIND)
|
||||
{
|
||||
unsigned char flags = DU_DRAWNAVMESH_CLOSEDLIST;
|
||||
if (m_navMesh)
|
||||
flags |= DU_DRAWNAVMESH_OFFMESHCONS;
|
||||
m_sample->setNavMeshDrawFlags(flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char flags = 0;
|
||||
if (m_navMesh)
|
||||
flags |= DU_DRAWNAVMESH_OFFMESHCONS;
|
||||
m_sample->setNavMeshDrawFlags(flags);
|
||||
}
|
||||
}
|
||||
|
||||
void NavMeshTesterTool::handleClick(const float* p, bool shift)
|
||||
@ -148,7 +180,7 @@ static bool getSteerTarget(dtNavMesh* navMesh, const float* startPos, const floa
|
||||
while (ns < nsteerPath)
|
||||
{
|
||||
// Stop at Off-Mesh link or when point is further than slop away.
|
||||
if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_LINK) ||
|
||||
if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ||
|
||||
!inRange(&steerPath[ns*3], startPos, minTargetDist, 1000.0f))
|
||||
break;
|
||||
ns++;
|
||||
@ -171,12 +203,12 @@ void NavMeshTesterTool::recalc()
|
||||
return;
|
||||
|
||||
if (m_sposSet)
|
||||
m_startRef = m_navMesh->findNearestPoly(m_spos, m_polyPickExt);
|
||||
m_startRef = m_navMesh->findNearestPoly(m_spos, m_polyPickExt, 0);
|
||||
else
|
||||
m_startRef = 0;
|
||||
|
||||
if (m_eposSet)
|
||||
m_endRef = m_navMesh->findNearestPoly(m_epos, m_polyPickExt);
|
||||
m_endRef = m_navMesh->findNearestPoly(m_epos, m_polyPickExt, 0);
|
||||
else
|
||||
m_endRef = 0;
|
||||
|
||||
@ -225,14 +257,14 @@ void NavMeshTesterTool::recalc()
|
||||
break;
|
||||
|
||||
bool endOfPath = steerPosFlag & DT_STRAIGHTPATH_END;
|
||||
bool offMeshLink = steerPosFlag & DT_STRAIGHTPATH_OFFMESH_LINK;
|
||||
bool offMeshConnection = steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION;
|
||||
|
||||
// Find movement delta.
|
||||
float delta[3], len;
|
||||
vsub(delta, steerPos, iterPos);
|
||||
len = sqrtf(vdot(delta,delta));
|
||||
// If the steer target is end of path or off-mesh link, do not move past the location.
|
||||
if ((endOfPath || offMeshLink) && len < STEP_SIZE)
|
||||
if ((endOfPath || offMeshConnection) && len < STEP_SIZE)
|
||||
len = 1;
|
||||
else
|
||||
len = STEP_SIZE / len;
|
||||
@ -266,12 +298,12 @@ void NavMeshTesterTool::recalc()
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (offMeshLink && inRange(iterPos, steerPos, SLOP, 1.0f))
|
||||
else if (offMeshConnection && inRange(iterPos, steerPos, SLOP, 1.0f))
|
||||
{
|
||||
// Reached off-mesh link.
|
||||
// Reached off-mesh connection.
|
||||
float startPos[3], endPos[3];
|
||||
|
||||
// Advance the path up to and over the off-mesh link.
|
||||
// Advance the path up to and over the off-mesh connection.
|
||||
dtPolyRef prevRef = 0, polyRef = polys[0];
|
||||
while (npolys && polyRef != steerPosRef)
|
||||
{
|
||||
@ -281,16 +313,25 @@ void NavMeshTesterTool::recalc()
|
||||
npolys--;
|
||||
}
|
||||
|
||||
// Handle the link.
|
||||
if (m_navMesh->getOffMeshLinkPolyEndPoints(prevRef, polyRef, startPos, endPos))
|
||||
// Handle the connection.
|
||||
if (m_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, startPos, endPos))
|
||||
{
|
||||
if (m_nsmoothPath < MAX_SMOOTH)
|
||||
{
|
||||
vcopy(&m_smoothPath[m_nsmoothPath*3], startPos);
|
||||
m_nsmoothPath++;
|
||||
// Hack to make the dotted path not visible during off-mesh connection.
|
||||
if (m_nsmoothPath & 1)
|
||||
{
|
||||
vcopy(&m_smoothPath[m_nsmoothPath*3], startPos);
|
||||
m_nsmoothPath++;
|
||||
}
|
||||
}
|
||||
// Move position at the other side of the off-mesh link.
|
||||
vcopy(iterPos, endPos);
|
||||
float h;
|
||||
m_navMesh->getPolyHeight(polys[0], iterPos, &h);
|
||||
iterPos[1] = h;
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,14 +400,14 @@ static void getPolyCenter(dtNavMesh* navMesh, dtPolyRef ref, float* center)
|
||||
center[0] = 0;
|
||||
center[1] = 0;
|
||||
center[2] = 0;
|
||||
for (int i = 0; i < (int)p->nv; ++i)
|
||||
for (int i = 0; i < (int)p->vertCount; ++i)
|
||||
{
|
||||
const float* v = &verts[p->v[i]*3];
|
||||
const float* v = &verts[p->verts[i]*3];
|
||||
center[0] += v[0];
|
||||
center[1] += v[1];
|
||||
center[2] += v[2];
|
||||
}
|
||||
const float s = 1.0f / p->nv;
|
||||
const float s = 1.0f / p->vertCount;
|
||||
center[0] *= s;
|
||||
center[1] *= s;
|
||||
center[2] *= s;
|
||||
@ -390,14 +431,6 @@ void NavMeshTesterTool::handleRender()
|
||||
if (m_eposSet)
|
||||
drawAgent(m_epos, m_agentRadius, m_agentHeight, 0/*m_agentMaxClimb*/, endCol);
|
||||
|
||||
/* if (flags & NAVMESH_POLYS)
|
||||
duDebugDrawNavMesh(&dd, m_navMesh, m_toolMode == TOOLMODE_PATHFIND);
|
||||
|
||||
if (flags & NAVMESH_BVTREE)
|
||||
duDebugDrawNavMeshBVTree(&dd, m_navMesh);
|
||||
|
||||
if (flags & NAVMESH_TOOLS)*/
|
||||
{
|
||||
if (m_toolMode == TOOLMODE_PATHFIND)
|
||||
{
|
||||
duDebugDrawNavMeshPoly(&dd, m_navMesh, m_startRef, startCol);
|
||||
@ -417,7 +450,7 @@ void NavMeshTesterTool::handleRender()
|
||||
for (int i = 0; i < m_nstraightPath-1; ++i)
|
||||
{
|
||||
unsigned int col = 0;
|
||||
if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_LINK)
|
||||
if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)
|
||||
col = offMeshCol;
|
||||
else
|
||||
col = pathCol;
|
||||
@ -434,7 +467,7 @@ void NavMeshTesterTool::handleRender()
|
||||
col = startCol;
|
||||
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_START)
|
||||
col = endCol;
|
||||
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_LINK)
|
||||
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)
|
||||
col = offMeshCol;
|
||||
else
|
||||
col = pathCol;
|
||||
@ -504,16 +537,22 @@ void NavMeshTesterTool::handleRender()
|
||||
if (m_parent[i])
|
||||
{
|
||||
float p0[3], p1[3];
|
||||
getPolyCenter(m_navMesh, m_polys[i], p0);
|
||||
getPolyCenter(m_navMesh, m_parent[i], p1);
|
||||
duDebugDrawArc(&dd, p0[0],p0[1],p0[2], p1[0],p1[1],p1[2], 0.25f, duRGBA(0,0,0,128), 2.0f);
|
||||
dd.depthMask(false);
|
||||
getPolyCenter(m_navMesh, m_parent[i], p0);
|
||||
getPolyCenter(m_navMesh, m_polys[i], p1);
|
||||
duDebugDrawArc(&dd, p0[0],p0[1],p0[2], p1[0],p1[1],p1[2], 0.25f, 0.0f, 0.4f, duRGBA(0,0,0,128), 2.0f);
|
||||
dd.depthMask(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_sposSet && m_eposSet)
|
||||
{
|
||||
dd.depthMask(false);
|
||||
const float dx = m_epos[0] - m_spos[0];
|
||||
const float dz = m_epos[2] - m_spos[2];
|
||||
const float dist = sqrtf(dx*dx + dz*dz);
|
||||
duDebugDrawCircle(&dd, m_spos[0], m_spos[1]+m_agentHeight/2, m_spos[2], dist, duRGBA(64,16,0,220), 2.0f);
|
||||
dd.depthMask(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "imgui.h"
|
||||
#include "OffMeshLinkTool.h"
|
||||
#include "OffMeshConnectionTool.h"
|
||||
#include "InputGeom.h"
|
||||
#include "Sample.h"
|
||||
#include "Recast.h"
|
||||
@ -35,39 +35,47 @@
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
OffMeshLinkTool::OffMeshLinkTool() :
|
||||
OffMeshConnectionTool::OffMeshConnectionTool() :
|
||||
m_sample(0),
|
||||
m_hitPosSet(0)
|
||||
m_hitPosSet(0),
|
||||
m_bidir(true)
|
||||
{
|
||||
}
|
||||
|
||||
OffMeshLinkTool::~OffMeshLinkTool()
|
||||
OffMeshConnectionTool::~OffMeshConnectionTool()
|
||||
{
|
||||
}
|
||||
|
||||
void OffMeshLinkTool::init(Sample* sample)
|
||||
void OffMeshConnectionTool::init(Sample* sample)
|
||||
{
|
||||
m_sample = sample;
|
||||
if (m_sample)
|
||||
m_sample->setNavMeshDrawFlags(0);
|
||||
}
|
||||
|
||||
void OffMeshLinkTool::reset()
|
||||
void OffMeshConnectionTool::reset()
|
||||
{
|
||||
m_hitPosSet = false;
|
||||
}
|
||||
|
||||
void OffMeshLinkTool::handleMenu()
|
||||
void OffMeshConnectionTool::handleMenu()
|
||||
{
|
||||
if (m_hitPosSet)
|
||||
if (imguiCheck("One Way", !m_bidir))
|
||||
m_bidir = false;
|
||||
if (imguiCheck("Bidirectional", m_bidir))
|
||||
m_bidir = true;
|
||||
|
||||
if (!m_hitPosSet)
|
||||
{
|
||||
imguiValue("Click to set link start.");
|
||||
imguiValue("Click to set connection start.");
|
||||
}
|
||||
else
|
||||
{
|
||||
imguiValue("Click to set link end.");
|
||||
imguiValue("Click to set connection end.");
|
||||
}
|
||||
}
|
||||
|
||||
void OffMeshLinkTool::handleClick(const float* p, bool shift)
|
||||
void OffMeshConnectionTool::handleClick(const float* p, bool shift)
|
||||
{
|
||||
if (!m_sample) return;
|
||||
InputGeom* geom = m_sample->getInputGeom();
|
||||
@ -79,8 +87,8 @@ void OffMeshLinkTool::handleClick(const float* p, bool shift)
|
||||
// Find nearest link end-point
|
||||
float nearestDist = FLT_MAX;
|
||||
int nearestIndex = -1;
|
||||
const float* verts = geom->getOffMeshLinkVertices();
|
||||
for (int i = 0; i < geom->getOffMeshLinkCount()*2; ++i)
|
||||
const float* verts = geom->getOffMeshConnectionVerts();
|
||||
for (int i = 0; i < geom->getOffMeshConnectionCount()*2; ++i)
|
||||
{
|
||||
const float* v = &verts[i*3];
|
||||
float d = vdistSqr(p, v);
|
||||
@ -94,7 +102,7 @@ void OffMeshLinkTool::handleClick(const float* p, bool shift)
|
||||
if (nearestIndex != -1 &&
|
||||
sqrtf(nearestDist) < m_sample->getAgentRadius())
|
||||
{
|
||||
geom->deleteOffMeshLink(nearestIndex);
|
||||
geom->deleteOffMeshConnection(nearestIndex);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -107,14 +115,14 @@ void OffMeshLinkTool::handleClick(const float* p, bool shift)
|
||||
}
|
||||
else
|
||||
{
|
||||
geom->addOffMeshLink(m_hitPos, p);
|
||||
geom->addOffMeshConnection(m_hitPos, p, m_sample->getAgentRadius(), m_bidir ? 1 : 0);
|
||||
m_hitPosSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void OffMeshLinkTool::handleRender()
|
||||
void OffMeshConnectionTool::handleRender()
|
||||
{
|
||||
DebugDrawGL dd;
|
||||
const float s = m_sample->getAgentRadius();
|
||||
@ -124,10 +132,10 @@ void OffMeshLinkTool::handleRender()
|
||||
|
||||
InputGeom* geom = m_sample->getInputGeom();
|
||||
if (geom)
|
||||
geom->drawLinks(&dd, s);
|
||||
geom->drawOffMeshConnections(&dd, true);
|
||||
}
|
||||
|
||||
void OffMeshLinkTool::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
void OffMeshConnectionTool::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
{
|
||||
GLdouble x, y, z;
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "InputGeom.h"
|
||||
#include "Recast.h"
|
||||
#include "RecastDebugDraw.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "imgui.h"
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
@ -32,6 +33,11 @@
|
||||
#endif
|
||||
|
||||
|
||||
void DebugDrawGL::depthMask(bool state)
|
||||
{
|
||||
glDepthMask(state ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void DebugDrawGL::begin(duDebugDrawPrimitives prim, float size)
|
||||
{
|
||||
switch (prim)
|
||||
@ -76,6 +82,7 @@ void DebugDrawGL::end()
|
||||
Sample::Sample() :
|
||||
m_geom(0),
|
||||
m_navMesh(0),
|
||||
m_navMeshDrawFlags(DU_DRAWNAVMESH_CLOSEDLIST),
|
||||
m_tool(0)
|
||||
{
|
||||
resetCommonSettings();
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "DetourNavMeshBuilder.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "NavMeshTesterTool.h"
|
||||
#include "OffMeshLinkTool.h"
|
||||
#include "OffMeshConnectionTool.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
@ -95,9 +95,9 @@ void Sample_SoloMeshSimple::handleTools()
|
||||
{
|
||||
setTool(new NavMeshTesterTool);
|
||||
}
|
||||
if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_LINK))
|
||||
if (imguiCheck("Create Off-Mesh Connections", type == TOOL_OFFMESH_CONNECTION))
|
||||
{
|
||||
setTool(new OffMeshLinkTool);
|
||||
setTool(new OffMeshConnectionTool);
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
@ -197,14 +197,16 @@ void Sample_SoloMeshSimple::handleRender()
|
||||
duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
|
||||
m_agentMaxSlope);
|
||||
m_geom->drawLinks(&dd, m_agentRadius);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
}
|
||||
else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
|
||||
{
|
||||
// Draw mesh
|
||||
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
|
||||
m_geom->drawLinks(&dd, m_agentRadius);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
}
|
||||
|
||||
glDisable(GL_FOG);
|
||||
@ -222,7 +224,7 @@ void Sample_SoloMeshSimple::handleRender()
|
||||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
|
||||
{
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
|
||||
duDebugDrawNavMesh(&dd, m_navMesh); //, m_toolMode == TOOLMODE_PATHFIND);
|
||||
duDebugDrawNavMesh(&dd, m_navMesh, m_navMeshDrawFlags);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
|
||||
duDebugDrawNavMeshBVTree(&dd, m_navMesh);
|
||||
}
|
||||
@ -550,13 +552,32 @@ bool Sample_SoloMeshSimple::handleBuild()
|
||||
{
|
||||
unsigned char* navData = 0;
|
||||
int navDataSize = 0;
|
||||
if (!dtCreateNavMeshData(m_pmesh->verts, m_pmesh->nverts,
|
||||
m_pmesh->polys, m_pmesh->npolys, m_pmesh->nvp,
|
||||
m_dmesh->meshes, m_dmesh->verts, m_dmesh->nverts,
|
||||
m_dmesh->tris, m_dmesh->ntris,
|
||||
m_geom->getOffMeshLinkVertices(), m_geom->getOffMeshLinkCount(),
|
||||
m_pmesh->bmin, m_pmesh->bmax, m_cfg.cs, m_cfg.ch, 0, m_cfg.walkableClimb,
|
||||
&navData, &navDataSize))
|
||||
|
||||
dtNavMeshCreateParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.verts = m_pmesh->verts;
|
||||
params.vertCount = m_pmesh->nverts;
|
||||
params.polys = m_pmesh->polys;
|
||||
params.polyCount = m_pmesh->npolys;
|
||||
params.nvp = m_pmesh->nvp;
|
||||
params.detailMeshes = m_dmesh->meshes;
|
||||
params.detailVerts = m_dmesh->verts;
|
||||
params.detailVertsCount = m_dmesh->nverts;
|
||||
params.detailTris = m_dmesh->tris;
|
||||
params.detailTriCount = m_dmesh->ntris;
|
||||
params.offMeshConVerts = m_geom->getOffMeshConnectionVerts();
|
||||
params.offMeshConRad = m_geom->getOffMeshConnectionRads();
|
||||
params.offMeshConDir = m_geom->getOffMeshConnectionDirs();
|
||||
params.offMeshConCount = m_geom->getOffMeshConnectionCount();
|
||||
params.walkableHeight = m_agentHeight;
|
||||
params.walkableRadius = m_agentRadius;
|
||||
params.walkableClimb = m_agentMaxClimb;
|
||||
vcopy(params.bmin, m_pmesh->bmin);
|
||||
vcopy(params.bmax, m_pmesh->bmax);
|
||||
params.cs = m_cfg.cs;
|
||||
params.ch = m_cfg.ch;
|
||||
|
||||
if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize))
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
|
||||
@ -618,6 +639,8 @@ bool Sample_SoloMeshSimple::handleBuild()
|
||||
rcGetLog()->log(RC_LOG_PROGRESS, "TOTAL: %.1fms", rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f);
|
||||
}
|
||||
|
||||
setNavMeshDrawFlags(DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->init(this);
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "DetourNavMeshBuilder.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "NavMeshTesterTool.h"
|
||||
#include "OffMeshLinkTool.h"
|
||||
#include "OffMeshConnectionTool.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
@ -110,9 +110,9 @@ void Sample_SoloMeshTiled::handleTools()
|
||||
{
|
||||
setTool(new NavMeshTesterTool);
|
||||
}
|
||||
if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_LINK))
|
||||
if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_CONNECTION))
|
||||
{
|
||||
setTool(new OffMeshLinkTool);
|
||||
setTool(new OffMeshConnectionTool);
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
@ -231,14 +231,16 @@ void Sample_SoloMeshTiled::handleRender()
|
||||
duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
|
||||
m_agentMaxSlope);
|
||||
m_geom->drawLinks(&dd, m_agentRadius);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
}
|
||||
else if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
|
||||
{
|
||||
// Draw mesh
|
||||
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
|
||||
m_geom->drawLinks(&dd, m_agentRadius);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
}
|
||||
|
||||
glDisable(GL_FOG);
|
||||
@ -264,7 +266,7 @@ void Sample_SoloMeshTiled::handleRender()
|
||||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
|
||||
{
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
|
||||
duDebugDrawNavMesh(&dd, m_navMesh); //, m_toolMode == TOOLMODE_PATHFIND);
|
||||
duDebugDrawNavMesh(&dd, m_navMesh, m_navMeshDrawFlags);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
|
||||
duDebugDrawNavMeshBVTree(&dd, m_navMesh);
|
||||
}
|
||||
@ -922,13 +924,32 @@ bool Sample_SoloMeshTiled::handleBuild()
|
||||
{
|
||||
unsigned char* navData = 0;
|
||||
int navDataSize = 0;
|
||||
if (!dtCreateNavMeshData(m_pmesh->verts, m_pmesh->nverts,
|
||||
m_pmesh->polys, m_pmesh->npolys, m_pmesh->nvp,
|
||||
m_dmesh->meshes, m_dmesh->verts, m_dmesh->nverts,
|
||||
m_dmesh->tris, m_dmesh->ntris,
|
||||
0, 0,
|
||||
m_pmesh->bmin, m_pmesh->bmax, m_cfg.cs, m_cfg.ch, 0, m_cfg.walkableClimb,
|
||||
&navData, &navDataSize))
|
||||
|
||||
dtNavMeshCreateParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.verts = m_pmesh->verts;
|
||||
params.vertCount = m_pmesh->nverts;
|
||||
params.polys = m_pmesh->polys;
|
||||
params.polyCount = m_pmesh->npolys;
|
||||
params.nvp = m_pmesh->nvp;
|
||||
params.detailMeshes = m_dmesh->meshes;
|
||||
params.detailVerts = m_dmesh->verts;
|
||||
params.detailVertsCount = m_dmesh->nverts;
|
||||
params.detailTris = m_dmesh->tris;
|
||||
params.detailTriCount = m_dmesh->ntris;
|
||||
params.offMeshConVerts = 0;
|
||||
params.offMeshConRad = 0;
|
||||
params.offMeshConDir = 0;
|
||||
params.offMeshConCount = 0;
|
||||
params.walkableHeight = m_agentHeight;
|
||||
params.walkableRadius = m_agentRadius;
|
||||
params.walkableClimb = m_agentMaxClimb;
|
||||
vcopy(params.bmin, m_pmesh->bmin);
|
||||
vcopy(params.bmax, m_pmesh->bmax);
|
||||
params.cs = m_cfg.cs;
|
||||
params.ch = m_cfg.ch;
|
||||
|
||||
if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize))
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
|
||||
@ -992,6 +1013,8 @@ bool Sample_SoloMeshTiled::handleBuild()
|
||||
rcGetLog()->log(RC_LOG_PROGRESS, "TOTAL: %.1fms", rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f);
|
||||
}
|
||||
|
||||
setNavMeshDrawFlags(DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->init(this);
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "DetourNavMeshBuilder.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "NavMeshTesterTool.h"
|
||||
#include "OffMeshLinkTool.h"
|
||||
#include "OffMeshConnectionTool.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
@ -253,9 +253,9 @@ void Sample_TileMesh::handleTools()
|
||||
{
|
||||
setTool(new NavMeshTileTool);
|
||||
}
|
||||
if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_LINK))
|
||||
if (imguiCheck("Create Off-Mesh Links", type == TOOL_OFFMESH_CONNECTION))
|
||||
{
|
||||
setTool(new OffMeshLinkTool);
|
||||
setTool(new OffMeshConnectionTool);
|
||||
}
|
||||
|
||||
imguiSeparator();
|
||||
@ -288,14 +288,14 @@ static void getPolyCenter(dtNavMesh* navMesh, dtPolyRef ref, float* center)
|
||||
center[0] = 0;
|
||||
center[1] = 0;
|
||||
center[2] = 0;
|
||||
for (int i = 0; i < (int)p->nv; ++i)
|
||||
for (int i = 0; i < (int)p->vertCount; ++i)
|
||||
{
|
||||
const float* v = &verts[p->v[i]*3];
|
||||
const float* v = &verts[p->verts[i]*3];
|
||||
center[0] += v[0];
|
||||
center[1] += v[1];
|
||||
center[2] += v[2];
|
||||
}
|
||||
const float s = 1.0f / p->nv;
|
||||
const float s = 1.0f / p->vertCount;
|
||||
center[0] *= s;
|
||||
center[1] *= s;
|
||||
center[2] *= s;
|
||||
@ -311,7 +311,8 @@ void Sample_TileMesh::handleRender()
|
||||
// Draw mesh
|
||||
duDebugDrawTriMesh(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(), 0);
|
||||
m_geom->drawLinks(&dd, m_agentRadius);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
@ -332,7 +333,7 @@ void Sample_TileMesh::handleRender()
|
||||
duDebugDrawBoxWire(&dd, m_tileBmin[0],m_tileBmin[1],m_tileBmin[2], m_tileBmax[0],m_tileBmax[1],m_tileBmax[2], m_tileCol, 2.0f);
|
||||
|
||||
if (m_navMesh)
|
||||
duDebugDrawNavMesh(&dd, m_navMesh);
|
||||
duDebugDrawNavMesh(&dd, m_navMesh, m_navMeshDrawFlags);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleRender();
|
||||
@ -392,9 +393,8 @@ bool Sample_TileMesh::handleBuild()
|
||||
const float* bmin = m_geom->getMeshBoundsMin();
|
||||
const float tileWorldWidth = m_tileSize*m_cellSize;
|
||||
const float tileWorldHeight = m_tileSize*m_cellSize;
|
||||
const float portalHeight = m_agentMaxClimb*m_cellHeight;
|
||||
|
||||
if (!m_navMesh->init(bmin, tileWorldWidth, tileWorldHeight, portalHeight, m_maxTiles, m_maxPolysPerTile, 2048))
|
||||
if (!m_navMesh->init(bmin, tileWorldWidth, tileWorldHeight, m_maxTiles, m_maxPolysPerTile, 2048))
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not init navmesh.");
|
||||
@ -404,6 +404,8 @@ bool Sample_TileMesh::handleBuild()
|
||||
if (m_buildAll)
|
||||
buildAllTiles();
|
||||
|
||||
setNavMeshDrawFlags(DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->init(this);
|
||||
|
||||
@ -782,12 +784,32 @@ unsigned char* Sample_TileMesh::buildTileMesh(const float* bmin, const float* bm
|
||||
return false;
|
||||
}*/
|
||||
|
||||
if (!dtCreateNavMeshData(m_pmesh->verts, m_pmesh->nverts,
|
||||
m_pmesh->polys, m_pmesh->npolys, m_pmesh->nvp,
|
||||
m_dmesh->meshes, m_dmesh->verts, m_dmesh->nverts, m_dmesh->tris, m_dmesh->ntris,
|
||||
0, 0,
|
||||
bmin, bmax, m_cfg.cs, m_cfg.ch, m_cfg.tileSize, m_cfg.walkableClimb,
|
||||
&navData, &navDataSize))
|
||||
dtNavMeshCreateParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.verts = m_pmesh->verts;
|
||||
params.vertCount = m_pmesh->nverts;
|
||||
params.polys = m_pmesh->polys;
|
||||
params.polyCount = m_pmesh->npolys;
|
||||
params.nvp = m_pmesh->nvp;
|
||||
params.detailMeshes = m_dmesh->meshes;
|
||||
params.detailVerts = m_dmesh->verts;
|
||||
params.detailVertsCount = m_dmesh->nverts;
|
||||
params.detailTris = m_dmesh->tris;
|
||||
params.detailTriCount = m_dmesh->ntris;
|
||||
params.offMeshConVerts = 0;
|
||||
params.offMeshConRad = 0;
|
||||
params.offMeshConDir = 0;
|
||||
params.offMeshConCount = 0;
|
||||
params.walkableHeight = m_agentHeight;
|
||||
params.walkableRadius = m_agentRadius;
|
||||
params.walkableClimb = m_agentMaxClimb;
|
||||
vcopy(params.bmin, bmin);
|
||||
vcopy(params.bmax, bmax);
|
||||
params.cs = m_cfg.cs;
|
||||
params.ch = m_cfg.ch;
|
||||
params.tileSize = m_cfg.tileSize;
|
||||
|
||||
if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize))
|
||||
{
|
||||
if (rcGetLog())
|
||||
rcGetLog()->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
|
||||
|
Loading…
x
Reference in New Issue
Block a user