Off-Mesh connections across tile boundaries. Fixed getPolysAround(). Detour links per poly use linked list. Adjusted off-mesh connection tool.
This commit is contained in:
parent
e973b71d4b
commit
a56bf3ec2d
@ -62,9 +62,9 @@ static void drawPolyBoundaries(duDebugDraw* dd, const dtMeshHeader* header,
|
||||
if (p->neis[j] & DT_EXT_LINK)
|
||||
{
|
||||
bool con = false;
|
||||
for (int k = 0; k < p->linkCount; ++k)
|
||||
for (unsigned int k = p->firstLink; k != DT_NULL_LINK; k = header->links[k].next)
|
||||
{
|
||||
if (header->links[p->linkBase+k].edge == j)
|
||||
if (header->links[k].edge == j)
|
||||
{
|
||||
con = true;
|
||||
break;
|
||||
@ -175,15 +175,26 @@ static void drawMeshTile(duDebugDraw* dd, const dtNavMesh* mesh, const dtMeshTil
|
||||
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];
|
||||
|
||||
// Check to see if start and end end-points have links.
|
||||
bool startSet = false;
|
||||
bool endSet = false;
|
||||
for (unsigned int k = p->firstLink; k != DT_NULL_LINK; k = header->links[k].next)
|
||||
{
|
||||
if (header->links[k].edge == 0)
|
||||
startSet = true;
|
||||
if (header->links[k].edge == 1)
|
||||
endSet = true;
|
||||
}
|
||||
|
||||
// End points and their on-mesh locations.
|
||||
if (con->ref[0])
|
||||
if (startSet)
|
||||
{
|
||||
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])
|
||||
if (endSet)
|
||||
{
|
||||
dd->vertex(vb[0],vb[1],vb[2], col);
|
||||
dd->vertex(con->pos[3],con->pos[4],con->pos[5], col);
|
||||
|
@ -29,6 +29,7 @@ static const int DT_NAVMESH_MAGIC = 'DNAV';
|
||||
static const int DT_NAVMESH_VERSION = 2;
|
||||
|
||||
static const unsigned short DT_EXT_LINK = 0x8000;
|
||||
static const unsigned int DT_NULL_LINK = 0xffffffff;
|
||||
|
||||
// Flags returned by findStraightPath().
|
||||
enum dtStraightPathFlags
|
||||
@ -55,11 +56,10 @@ struct dtQueryFilter
|
||||
// Structure describing the navigation polygon data.
|
||||
struct dtPoly
|
||||
{
|
||||
unsigned int firstLink; // Index to first link in linked list.
|
||||
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 short flags; // Flags (see dtPolyFlags).
|
||||
unsigned char linkCount; // Number of links for
|
||||
unsigned char vertCount; // Number of vertices.
|
||||
};
|
||||
|
||||
@ -76,7 +76,7 @@ struct dtPolyDetail
|
||||
struct dtLink
|
||||
{
|
||||
dtPolyRef ref; // Neighbour reference.
|
||||
unsigned short poly; // Index to polygon which owns this link.
|
||||
unsigned int next; // Index to next 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.
|
||||
@ -92,9 +92,9 @@ struct dtOffMeshConnection
|
||||
{
|
||||
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
|
||||
unsigned char side; // End point side.
|
||||
};
|
||||
|
||||
struct dtMeshHeader
|
||||
@ -104,7 +104,6 @@ struct dtMeshHeader
|
||||
|
||||
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.
|
||||
@ -112,9 +111,10 @@ struct dtMeshHeader
|
||||
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;
|
||||
unsigned int linksFreeList; // Index to next free link.
|
||||
float walkableHeight; // Height of the agent.
|
||||
float walkableRadius; // Radius of the agent
|
||||
float walkableClimb; // Max climb height of the agent.
|
||||
float bmin[3], bmax[3]; // Bounding box of the tile.
|
||||
float bvQuantFactor; // BVtree quantization factor (world to bvnode coords)
|
||||
dtPoly* polys; // Pointer to the polygons (will be updated when tile is added).
|
||||
@ -358,19 +358,31 @@ public:
|
||||
bool isInClosedList(dtPolyRef ref) const;
|
||||
|
||||
// Encodes a tile id.
|
||||
inline dtPolyRef dtEncodePolyId(unsigned int salt, unsigned int it, unsigned int ip) const
|
||||
inline dtPolyRef encodePolyId(unsigned int salt, unsigned int it, unsigned int ip) const
|
||||
{
|
||||
return (salt << (m_polyBits+m_tileBits)) | ((it+1) << m_polyBits) | ip;
|
||||
}
|
||||
|
||||
// Decodes a tile id.
|
||||
inline void dtDecodePolyId(dtPolyRef ref, unsigned int& salt, unsigned int& it, unsigned int& ip) const
|
||||
inline void decodePolyId(dtPolyRef ref, unsigned int& salt, unsigned int& it, unsigned int& ip) const
|
||||
{
|
||||
salt = (ref >> (m_polyBits+m_tileBits)) & ((1<<m_saltBits)-1);
|
||||
it = ((ref >> m_polyBits) - 1) & ((1<<m_tileBits)-1);
|
||||
ip = ref & ((1<<m_polyBits)-1);
|
||||
}
|
||||
|
||||
// Decodes a tile id.
|
||||
inline unsigned int decodePolyIdTile(dtPolyRef ref) const
|
||||
{
|
||||
return ((ref >> m_polyBits) - 1) & ((1<<m_tileBits)-1);
|
||||
}
|
||||
|
||||
// Decodes a tile id.
|
||||
inline unsigned int decodePolyIdPoly(dtPolyRef ref) const
|
||||
{
|
||||
return ref & ((1<<m_polyBits)-1);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Returns neighbour tile based on side.
|
||||
@ -379,15 +391,29 @@ private:
|
||||
int findConnectingPolys(const float* va, const float* vb,
|
||||
dtMeshTile* tile, int side,
|
||||
dtPolyRef* con, float* conarea, int maxcon);
|
||||
|
||||
// Builds internal polygons links for a tile.
|
||||
void buildIntLinks(dtMeshTile* tile);
|
||||
void connectIntLinks(dtMeshTile* tile);
|
||||
// Builds internal polygons links for a tile.
|
||||
void connectIntOffMeshLinks(dtMeshTile* tile);
|
||||
|
||||
// Builds external polygon links for a tile.
|
||||
void buildExtLinks(dtMeshTile* tile, dtMeshTile* target, int side);
|
||||
void connectExtLinks(dtMeshTile* tile, dtMeshTile* target, int side);
|
||||
// Builds external polygon links for a tile.
|
||||
void connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int side);
|
||||
|
||||
// Removes external links at specified side.
|
||||
void removeExtLinks(dtMeshTile* tile, int side);
|
||||
void unconnectExtLinks(dtMeshTile* tile, int side);
|
||||
|
||||
// Queries polygons within a tile.
|
||||
int queryTilePolygons(dtMeshTile* tile, const float* qmin, const float* qmax, dtQueryFilter* filter,
|
||||
dtPolyRef* polys, const int maxPolys);
|
||||
int queryPolygonsInTile(dtMeshTile* tile, const float* qmin, const float* qmax, dtQueryFilter* filter,
|
||||
dtPolyRef* polys, const int maxPolys);
|
||||
// Find nearest polygon within a tile.
|
||||
dtPolyRef findNearestPolyInTile(dtMeshTile* tile, const float* center, const float* extents,
|
||||
dtQueryFilter* filter, float* nearestPt);
|
||||
// Returns closest point on polygon.
|
||||
bool closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip, const float* pos, float* closest) const;
|
||||
|
||||
unsigned short getPolyFlags(dtPolyRef ref);
|
||||
float getCost(dtPolyRef prev, dtPolyRef from, dtPolyRef to) const;
|
||||
float getFirstCost(const float* pos, dtPolyRef from, dtPolyRef to) const;
|
||||
@ -409,11 +435,7 @@ private:
|
||||
dtMeshTile** m_posLookup; // Tile hash lookup.
|
||||
dtMeshTile* m_nextFree; // Freelist of tiles.
|
||||
dtMeshTile* m_tiles; // List of tiles.
|
||||
|
||||
// TODO: dont grow!
|
||||
dtLink* m_tmpLinks; // Temp array used to build links between tiles.
|
||||
int m_ntmpLinks; // Size of the temp link array.
|
||||
|
||||
|
||||
unsigned int m_saltBits; // Number of salt bits in the tile ID.
|
||||
unsigned int m_tileBits; // Number of tile bits in the tile ID.
|
||||
unsigned int m_polyBits; // Number of poly bits in the tile ID.
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "DetourCommon.h"
|
||||
|
||||
|
||||
inline int opposite(int side) { return (side+2) & 0x3; }
|
||||
inline int opposite(int side) { return (side+4) & 0x7; }
|
||||
|
||||
inline bool overlapBoxes(const float* amin, const float* amax,
|
||||
const float* bmin, const float* bmax)
|
||||
@ -50,14 +50,14 @@ static void calcRect(const float* va, const float* vb,
|
||||
float* bmin, float* bmax,
|
||||
int side, float padx, float pady)
|
||||
{
|
||||
if ((side&1) == 0)
|
||||
if (side == 0 || side == 4)
|
||||
{
|
||||
bmin[0] = min(va[2],vb[2]) + padx;
|
||||
bmin[1] = min(va[1],vb[1]) - pady;
|
||||
bmax[0] = max(va[2],vb[2]) - padx;
|
||||
bmax[1] = max(va[1],vb[1]) + pady;
|
||||
}
|
||||
else
|
||||
else if (side == 2 || side == 6)
|
||||
{
|
||||
bmin[0] = min(va[0],vb[0]) + padx;
|
||||
bmin[1] = min(va[1],vb[1]) - pady;
|
||||
@ -74,6 +74,22 @@ inline int computeTileHash(int x, int y, const int mask)
|
||||
return (int)(n & mask);
|
||||
}
|
||||
|
||||
inline unsigned int allocLink(dtMeshTile* tile)
|
||||
{
|
||||
if (tile->header->linksFreeList == DT_NULL_LINK)
|
||||
return DT_NULL_LINK;
|
||||
unsigned int link = tile->header->linksFreeList;
|
||||
tile->header->linksFreeList = tile->header->links[link].next;
|
||||
return link;
|
||||
}
|
||||
|
||||
inline void freeLink(dtMeshTile* tile, unsigned int link)
|
||||
{
|
||||
tile->header->links[link].next = tile->header->linksFreeList;
|
||||
tile->header->linksFreeList = link;
|
||||
}
|
||||
|
||||
|
||||
inline bool passFilter(dtQueryFilter* filter, unsigned short flags)
|
||||
{
|
||||
return (flags & filter->includeFlags) != 0 && (flags & filter->excludeFlags) == 0;
|
||||
@ -91,8 +107,6 @@ dtNavMesh::dtNavMesh() :
|
||||
m_posLookup(0),
|
||||
m_nextFree(0),
|
||||
m_tiles(0),
|
||||
m_tmpLinks(0),
|
||||
m_ntmpLinks(0),
|
||||
m_saltBits(0),
|
||||
m_tileBits(0),
|
||||
m_polyBits(0),
|
||||
@ -115,7 +129,6 @@ dtNavMesh::~dtNavMesh()
|
||||
m_tiles[i].dataSize = 0;
|
||||
}
|
||||
}
|
||||
delete [] m_tmpLinks;
|
||||
delete m_nodePool;
|
||||
delete m_openList;
|
||||
delete [] m_posLookup;
|
||||
@ -236,67 +249,49 @@ int dtNavMesh::findConnectingPolys(const float* va, const float* vb,
|
||||
return n;
|
||||
}
|
||||
|
||||
void dtNavMesh::removeExtLinks(dtMeshTile* tile, int side)
|
||||
void dtNavMesh::unconnectExtLinks(dtMeshTile* tile, int side)
|
||||
{
|
||||
if (!tile) return;
|
||||
dtMeshHeader* h = tile->header;
|
||||
|
||||
// Remove links pointing to 'side' and compact the links array.
|
||||
dtLink* pool = m_tmpLinks;
|
||||
int nlinks = 0;
|
||||
for (int i = 0; i < h->polyCount; ++i)
|
||||
dtMeshHeader* header = tile->header;
|
||||
|
||||
for (int i = 0; i < header->polyCount; ++i)
|
||||
{
|
||||
dtPoly* poly = &h->polys[i];
|
||||
int plinks = nlinks;
|
||||
int nplinks = 0;
|
||||
for (int j = 0; j < poly->linkCount; ++j)
|
||||
dtPoly* poly = &header->polys[i];
|
||||
unsigned int j = poly->firstLink;
|
||||
unsigned int pj = DT_NULL_LINK;
|
||||
while (j != DT_NULL_LINK)
|
||||
{
|
||||
dtLink* link = &h->links[poly->linkBase+j];
|
||||
if ((int)link->side != side)
|
||||
if (header->links[j].side == side)
|
||||
{
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* dst = &pool[nlinks++];
|
||||
memcpy(dst, link, sizeof(dtLink));
|
||||
nplinks++;
|
||||
}
|
||||
// Revove link.
|
||||
unsigned int nj = header->links[j].next;
|
||||
if (pj == DT_NULL_LINK)
|
||||
poly->firstLink = nj;
|
||||
else
|
||||
header->links[pj].next = nj;
|
||||
freeLink(tile, j);
|
||||
j = nj;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Advance
|
||||
pj = j;
|
||||
j = header->links[j].next;
|
||||
}
|
||||
}
|
||||
poly->linkBase = plinks;
|
||||
poly->linkCount = nplinks;
|
||||
}
|
||||
h->linkCount = nlinks;
|
||||
if (h->linkCount)
|
||||
memcpy(h->links, m_tmpLinks, sizeof(dtLink)*nlinks);
|
||||
}
|
||||
|
||||
void dtNavMesh::buildExtLinks(dtMeshTile* tile, dtMeshTile* target, int side)
|
||||
void dtNavMesh::connectExtLinks(dtMeshTile* tile, dtMeshTile* target, int side)
|
||||
{
|
||||
if (!tile) return;
|
||||
dtMeshHeader* h = tile->header;
|
||||
dtMeshHeader* header = tile->header;
|
||||
|
||||
// Remove links pointing to 'side' and compact the links array.
|
||||
dtLink* pool = m_tmpLinks;
|
||||
int nlinks = 0;
|
||||
for (int i = 0; i < h->polyCount; ++i)
|
||||
// Connect border links.
|
||||
for (int i = 0; i < header->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->linkCount; ++j)
|
||||
{
|
||||
dtLink* link = &h->links[poly->linkBase+j];
|
||||
if ((int)link->side != side)
|
||||
{
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* dst = &pool[nlinks++];
|
||||
memcpy(dst, link, sizeof(dtLink));
|
||||
nplinks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
dtPoly* poly = &header->polys[i];
|
||||
|
||||
// Create new links.
|
||||
unsigned short m = DT_EXT_LINK | (unsigned short)side;
|
||||
const int nv = poly->vertCount;
|
||||
@ -306,168 +301,216 @@ void dtNavMesh::buildExtLinks(dtMeshTile* tile, dtMeshTile* target, int side)
|
||||
if (poly->neis[j] != m) continue;
|
||||
|
||||
// Create new links
|
||||
const float* va = &h->verts[poly->verts[j]*3];
|
||||
const float* vb = &h->verts[poly->verts[(j+1) % nv]*3];
|
||||
const float* va = &header->verts[poly->verts[j]*3];
|
||||
const float* vb = &header->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->maxLinkCount)
|
||||
unsigned int idx = allocLink(tile);
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
dtLink* link = &pool[nlinks++];
|
||||
dtLink* link = &header->links[idx];
|
||||
link->ref = nei[k];
|
||||
link->poly = (unsigned short)i;
|
||||
link->edge = (unsigned char)j;
|
||||
link->side = (unsigned char)side;
|
||||
|
||||
link->next = poly->firstLink;
|
||||
poly->firstLink = idx;
|
||||
|
||||
// Compress portal limits to a byte value.
|
||||
if (side == 0 || side == 2)
|
||||
if (side == 0 || side == 4)
|
||||
{
|
||||
const float lmin = min(va[2], vb[2]);
|
||||
const float lmax = max(va[2], vb[2]);
|
||||
link->bmin = (unsigned char)(clamp((neia[k*2+0]-lmin)/(lmax-lmin), 0.0f, 1.0f)*255.0f);
|
||||
link->bmax = (unsigned char)(clamp((neia[k*2+1]-lmin)/(lmax-lmin), 0.0f, 1.0f)*255.0f);
|
||||
}
|
||||
else
|
||||
else if (side == 2 || side == 6)
|
||||
{
|
||||
const float lmin = min(va[0], vb[0]);
|
||||
const float lmax = max(va[0], vb[0]);
|
||||
link->bmin = (unsigned char)(clamp((neia[k*2+0]-lmin)/(lmax-lmin), 0.0f, 1.0f)*255.0f);
|
||||
link->bmax = (unsigned char)(clamp((neia[k*2+1]-lmin)/(lmax-lmin), 0.0f, 1.0f)*255.0f);
|
||||
}
|
||||
nplinks++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
poly->linkBase = plinks;
|
||||
poly->linkCount = nplinks;
|
||||
}
|
||||
h->linkCount = nlinks;
|
||||
if (h->linkCount)
|
||||
memcpy(h->links, m_tmpLinks, sizeof(dtLink)*nlinks);
|
||||
}
|
||||
|
||||
void dtNavMesh::buildIntLinks(dtMeshTile* tile)
|
||||
{
|
||||
if (!tile) return;
|
||||
dtMeshHeader* h = tile->header;
|
||||
|
||||
dtPolyRef base = getTileId(tile);
|
||||
dtLink* pool = h->links;
|
||||
int nlinks = 0;
|
||||
|
||||
unsigned int salt, it, ip, tileIdx;
|
||||
dtDecodePolyId(base, salt, tileIdx, ip);
|
||||
|
||||
// Find Off-mesh connection end points.
|
||||
for (int i = 0; i < h->offMeshConCount; ++i)
|
||||
{
|
||||
dtOffMeshConnection* con = &h->offMeshCons[i];
|
||||
dtPoly* poly = &h->polys[con->poly];
|
||||
dtQueryFilter defaultFilter;
|
||||
|
||||
con->ref[0] = 0;
|
||||
con->ref[1] = 0;
|
||||
|
||||
const float ext[3] = { con->rad, h->walkableClimb, con->rad };
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
// Find polygon to connect to.
|
||||
const float* p = &con->pos[j*3];
|
||||
float nearestPt[3];
|
||||
dtPolyRef ref = findNearestPoly(p, ext, &defaultFilter, 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;
|
||||
|
||||
// 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->polyCount; ++i)
|
||||
{
|
||||
dtPoly* poly = &h->polys[i];
|
||||
poly->linkBase = nlinks;
|
||||
poly->linkCount = 0;
|
||||
|
||||
if (poly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
// Find Off-Mesh link and fill in information.
|
||||
dtOffMeshConnection* con = &h->offMeshCons[i - h->offMeshBase];
|
||||
// Connect both ends.
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* link = &pool[nlinks++];
|
||||
link->ref = con->ref[j];
|
||||
link->poly = (unsigned short)i;
|
||||
link->edge = (unsigned char)j;
|
||||
link->side = 0xff;
|
||||
link->bmin = link->bmax = 0;
|
||||
poly->linkCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Polygon edges.
|
||||
for (int j = 0; j < poly->vertCount; ++j)
|
||||
{
|
||||
// Skip hard and non-internal edges.
|
||||
if (poly->neis[j] == 0 || (poly->neis[j] & DT_EXT_LINK)) continue;
|
||||
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* link = &pool[nlinks++];
|
||||
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->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->offMeshConCount; ++j)
|
||||
{
|
||||
const dtOffMeshConnection* con = &h->offMeshCons[j];
|
||||
// Test both end points.
|
||||
for (int k = 0; k < 2; ++k)
|
||||
{
|
||||
if (con->ref[k] == curRef)
|
||||
{
|
||||
if (nlinks < h->maxLinkCount)
|
||||
{
|
||||
dtLink* link = &pool[nlinks++];
|
||||
link->ref = base | (dtPolyRef)con->poly;
|
||||
link->poly = (unsigned short)i;
|
||||
link->edge = 0;
|
||||
link->side = 0xff;
|
||||
link->bmin = link->bmax = 0;
|
||||
poly->linkCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dtNavMesh::connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int side)
|
||||
{
|
||||
if (!tile) return;
|
||||
dtMeshHeader* header = tile->header;
|
||||
|
||||
// Connect off-mesh links.
|
||||
// We are interested on links which land from target tile to this tile.
|
||||
dtMeshHeader* targetHeader = target->header;
|
||||
const unsigned char oppositeSide = (unsigned char)opposite(side);
|
||||
dtQueryFilter defaultFilter;
|
||||
|
||||
for (int i = 0; i < targetHeader->offMeshConCount; ++i)
|
||||
{
|
||||
dtOffMeshConnection* targetCon = &targetHeader->offMeshCons[i];
|
||||
if (targetCon->side != oppositeSide)
|
||||
continue;
|
||||
|
||||
dtPoly* targetPoly = &targetHeader->polys[targetCon->poly];
|
||||
|
||||
const float ext[3] = { targetCon->rad, targetHeader->walkableClimb, targetCon->rad };
|
||||
|
||||
// Find polygon to connect to.
|
||||
const float* p = &targetCon->pos[3];
|
||||
float nearestPt[3];
|
||||
dtPolyRef ref = findNearestPolyInTile(tile, p, ext, &defaultFilter, nearestPt);
|
||||
if (!ref) continue;
|
||||
// findNearestPoly may return too optimistic results, further check to make sure.
|
||||
if (sqr(nearestPt[0]-p[0])+sqr(nearestPt[2]-p[2]) > sqr(targetCon->rad))
|
||||
continue;
|
||||
// Make sure the location is on current mesh.
|
||||
float* v = &targetHeader->verts[targetPoly->verts[1]*3];
|
||||
vcopy(v, nearestPt);
|
||||
|
||||
// Link off-mesh connection to target poly.
|
||||
unsigned int idx = allocLink(target);
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
dtLink* link = &targetHeader->links[idx];
|
||||
link->ref = ref;
|
||||
link->edge = (unsigned char)1;
|
||||
link->side = oppositeSide;
|
||||
link->bmin = link->bmax = 0;
|
||||
// Add to linked list.
|
||||
link->next = targetPoly->firstLink;
|
||||
targetPoly->firstLink = idx;
|
||||
}
|
||||
|
||||
// Link target poly to off-mesh connection.
|
||||
idx = allocLink(tile);
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
unsigned short landPolyIdx = decodePolyIdPoly(ref);
|
||||
dtPoly* landPoly = &header->polys[landPolyIdx];
|
||||
dtLink* link = &header->links[idx];
|
||||
link->ref = getTileId(target) | (unsigned int)(targetCon->poly);
|
||||
link->edge = 0;
|
||||
link->side = side;
|
||||
link->bmin = link->bmax = 0;
|
||||
// Add to linked list.
|
||||
link->next = landPoly->firstLink;
|
||||
landPoly->firstLink = idx;
|
||||
}
|
||||
}
|
||||
|
||||
h->linkCount = nlinks;
|
||||
}
|
||||
|
||||
void dtNavMesh::connectIntLinks(dtMeshTile* tile)
|
||||
{
|
||||
if (!tile) return;
|
||||
dtMeshHeader* header = tile->header;
|
||||
|
||||
dtPolyRef base = getTileId(tile);
|
||||
|
||||
for (int i = 0; i < header->polyCount; ++i)
|
||||
{
|
||||
dtPoly* poly = &header->polys[i];
|
||||
poly->firstLink = DT_NULL_LINK;
|
||||
|
||||
if (poly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
continue;
|
||||
|
||||
// Build edge links backwards so that the links will be
|
||||
// in the linked list from lowest index to highest.
|
||||
for (int j = poly->vertCount-1; j >= 0; --j)
|
||||
{
|
||||
// Skip hard and non-internal edges.
|
||||
if (poly->neis[j] == 0 || (poly->neis[j] & DT_EXT_LINK)) continue;
|
||||
|
||||
unsigned int idx = allocLink(tile);
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
dtLink* link = &header->links[idx];
|
||||
link->ref = base | (unsigned int)(poly->neis[j]-1);
|
||||
link->edge = (unsigned char)j;
|
||||
link->side = 0xff;
|
||||
link->bmin = link->bmax = 0;
|
||||
// Add to linked list.
|
||||
link->next = poly->firstLink;
|
||||
poly->firstLink = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dtNavMesh::connectIntOffMeshLinks(dtMeshTile* tile)
|
||||
{
|
||||
if (!tile) return;
|
||||
dtMeshHeader* header = tile->header;
|
||||
|
||||
dtPolyRef base = getTileId(tile);
|
||||
|
||||
// Find Off-mesh connection end points.
|
||||
for (int i = 0; i < header->offMeshConCount; ++i)
|
||||
{
|
||||
dtOffMeshConnection* con = &header->offMeshCons[i];
|
||||
dtPoly* poly = &header->polys[con->poly];
|
||||
dtQueryFilter defaultFilter;
|
||||
|
||||
const float ext[3] = { con->rad, header->walkableClimb, con->rad };
|
||||
|
||||
for (int j = 0; j < 2; ++j)
|
||||
{
|
||||
unsigned char side = j == 0 ? 0xff : con->side;
|
||||
|
||||
if (side == 0xff)
|
||||
{
|
||||
// Find polygon to connect to.
|
||||
const float* p = &con->pos[j*3];
|
||||
float nearestPt[3];
|
||||
dtPolyRef ref = findNearestPolyInTile(tile, p, ext, &defaultFilter, nearestPt);
|
||||
if (!ref) continue;
|
||||
// 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;
|
||||
// Make sure the location is on current mesh.
|
||||
float* v = &header->verts[poly->verts[j]*3];
|
||||
vcopy(v, nearestPt);
|
||||
|
||||
// Link off-mesh connection to target poly.
|
||||
unsigned int idx = allocLink(tile);
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
dtLink* link = &header->links[idx];
|
||||
link->ref = ref;
|
||||
link->edge = (unsigned char)j;
|
||||
link->side = 0xff;
|
||||
link->bmin = link->bmax = 0;
|
||||
// Add to linked list.
|
||||
link->next = poly->firstLink;
|
||||
poly->firstLink = idx;
|
||||
}
|
||||
|
||||
// Link target poly to off-mesh connection.
|
||||
idx = allocLink(tile);
|
||||
if (idx != DT_NULL_LINK)
|
||||
{
|
||||
unsigned short landPolyIdx = decodePolyIdPoly(ref);
|
||||
dtPoly* landPoly = &header->polys[landPolyIdx];
|
||||
dtLink* link = &header->links[idx];
|
||||
link->ref = base | (unsigned int)(con->poly);
|
||||
link->edge = 0;
|
||||
link->side = 0xff;
|
||||
link->bmin = link->bmax = 0;
|
||||
// Add to linked list.
|
||||
link->next = landPoly->firstLink;
|
||||
landPoly->firstLink = idx;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dtNavMesh::addTileAt(int x, int y, unsigned char* data, int dataSize, bool ownsData)
|
||||
@ -483,18 +526,7 @@ bool dtNavMesh::addTileAt(int x, int y, unsigned char* data, int dataSize, bool
|
||||
return false;
|
||||
if (header->version != DT_NAVMESH_VERSION)
|
||||
return false;
|
||||
|
||||
// Make sure the tmp link array is large enough.
|
||||
if (header->maxLinkCount > m_ntmpLinks)
|
||||
{
|
||||
m_ntmpLinks = header->maxLinkCount;
|
||||
delete [] m_tmpLinks;
|
||||
m_tmpLinks = 0;
|
||||
m_tmpLinks = new dtLink[m_ntmpLinks];
|
||||
}
|
||||
if (!m_tmpLinks)
|
||||
return false;
|
||||
|
||||
|
||||
// Allocate a tile.
|
||||
dtMeshTile* tile = m_nextFree;
|
||||
m_nextFree = tile->next;
|
||||
@ -526,6 +558,12 @@ bool dtNavMesh::addTileAt(int x, int y, unsigned char* data, int dataSize, bool
|
||||
header->bvTree = (dtBVNode*)d; d += bvtreeSize;
|
||||
header->offMeshCons = (dtOffMeshConnection*)d; d += offMeshLinksSize;
|
||||
|
||||
// Build links freelist
|
||||
header->linksFreeList = 0;
|
||||
header->links[header->maxLinkCount-1].next = DT_NULL_LINK;
|
||||
for (int i = 0; i < header->maxLinkCount-1; ++i)
|
||||
header->links[i].next = i+1;
|
||||
|
||||
// Init tile.
|
||||
tile->header = header;
|
||||
tile->x = x;
|
||||
@ -534,16 +572,19 @@ bool dtNavMesh::addTileAt(int x, int y, unsigned char* data, int dataSize, bool
|
||||
tile->dataSize = dataSize;
|
||||
tile->ownsData = ownsData;
|
||||
|
||||
buildIntLinks(tile);
|
||||
connectIntLinks(tile);
|
||||
connectIntOffMeshLinks(tile);
|
||||
|
||||
// Create connections connections.
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
dtMeshTile* nei = getNeighbourTileAt(x,y,i);
|
||||
if (nei)
|
||||
{
|
||||
buildExtLinks(tile, nei, i);
|
||||
buildExtLinks(nei, tile, opposite(i));
|
||||
connectExtLinks(tile, nei, i);
|
||||
connectExtLinks(nei, tile, opposite(i));
|
||||
connectExtOffMeshLinks(tile, nei, i);
|
||||
connectExtOffMeshLinks(nei, tile, opposite(i));
|
||||
}
|
||||
}
|
||||
|
||||
@ -582,7 +623,7 @@ const dtMeshTile* dtNavMesh::getTile(int i) const
|
||||
const dtMeshTile* dtNavMesh::getTileByRef(dtPolyRef ref, int* polyIndex) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
decodePolyId(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->polyCount) return 0;
|
||||
@ -595,9 +636,13 @@ dtMeshTile* dtNavMesh::getNeighbourTileAt(int x, int y, int side)
|
||||
switch (side)
|
||||
{
|
||||
case 0: x++; break;
|
||||
case 1: y++; break;
|
||||
case 2: x--; break;
|
||||
case 3: y--; break;
|
||||
case 1: x++; y++; break;
|
||||
case 2: y++; break;
|
||||
case 3: x--; y++; break;
|
||||
case 4: x--; break;
|
||||
case 5: x--; y--; break;
|
||||
case 6: y--; break;
|
||||
case 7: x++; y--; break;
|
||||
};
|
||||
return getTileAt(x,y);
|
||||
}
|
||||
@ -625,11 +670,11 @@ bool dtNavMesh::removeTileAt(int x, int y, unsigned char** data, int* dataSize)
|
||||
return false;
|
||||
|
||||
// Remove connections to neighbour tiles.
|
||||
for (int i = 0; i < 4; ++i)
|
||||
for (int i = 0; i < 8; ++i)
|
||||
{
|
||||
dtMeshTile* nei = getNeighbourTileAt(x,y,i);
|
||||
if (!nei) continue;
|
||||
removeExtLinks(nei, opposite(i));
|
||||
unconnectExtLinks(nei, opposite(i));
|
||||
}
|
||||
|
||||
|
||||
@ -663,19 +708,25 @@ dtPolyRef dtNavMesh::getTileId(const dtMeshTile* tile) const
|
||||
{
|
||||
if (!tile) return 0;
|
||||
const unsigned int it = tile - m_tiles;
|
||||
return dtEncodePolyId(tile->salt, it, 0);
|
||||
return encodePolyId(tile->salt, it, 0);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
bool dtNavMesh::closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
decodePolyId(ref, salt, it, ip);
|
||||
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->polyCount) return false;
|
||||
|
||||
return closestPointOnPolyInTile(&m_tiles[it], ip, pos, closest);
|
||||
}
|
||||
|
||||
bool dtNavMesh::closestPointOnPolyInTile(const dtMeshTile* tile, unsigned int ip, const float* pos, float* closest) const
|
||||
{
|
||||
const dtMeshHeader* header = tile->header;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
float closestDistSqr = FLT_MAX;
|
||||
@ -708,7 +759,7 @@ bool dtNavMesh::closestPointOnPoly(dtPolyRef ref, const float* pos, float* close
|
||||
bool dtNavMesh::closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, float* closest) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
decodePolyId(ref, salt, it, ip);
|
||||
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;
|
||||
@ -759,16 +810,8 @@ bool dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef p
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
|
||||
// Get previous poly
|
||||
dtDecodePolyId(prevRef, salt, it, ip);
|
||||
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->polyCount) return false;
|
||||
const dtPoly* prevPoly = &prevHeader->polys[ip];
|
||||
|
||||
// Get current polygon
|
||||
dtDecodePolyId(polyRef, salt, it, ip);
|
||||
decodePolyId(polyRef, salt, it, ip);
|
||||
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;
|
||||
@ -782,20 +825,20 @@ bool dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef p
|
||||
// Figure out which way to hand out the vertices.
|
||||
int idx0 = 0, idx1 = 1;
|
||||
|
||||
for (int i = 0; i < prevPoly->linkCount; ++i)
|
||||
// Find link that points to first vertex.
|
||||
for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = header->links[i].next)
|
||||
{
|
||||
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->linkBase+0].ref != prevRef)
|
||||
if (header->links[i].edge == 0)
|
||||
{
|
||||
idx0 = 1;
|
||||
idx1 = 0;
|
||||
if (header->links[i].ref != prevRef)
|
||||
{
|
||||
idx0 = 1;
|
||||
idx1 = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
vcopy(startPos, &header->verts[poly->verts[idx0]*3]);
|
||||
vcopy(endPos, &header->verts[poly->verts[idx1]*3]);
|
||||
|
||||
@ -806,7 +849,7 @@ bool dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef p
|
||||
bool dtNavMesh::getPolyHeight(dtPolyRef ref, const float* pos, float* height) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
decodePolyId(ref, salt, it, ip);
|
||||
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;
|
||||
@ -881,9 +924,42 @@ dtPolyRef dtNavMesh::findNearestPoly(const float* center, const float* extents,
|
||||
return nearest;
|
||||
}
|
||||
|
||||
int dtNavMesh::queryTilePolygons(dtMeshTile* tile, const float* qmin, const float* qmax,
|
||||
dtQueryFilter* filter,
|
||||
dtPolyRef* polys, const int maxPolys)
|
||||
dtPolyRef dtNavMesh::findNearestPolyInTile(dtMeshTile* tile, const float* center, const float* extents,
|
||||
dtQueryFilter* filter, float* nearestPt)
|
||||
{
|
||||
float bmin[3], bmax[3];
|
||||
vsub(bmin, center, extents);
|
||||
vadd(bmax, center, extents);
|
||||
|
||||
// Get nearby polygons from proximity grid.
|
||||
dtPolyRef polys[128];
|
||||
int polyCount = queryPolygonsInTile(tile, bmin, bmax, filter, polys, 128);
|
||||
|
||||
// Find nearest polygon amongst the nearby polygons.
|
||||
dtPolyRef nearest = 0;
|
||||
float nearestDistanceSqr = FLT_MAX;
|
||||
for (int i = 0; i < polyCount; ++i)
|
||||
{
|
||||
dtPolyRef ref = polys[i];
|
||||
float closestPtPoly[3];
|
||||
if (!closestPointOnPolyInTile(tile, decodePolyIdPoly(ref), center, closestPtPoly))
|
||||
continue;
|
||||
float d = vdistSqr(center, closestPtPoly);
|
||||
if (d < nearestDistanceSqr)
|
||||
{
|
||||
if (nearestPt)
|
||||
vcopy(nearestPt, closestPtPoly);
|
||||
nearestDistanceSqr = d;
|
||||
nearest = ref;
|
||||
}
|
||||
}
|
||||
|
||||
return nearest;
|
||||
}
|
||||
|
||||
int dtNavMesh::queryPolygonsInTile(dtMeshTile* tile, const float* qmin, const float* qmax,
|
||||
dtQueryFilter* filter,
|
||||
dtPolyRef* polys, const int maxPolys)
|
||||
{
|
||||
const dtMeshHeader* header = tile->header;
|
||||
if (header->bvTree)
|
||||
@ -972,13 +1048,8 @@ int dtNavMesh::queryPolygons(const float* center, const float* extents, dtQueryF
|
||||
dtPolyRef* polys, const int maxPolys)
|
||||
{
|
||||
float bmin[3], bmax[3];
|
||||
bmin[0] = center[0] - extents[0];
|
||||
bmin[1] = center[1] - extents[1];
|
||||
bmin[2] = center[2] - extents[2];
|
||||
|
||||
bmax[0] = center[0] + extents[0];
|
||||
bmax[1] = center[1] + extents[1];
|
||||
bmax[2] = center[2] + extents[2];
|
||||
vsub(bmin, center, extents);
|
||||
vadd(bmax, center, extents);
|
||||
|
||||
// Find tiles the query touches.
|
||||
const int minx = (int)floorf((bmin[0]-m_orig[0]) / m_tileWidth);
|
||||
@ -994,7 +1065,7 @@ int dtNavMesh::queryPolygons(const float* center, const float* extents, dtQueryF
|
||||
{
|
||||
dtMeshTile* tile = getTileAt(x,y);
|
||||
if (!tile) continue;
|
||||
n += queryTilePolygons(tile, bmin, bmax, filter, polys+n, maxPolys-n);
|
||||
n += queryPolygonsInTile(tile, bmin, bmax, filter, polys+n, maxPolys-n);
|
||||
if (n >= maxPolys) return n;
|
||||
}
|
||||
}
|
||||
@ -1052,14 +1123,14 @@ int dtNavMesh::findPath(dtPolyRef startRef, dtPolyRef endRef,
|
||||
|
||||
// Get poly and tile.
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(bestNode->id, salt, it, ip);
|
||||
decodePolyId(bestNode->id, salt, it, ip);
|
||||
// The API input has been cheked already, skip checking internal data.
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = header->links[i].next)
|
||||
{
|
||||
dtPolyRef neighbour = header->links[poly->linkBase+i].ref;
|
||||
dtPolyRef neighbour = header->links[i].ref;
|
||||
if (neighbour)
|
||||
{
|
||||
// Skip parent node.
|
||||
@ -1388,7 +1459,7 @@ int dtNavMesh::moveAlongPathCorridor(const float* startPos, const float* endPos,
|
||||
{
|
||||
// Get current polygon and poly vertices.
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(path[n], salt, it, ip);
|
||||
decodePolyId(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->polyCount) return n;
|
||||
@ -1465,7 +1536,7 @@ bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float
|
||||
unsigned short& fromFlags, unsigned short& toFlags) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(from, salt, it, ip);
|
||||
decodePolyId(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->polyCount) return false;
|
||||
@ -1473,13 +1544,13 @@ bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float
|
||||
const dtPoly* fromPoly = &fromHeader->polys[ip];
|
||||
fromFlags = fromPoly->flags;
|
||||
|
||||
for (int i = 0; i < fromPoly->linkCount; ++i)
|
||||
for (unsigned int i = fromPoly->firstLink; i != DT_NULL_LINK; i = fromHeader->links[i].next)
|
||||
{
|
||||
const dtLink* link = &fromHeader->links[fromPoly->linkBase+i];
|
||||
const dtLink* link = &fromHeader->links[i];
|
||||
if (link->ref != to)
|
||||
continue;
|
||||
|
||||
dtDecodePolyId(to, salt, it, ip);
|
||||
decodePolyId(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->polyCount) return false;
|
||||
@ -1489,18 +1560,33 @@ bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float
|
||||
|
||||
if (fromPoly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
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;
|
||||
// Find link that points to first vertex.
|
||||
for (unsigned int i = fromPoly->firstLink; i != DT_NULL_LINK; i = fromHeader->links[i].next)
|
||||
{
|
||||
if (fromHeader->links[i].ref == to)
|
||||
{
|
||||
const int v = fromHeader->links[i].edge;
|
||||
vcopy(left, &fromHeader->verts[fromPoly->verts[v]*3]);
|
||||
vcopy(right, &fromHeader->verts[fromPoly->verts[v]*3]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (toPoly->flags & DT_POLY_OFFMESH_CONNECTION)
|
||||
{
|
||||
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;
|
||||
for (unsigned int i = toPoly->firstLink; i != DT_NULL_LINK; i = toHeader->links[i].next)
|
||||
{
|
||||
if (toHeader->links[i].ref == from)
|
||||
{
|
||||
const int v = toHeader->links[i].edge;
|
||||
vcopy(left, &toHeader->verts[toPoly->verts[v]*3]);
|
||||
vcopy(right, &toHeader->verts[toPoly->verts[v]*3]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find portal vertices.
|
||||
@ -1510,7 +1596,7 @@ bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float
|
||||
vcopy(right, &fromHeader->verts[v1*3]);
|
||||
// If the link is at tile boundary, clamp the vertices to
|
||||
// the link width.
|
||||
if (link->side == 0 || link->side == 2)
|
||||
if (link->side == 0 || link->side == 4)
|
||||
{
|
||||
// Unpack portal limits.
|
||||
const float smin = min(left[2],right[2]);
|
||||
@ -1523,7 +1609,7 @@ bool dtNavMesh::getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float
|
||||
right[2] = max(right[2],lmin);
|
||||
right[2] = min(right[2],lmax);
|
||||
}
|
||||
else if (link->side == 1 || link->side == 3)
|
||||
else if (link->side == 2 || link->side == 6)
|
||||
{
|
||||
// Unpack portal limits.
|
||||
const float smin = min(left[0],right[0]);
|
||||
@ -1556,7 +1642,7 @@ bool dtNavMesh::getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const
|
||||
unsigned short dtNavMesh::getPolyFlags(dtPolyRef ref)
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
decodePolyId(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->polyCount) return 0;
|
||||
@ -1586,8 +1672,8 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
// Cast ray against current polygon.
|
||||
|
||||
// The API input has been cheked already, skip checking internal data.
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(curRef, salt, it, ip);
|
||||
unsigned int it = decodePolyIdTile(curRef);
|
||||
unsigned int ip = decodePolyIdPoly(curRef);
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
@ -1615,9 +1701,10 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
|
||||
// Follow neighbours.
|
||||
dtPolyRef nextRef = 0;
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
|
||||
for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = header->links[i].next)
|
||||
{
|
||||
const dtLink* link = &header->links[poly->linkBase+i];
|
||||
const dtLink* link = &header->links[i];
|
||||
if ((int)link->edge == segMax)
|
||||
{
|
||||
// If the link is internal, just return the ref.
|
||||
@ -1634,7 +1721,7 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
const float* right = &header->verts[v1*3];
|
||||
|
||||
// Check that the intersection lies inside the link portal.
|
||||
if (link->side == 0 || link->side == 2)
|
||||
if (link->side == 0 || link->side == 4)
|
||||
{
|
||||
// Calculate link size.
|
||||
const float smin = min(left[2],right[2]);
|
||||
@ -1650,7 +1737,7 @@ int dtNavMesh::raycast(dtPolyRef centerRef, const float* startPos, const float*
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (link->side == 1 || link->side == 3)
|
||||
else if (link->side == 2 || link->side == 6)
|
||||
{
|
||||
// Calculate link size.
|
||||
const float smin = min(left[0],right[0]);
|
||||
@ -1733,15 +1820,15 @@ int dtNavMesh::findPolysAround(dtPolyRef centerRef, const float* centerPos, floa
|
||||
dtNode* bestNode = m_openList->pop();
|
||||
|
||||
// Get poly and tile.
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(bestNode->id, salt, it, ip);
|
||||
// The API input has been cheked already, skip checking internal data.
|
||||
unsigned int it = decodePolyIdTile(bestNode->id);
|
||||
unsigned int ip = decodePolyIdPoly(bestNode->id);
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = header->links[i].next)
|
||||
{
|
||||
const dtLink* link = &header->links[poly->linkBase+i];
|
||||
const dtLink* link = &header->links[i];
|
||||
dtPolyRef neighbour = link->ref;
|
||||
if (neighbour)
|
||||
{
|
||||
@ -1839,9 +1926,9 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
dtNode* bestNode = m_openList->pop();
|
||||
|
||||
// Get poly and tile.
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(bestNode->id, salt, it, ip);
|
||||
// The API input has been cheked already, skip checking internal data.
|
||||
unsigned int it = decodePolyIdTile(bestNode->id);
|
||||
unsigned int ip = decodePolyIdPoly(bestNode->id);
|
||||
const dtMeshHeader* header = m_tiles[it].header;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
@ -1853,9 +1940,9 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
{
|
||||
// Tile border.
|
||||
bool solid = true;
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
for (unsigned int k = poly->firstLink; k != DT_NULL_LINK; k = header->links[k].next)
|
||||
{
|
||||
const dtLink* link = &header->links[poly->linkBase+i];
|
||||
const dtLink* link = &header->links[k];
|
||||
if (link->edge == j && link->ref != 0 && passFilter(filter, getPolyFlags(link->ref)))
|
||||
{
|
||||
solid = false;
|
||||
@ -1864,7 +1951,7 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
}
|
||||
if (!solid) continue;
|
||||
}
|
||||
else if (poly->neis[j] && passFilter(filter, getPolyFlags(poly->neis[j])))
|
||||
else if (poly->neis[j] && passFilter(filter, header->polys[poly->neis[j]].flags))
|
||||
{
|
||||
// Internal edge
|
||||
continue;
|
||||
@ -1888,9 +1975,9 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
hitPos[2] = vj[2] + (vi[2] - vj[2])*tseg;
|
||||
}
|
||||
|
||||
for (int i = 0; i < poly->linkCount; ++i)
|
||||
for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = header->links[i].next)
|
||||
{
|
||||
const dtLink* link = &header->links[poly->linkBase+i];
|
||||
const dtLink* link = &header->links[i];
|
||||
dtPolyRef neighbour = link->ref;
|
||||
if (neighbour)
|
||||
{
|
||||
@ -1959,7 +2046,7 @@ float dtNavMesh::findDistanceToWall(dtPolyRef centerRef, const float* centerPos,
|
||||
const dtPoly* dtNavMesh::getPolyByRef(dtPolyRef ref) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
decodePolyId(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->polyCount) return 0;
|
||||
@ -1969,7 +2056,7 @@ const dtPoly* dtNavMesh::getPolyByRef(dtPolyRef ref) const
|
||||
const float* dtNavMesh::getPolyVertsByRef(dtPolyRef ref) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
decodePolyId(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->polyCount) return 0;
|
||||
@ -1979,7 +2066,7 @@ const float* dtNavMesh::getPolyVertsByRef(dtPolyRef ref) const
|
||||
const dtLink* dtNavMesh::getPolyLinksByRef(dtPolyRef ref) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
decodePolyId(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->polyCount) return 0;
|
||||
|
@ -210,134 +210,35 @@ static int createBVTree(const unsigned short* verts, const int nverts,
|
||||
return curNode;
|
||||
}
|
||||
|
||||
/*
|
||||
static int queryPolygons(dtMeshHeader* header,
|
||||
const float* qmin, const float* qmax,
|
||||
unsigned short* polys, const int maxPolys)
|
||||
static unsigned char classifyOffMeshPoint(const float* pt, const float* bmin, const float* bmax)
|
||||
{
|
||||
const dtBVNode* node = &header->bvtree[0];
|
||||
const dtBVNode* end = &header->bvtree[header->nbvtree];
|
||||
|
||||
// Calculate quantized box
|
||||
unsigned short bmin[3], bmax[3];
|
||||
// Clamp query box to world box.
|
||||
float minx = clamp(qmin[0], header->bmin[0], header->bmax[0]) - header->bmin[0];
|
||||
float miny = clamp(qmin[1], header->bmin[1], header->bmax[1]) - header->bmin[1];
|
||||
float minz = clamp(qmin[2], header->bmin[2], header->bmax[2]) - header->bmin[2];
|
||||
float maxx = clamp(qmax[0], header->bmin[0], header->bmax[0]) - header->bmin[0];
|
||||
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;
|
||||
|
||||
// Traverse tree
|
||||
dtPolyRef base = getTileId(tile);
|
||||
int n = 0;
|
||||
while (node < end)
|
||||
static const unsigned char XP = 1<<0;
|
||||
static const unsigned char ZP = 1<<1;
|
||||
static const unsigned char XM = 1<<2;
|
||||
static const unsigned char ZM = 1<<3;
|
||||
|
||||
unsigned char outcode = 0;
|
||||
outcode |= (pt[0] >= bmax[0]) ? XP : 0;
|
||||
outcode |= (pt[2] >= bmax[2]) ? ZP : 0;
|
||||
outcode |= (pt[0] < bmin[0]) ? XM : 0;
|
||||
outcode |= (pt[2] < bmin[2]) ? ZM : 0;
|
||||
|
||||
switch (outcode)
|
||||
{
|
||||
bool overlap = checkOverlapBox(bmin, bmax, node->bmin, node->bmax);
|
||||
bool isLeafNode = node->i >= 0;
|
||||
|
||||
if (isLeafNode && overlap)
|
||||
{
|
||||
if (n < maxPolys)
|
||||
polys[n++] = base | (dtPolyRef)node->i;
|
||||
}
|
||||
|
||||
if (overlap || isLeafNode)
|
||||
node++;
|
||||
else
|
||||
{
|
||||
const int escapeIndex = -node->i;
|
||||
node += escapeIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
case XP: return 0;
|
||||
case XP|ZP: return 1;
|
||||
case ZP: return 2;
|
||||
case XM|ZP: return 3;
|
||||
case XM: return 4;
|
||||
case XM|ZM: return 5;
|
||||
case ZM: return 6;
|
||||
case XP|ZM: return 7;
|
||||
};
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
dtMeshHeader* header
|
||||
{
|
||||
bool dtNavMesh::closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest) const
|
||||
{
|
||||
unsigned int salt, it, ip;
|
||||
dtDecodePolyId(ref, salt, it, ip);
|
||||
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;
|
||||
const dtPoly* poly = &header->polys[ip];
|
||||
|
||||
float closestDistSqr = FLT_MAX;
|
||||
const dtPolyDetail* pd = &header->dmeshes[ip];
|
||||
|
||||
for (int j = 0; j < pd->ntris; ++j)
|
||||
{
|
||||
const unsigned char* t = &header->dtris[(pd->tbase+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];
|
||||
else
|
||||
v[k] = &header->dverts[(pd->vbase+(t[k]-poly->nv))*3];
|
||||
}
|
||||
float pt[3];
|
||||
closestPtPointTriangle(pt, pos, v[0], v[1], v[2]);
|
||||
float d = vdistSqr(pos, pt);
|
||||
if (d < closestDistSqr)
|
||||
{
|
||||
vcopy(closest, pt);
|
||||
closestDistSqr = d;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// TODO: Better error handling.
|
||||
|
||||
unsigned short findNearestPoly(dtMeshHeader* header, const float* center, const float* extents)
|
||||
{
|
||||
// Get nearby polygons from proximity grid.
|
||||
float bmin[3], bmax[3];
|
||||
bmin[0] = center[0] - extents[0];
|
||||
bmin[1] = center[1] - extents[1];
|
||||
bmin[2] = center[2] - extents[2];
|
||||
bmax[0] = center[0] + extents[0];
|
||||
bmax[1] = center[1] + extents[1];
|
||||
bmax[2] = center[2] + extents[2];
|
||||
unsigned short polys[128];
|
||||
int npolys = queryPolygons(header, bmin, bmax, polys, 128);
|
||||
|
||||
// Find nearest polygon amongst the nearby polygons.
|
||||
unsigned short nearest = 0xffff;
|
||||
float nearestDistanceSqr = FLT_MAX;
|
||||
for (int i = 0; i < npolys; ++i)
|
||||
{
|
||||
dtPolyRef ref = polys[i];
|
||||
float closest[3];
|
||||
|
||||
if (!closestPointOnPoly(ref, center, closest))
|
||||
continue;
|
||||
|
||||
float d = vdistSqr(center, closest);
|
||||
if (d < nearestDistanceSqr)
|
||||
{
|
||||
nearestDistanceSqr = d;
|
||||
nearest = ref;
|
||||
}
|
||||
}
|
||||
|
||||
return nearest;
|
||||
}
|
||||
*/
|
||||
|
||||
bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, int* outDataSize)
|
||||
{
|
||||
if (params->nvp > DT_VERTS_PER_POLYGON)
|
||||
@ -353,9 +254,36 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
|
||||
const int nvp = params->nvp;
|
||||
|
||||
// Classify off-mesh connection points. We store only the connections
|
||||
// whose start point is inside the tile.
|
||||
unsigned char* offMeshConFlags = new unsigned char [params->offMeshConCount*2];
|
||||
if (!offMeshConFlags)
|
||||
return false;
|
||||
|
||||
int storedOffMeshConCount = 0;
|
||||
int offMeshConLinkCount = 0;
|
||||
|
||||
printf("classify\n");
|
||||
for (int i = 0; i < params->offMeshConCount; ++i)
|
||||
{
|
||||
offMeshConFlags[i*2+0] = classifyOffMeshPoint(¶ms->offMeshConVerts[(i*2+0)*3], params->bmin, params->bmax);
|
||||
offMeshConFlags[i*2+1] = classifyOffMeshPoint(¶ms->offMeshConVerts[(i*2+1)*3], params->bmin, params->bmax);
|
||||
|
||||
printf(" %d, %d\n", (int)offMeshConFlags[i*2+0], (int)offMeshConFlags[i*2+1]);
|
||||
|
||||
// Cound how many links should be allocated for off-mesh connections.
|
||||
if (offMeshConFlags[i*2+0] == 0xff)
|
||||
offMeshConLinkCount++;
|
||||
if (offMeshConFlags[i*2+1] == 0xff)
|
||||
offMeshConLinkCount++;
|
||||
|
||||
if (offMeshConFlags[i*2+0] == 0xff)
|
||||
storedOffMeshConCount++;
|
||||
}
|
||||
|
||||
// Off-mesh connectionss are stored as polygons, adjust values.
|
||||
const int totPolyCount = params->polyCount + params->offMeshConCount;
|
||||
const int totVertCount = params->vertCount + params->offMeshConCount*2;
|
||||
const int totPolyCount = params->polyCount + storedOffMeshConCount;
|
||||
const int totVertCount = params->vertCount + storedOffMeshConCount*2;
|
||||
|
||||
// Find portal edges which are at tile borders.
|
||||
int edgeCount = 0;
|
||||
@ -387,8 +315,7 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
}
|
||||
}
|
||||
|
||||
const int maxLinkCount = edgeCount + portalCount*2 + params->offMeshConCount*4;
|
||||
|
||||
const int maxLinkCount = edgeCount + portalCount*2 + offMeshConLinkCount*2;
|
||||
|
||||
// Find unique detail vertices.
|
||||
int uniqueDetailVertCount = 0;
|
||||
@ -415,7 +342,7 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
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 offMeshConsSize = align4(sizeof(dtOffMeshConnection)*storedOffMeshConCount);
|
||||
|
||||
const int dataSize = headerSize + vertsSize + polysSize + linksSize +
|
||||
detailMeshesSize + detailVertsSize + detailTrisSize +
|
||||
@ -454,7 +381,7 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
header->walkableHeight = params->walkableHeight;
|
||||
header->walkableRadius = params->walkableRadius;
|
||||
header->walkableClimb = params->walkableClimb;
|
||||
header->offMeshConCount = params->offMeshConCount;
|
||||
header->offMeshConCount = storedOffMeshConCount;
|
||||
header->bvNodeCount = params->polyCount*2;
|
||||
|
||||
const int offMeshVertsBase = params->vertCount;
|
||||
@ -471,12 +398,18 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
v[2] = params->bmin[2] + iv[2] * params->cs;
|
||||
}
|
||||
// Off-mesh link vertices.
|
||||
int n = 0;
|
||||
for (int i = 0; i < params->offMeshConCount; ++i)
|
||||
{
|
||||
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]);
|
||||
// Only store connections which start from this tile.
|
||||
if (offMeshConFlags[i*2+0] == 0xff)
|
||||
{
|
||||
const float* linkv = ¶ms->offMeshConVerts[i*2*3];
|
||||
float* v = &navVerts[(offMeshVertsBase + n*2)*3];
|
||||
vcopy(&v[0], &linkv[0]);
|
||||
vcopy(&v[3], &linkv[3]);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// Store polygons
|
||||
@ -497,13 +430,19 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
src += nvp*2;
|
||||
}
|
||||
// Off-mesh connection vertices.
|
||||
n = 0;
|
||||
for (int i = 0; i < params->offMeshConCount; ++i)
|
||||
{
|
||||
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.
|
||||
// Only store connections which start from this tile.
|
||||
if (offMeshConFlags[i*2+0] == 0xff)
|
||||
{
|
||||
dtPoly* p = &navPolys[offMeshPolyBase+n];
|
||||
p->vertCount = 2;
|
||||
p->verts[0] = (unsigned short)(offMeshVertsBase + n*2+0);
|
||||
p->verts[1] = (unsigned short)(offMeshVertsBase + n*2+1);
|
||||
p->flags = DT_POLY_OFFMESH_CONNECTION; // Off-mesh link poly.
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
// Store portal edges.
|
||||
@ -523,11 +462,11 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
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->neis[j] = DT_EXT_LINK | 2;
|
||||
else if (va[0] == 0 && vb[0] == 0) // x-
|
||||
poly->neis[j] = DT_EXT_LINK | 4;
|
||||
else if (va[2] == 0 && vb[2] == 0) // z-
|
||||
poly->neis[j] = DT_EXT_LINK | 3;
|
||||
poly->neis[j] = DT_EXT_LINK | 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -562,18 +501,27 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
|
||||
nvp, params->cs, params->ch, params->polyCount*2, navBvtree);
|
||||
|
||||
// Store Off-Mesh connections.
|
||||
n = 0;
|
||||
for (int i = 0; i < params->offMeshConCount; ++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];
|
||||
// Only store connections which start from this tile.
|
||||
if (offMeshConFlags[i*2+0] == 0xff)
|
||||
{
|
||||
dtOffMeshConnection* con = &offMeshCons[n];
|
||||
con->poly = offMeshPolyBase + n;
|
||||
// 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];
|
||||
con->side = offMeshConFlags[i*2+1];
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
delete [] offMeshConFlags;
|
||||
|
||||
*outData = data;
|
||||
*outDataSize = dataSize;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -254,7 +254,7 @@
|
||||
<dict>
|
||||
<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
|
||||
<array>
|
||||
<real>282</real>
|
||||
<real>358</real>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
|
||||
<array>
|
||||
@ -288,7 +288,7 @@
|
||||
</array>
|
||||
</array>
|
||||
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
|
||||
<string>{{0, 41}, {282, 643}}</string>
|
||||
<string>{{0, 0}, {358, 643}}</string>
|
||||
</dict>
|
||||
<key>PBXTopSmartGroupGIDs</key>
|
||||
<array/>
|
||||
@ -298,11 +298,11 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {299, 661}}</string>
|
||||
<string>{{0, 0}, {375, 661}}</string>
|
||||
<key>GroupTreeTableConfiguration</key>
|
||||
<array>
|
||||
<string>MainColumn</string>
|
||||
<real>282</real>
|
||||
<real>358</real>
|
||||
</array>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>11 76 1256 702 0 0 1280 778 </string>
|
||||
@ -310,7 +310,7 @@
|
||||
<key>Module</key>
|
||||
<string>PBXSmartGroupTreeModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>299pt</string>
|
||||
<string>375pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Dock</key>
|
||||
@ -323,7 +323,7 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>6B8632A30F78115100E2684A</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>DetourNavMesh.h</string>
|
||||
<string>DetourNavMesh.cpp</string>
|
||||
<key>PBXSplitModuleInNavigatorKey</key>
|
||||
<dict>
|
||||
<key>Split0</key>
|
||||
@ -331,11 +331,11 @@
|
||||
<key>PBXProjectModuleGUID</key>
|
||||
<string>6B8632A40F78115100E2684A</string>
|
||||
<key>PBXProjectModuleLabel</key>
|
||||
<string>DetourNavMesh.h</string>
|
||||
<string>DetourNavMesh.cpp</string>
|
||||
<key>_historyCapacity</key>
|
||||
<integer>0</integer>
|
||||
<key>bookmark</key>
|
||||
<string>6BCF34F411060322009445BF</string>
|
||||
<string>6BF7BE92110F1BDA002B3F46</string>
|
||||
<key>history</key>
|
||||
<array>
|
||||
<string>6B57D358108C66B200DDD053</string>
|
||||
@ -355,39 +355,38 @@
|
||||
<string>6BB7FDC010F37703006DA0A6</string>
|
||||
<string>6BB7FDC110F37703006DA0A6</string>
|
||||
<string>6BB7FE1010F37CF7006DA0A6</string>
|
||||
<string>6BB7FE3B10F3817A006DA0A6</string>
|
||||
<string>6BB7FF6D10F4E8E2006DA0A6</string>
|
||||
<string>6BB3605210FE5CBD00A9B4B8</string>
|
||||
<string>6BB3606210FE5E8F00A9B4B8</string>
|
||||
<string>6B69736710FFBDCA00984788</string>
|
||||
<string>6B69739F10FFCA4500984788</string>
|
||||
<string>6BCF325E1104CFE7009445BF</string>
|
||||
<string>6BCF325F1104CFE7009445BF</string>
|
||||
<string>6BCF331911059E23009445BF</string>
|
||||
<string>6BCF331A11059E23009445BF</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>6BCF34441105ECEB009445BF</string>
|
||||
<string>6BCF34691105EF2D009445BF</string>
|
||||
<string>6BCF34831105F555009445BF</string>
|
||||
<string>6BCF34901105F821009445BF</string>
|
||||
<string>6BCF34911105F821009445BF</string>
|
||||
<string>6BCF34A41105F894009445BF</string>
|
||||
<string>6BCF34B01105FA03009445BF</string>
|
||||
<string>6BCF34B11105FA03009445BF</string>
|
||||
<string>6BCF34E2110602BB009445BF</string>
|
||||
<string>6BCF34E3110602BB009445BF</string>
|
||||
<string>6BCF34F111060322009445BF</string>
|
||||
<string>6BCF34F211060322009445BF</string>
|
||||
<string>6B4260231109DE9500C48C36</string>
|
||||
<string>6B4260301109E1EE00C48C36</string>
|
||||
<string>6B84BED0110E1818007D997B</string>
|
||||
<string>6B84BEE2110E1983007D997B</string>
|
||||
<string>6B84BEFE110E1E10007D997B</string>
|
||||
<string>6B84BEFF110E1E10007D997B</string>
|
||||
<string>6BF7BDBE110EF674002B3F46</string>
|
||||
<string>6BF7BE1F110F0792002B3F46</string>
|
||||
<string>6BF7BE39110F1576002B3F46</string>
|
||||
<string>6BF7BE5C110F170A002B3F46</string>
|
||||
<string>6BF7BE5D110F170A002B3F46</string>
|
||||
<string>6BF7BE5E110F170A002B3F46</string>
|
||||
<string>6BF7BE60110F170A002B3F46</string>
|
||||
<string>6BF7BE73110F1832002B3F46</string>
|
||||
<string>6BF7BE74110F1832002B3F46</string>
|
||||
<string>6BF7BE75110F1832002B3F46</string>
|
||||
<string>6BF7BE76110F1832002B3F46</string>
|
||||
<string>6BF7BE82110F196C002B3F46</string>
|
||||
<string>6BF7BE83110F196C002B3F46</string>
|
||||
<string>6BF7BE8C110F1AFC002B3F46</string>
|
||||
<string>6BF7BE8D110F1AFC002B3F46</string>
|
||||
<string>6BF7BE1E110F0792002B3F46</string>
|
||||
</array>
|
||||
<key>prevStack</key>
|
||||
<array>
|
||||
@ -409,236 +408,118 @@
|
||||
<string>6BB7FE2210F37CF7006DA0A6</string>
|
||||
<string>6BB7FE2310F37CF7006DA0A6</string>
|
||||
<string>6BB7FE5410F3817A006DA0A6</string>
|
||||
<string>6BB7FEB810F4B5E1006DA0A6</string>
|
||||
<string>6BB7FECF10F4B5E1006DA0A6</string>
|
||||
<string>6BB7FF2410F4D699006DA0A6</string>
|
||||
<string>6BB7FF9610F4E8E2006DA0A6</string>
|
||||
<string>6BB700C310FA3AB1006DA0A6</string>
|
||||
<string>6BE7320610FE6CEF00C1B074</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>
|
||||
<string>6BCF34941105F821009445BF</string>
|
||||
<string>6BCF34951105F821009445BF</string>
|
||||
<string>6BCF34961105F821009445BF</string>
|
||||
<string>6BCF34971105F821009445BF</string>
|
||||
<string>6BCF349D1105F845009445BF</string>
|
||||
<string>6BCF34A71105F894009445BF</string>
|
||||
<string>6BCF34A81105F894009445BF</string>
|
||||
<string>6BCF34A91105F894009445BF</string>
|
||||
<string>6BCF34AE1105F8DB009445BF</string>
|
||||
<string>6BCF34B31105FA03009445BF</string>
|
||||
<string>6BCF34B41105FA03009445BF</string>
|
||||
<string>6BCF34B51105FA03009445BF</string>
|
||||
<string>6BCF34BE1105FD0F009445BF</string>
|
||||
<string>6BCF34BF1105FD0F009445BF</string>
|
||||
<string>6BCF34C01105FD0F009445BF</string>
|
||||
<string>6BCF34C11105FD0F009445BF</string>
|
||||
<string>6BCF34C21105FD0F009445BF</string>
|
||||
<string>6BCF34C31105FD0F009445BF</string>
|
||||
<string>6BCF34C41105FD0F009445BF</string>
|
||||
<string>6BCF34C51105FD0F009445BF</string>
|
||||
<string>6BCF34C61105FD0F009445BF</string>
|
||||
<string>6BCF34C71105FD0F009445BF</string>
|
||||
<string>6BCF34C81105FD0F009445BF</string>
|
||||
<string>6BCF34C91105FD0F009445BF</string>
|
||||
<string>6BCF34CA1105FD0F009445BF</string>
|
||||
<string>6BCF34CB1105FD0F009445BF</string>
|
||||
<string>6BCF34CC1105FD0F009445BF</string>
|
||||
<string>6BCF34D01105FF32009445BF</string>
|
||||
<string>6BCF34D11105FF32009445BF</string>
|
||||
<string>6BCF34D21105FF32009445BF</string>
|
||||
<string>6BCF34D31105FF32009445BF</string>
|
||||
<string>6BCF34E5110602BB009445BF</string>
|
||||
<string>6BCF34E6110602BB009445BF</string>
|
||||
<string>6BCF34E7110602BB009445BF</string>
|
||||
<string>6BCF34E8110602BB009445BF</string>
|
||||
<string>6BCF34E9110602BB009445BF</string>
|
||||
<string>6BCF34EA110602BB009445BF</string>
|
||||
<string>6BCF34EB110602BB009445BF</string>
|
||||
<string>6BCF34EC110602BB009445BF</string>
|
||||
<string>6BCF34ED110602BB009445BF</string>
|
||||
<string>6BCF34EE110602BB009445BF</string>
|
||||
<string>6BCF34EF110602BB009445BF</string>
|
||||
<string>6BCF34F311060322009445BF</string>
|
||||
<string>6B4260411109E27F00C48C36</string>
|
||||
<string>6B4260471109E83800C48C36</string>
|
||||
<string>6B4260481109E83800C48C36</string>
|
||||
<string>6BF7BDC7110EF674002B3F46</string>
|
||||
<string>6BF7BDC8110EF674002B3F46</string>
|
||||
<string>6BF7BDC9110EF674002B3F46</string>
|
||||
<string>6BF7BDCA110EF674002B3F46</string>
|
||||
<string>6BF7BDCB110EF674002B3F46</string>
|
||||
<string>6BF7BDCC110EF674002B3F46</string>
|
||||
<string>6BF7BDCD110EF674002B3F46</string>
|
||||
<string>6BF7BDCE110EF674002B3F46</string>
|
||||
<string>6BF7BDCF110EF674002B3F46</string>
|
||||
<string>6BF7BDD0110EF674002B3F46</string>
|
||||
<string>6BF7BDD1110EF674002B3F46</string>
|
||||
<string>6BF7BDD2110EF674002B3F46</string>
|
||||
<string>6BF7BDD3110EF674002B3F46</string>
|
||||
<string>6BF7BDD4110EF674002B3F46</string>
|
||||
<string>6BF7BDD5110EF674002B3F46</string>
|
||||
<string>6BF7BDD6110EF674002B3F46</string>
|
||||
<string>6BF7BDD7110EF674002B3F46</string>
|
||||
<string>6BF7BDD8110EF674002B3F46</string>
|
||||
<string>6BF7BDD9110EF674002B3F46</string>
|
||||
<string>6BF7BDDA110EF674002B3F46</string>
|
||||
<string>6BF7BDDB110EF674002B3F46</string>
|
||||
<string>6BF7BDDC110EF674002B3F46</string>
|
||||
<string>6BF7BDDD110EF674002B3F46</string>
|
||||
<string>6BF7BDDE110EF674002B3F46</string>
|
||||
<string>6BF7BDDF110EF674002B3F46</string>
|
||||
<string>6BF7BDE0110EF674002B3F46</string>
|
||||
<string>6BF7BDE1110EF674002B3F46</string>
|
||||
<string>6BF7BDE2110EF674002B3F46</string>
|
||||
<string>6BF7BDE3110EF674002B3F46</string>
|
||||
<string>6BF7BDE4110EF674002B3F46</string>
|
||||
<string>6BF7BDE5110EF674002B3F46</string>
|
||||
<string>6BF7BDE6110EF674002B3F46</string>
|
||||
<string>6BF7BDE7110EF674002B3F46</string>
|
||||
<string>6BF7BDE8110EF674002B3F46</string>
|
||||
<string>6BF7BDE9110EF674002B3F46</string>
|
||||
<string>6BF7BDEA110EF674002B3F46</string>
|
||||
<string>6BF7BDF7110EF76D002B3F46</string>
|
||||
<string>6BF7BDF8110EF76D002B3F46</string>
|
||||
<string>6BF7BDF9110EF76D002B3F46</string>
|
||||
<string>6BF7BDFA110EF76D002B3F46</string>
|
||||
<string>6BF7BE07110EF794002B3F46</string>
|
||||
<string>6BF7BE11110EF7F7002B3F46</string>
|
||||
<string>6BF7BE1A110F023C002B3F46</string>
|
||||
<string>6BF7BE1B110F023C002B3F46</string>
|
||||
<string>6BF7BE1C110F023C002B3F46</string>
|
||||
<string>6BF7BE22110F0792002B3F46</string>
|
||||
<string>6BF7BE23110F0792002B3F46</string>
|
||||
<string>6BF7BE24110F0792002B3F46</string>
|
||||
<string>6BF7BE25110F0792002B3F46</string>
|
||||
<string>6BF7BE26110F0792002B3F46</string>
|
||||
<string>6BF7BE2C110F13F9002B3F46</string>
|
||||
<string>6BF7BE2D110F13F9002B3F46</string>
|
||||
<string>6BF7BE40110F1576002B3F46</string>
|
||||
<string>6BF7BE41110F1576002B3F46</string>
|
||||
<string>6BF7BE42110F1576002B3F46</string>
|
||||
<string>6BF7BE43110F1576002B3F46</string>
|
||||
<string>6BF7BE44110F1576002B3F46</string>
|
||||
<string>6BF7BE45110F1576002B3F46</string>
|
||||
<string>6BF7BE46110F1576002B3F46</string>
|
||||
<string>6BF7BE47110F1576002B3F46</string>
|
||||
<string>6BF7BE48110F1576002B3F46</string>
|
||||
<string>6BF7BE49110F1576002B3F46</string>
|
||||
<string>6BF7BE4A110F1576002B3F46</string>
|
||||
<string>6BF7BE4B110F1576002B3F46</string>
|
||||
<string>6BF7BE4C110F1576002B3F46</string>
|
||||
<string>6BF7BE4D110F1576002B3F46</string>
|
||||
<string>6BF7BE4E110F1576002B3F46</string>
|
||||
<string>6BF7BE56110F160F002B3F46</string>
|
||||
<string>6BF7BE57110F160F002B3F46</string>
|
||||
<string>6BF7BE64110F170A002B3F46</string>
|
||||
<string>6BF7BE65110F170A002B3F46</string>
|
||||
<string>6BF7BE66110F170A002B3F46</string>
|
||||
<string>6BF7BE67110F170A002B3F46</string>
|
||||
<string>6BF7BE68110F170A002B3F46</string>
|
||||
<string>6BF7BE69110F170A002B3F46</string>
|
||||
<string>6BF7BE6A110F170A002B3F46</string>
|
||||
<string>6BF7BE6B110F170A002B3F46</string>
|
||||
<string>6BF7BE6C110F170A002B3F46</string>
|
||||
<string>6BF7BE6D110F170A002B3F46</string>
|
||||
<string>6BF7BE78110F1832002B3F46</string>
|
||||
<string>6BF7BE79110F1832002B3F46</string>
|
||||
<string>6BF7BE7A110F1832002B3F46</string>
|
||||
<string>6BF7BE7B110F1832002B3F46</string>
|
||||
<string>6BF7BE7C110F1832002B3F46</string>
|
||||
<string>6BF7BE7D110F1832002B3F46</string>
|
||||
<string>6BF7BE85110F196C002B3F46</string>
|
||||
<string>6BF7BE86110F196C002B3F46</string>
|
||||
<string>6BF7BE87110F196C002B3F46</string>
|
||||
<string>6BF7BE88110F196C002B3F46</string>
|
||||
<string>6BF7BE89110F196C002B3F46</string>
|
||||
<string>6BF7BE8A110F196C002B3F46</string>
|
||||
<string>6BF7BE8E110F1AFC002B3F46</string>
|
||||
<string>6BF7BE8F110F1AFC002B3F46</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>SplitCount</key>
|
||||
@ -652,18 +533,18 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {952, 547}}</string>
|
||||
<string>{{0, 0}, {876, 556}}</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>547pt</string>
|
||||
<string>556pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>Proportion</key>
|
||||
<string>109pt</string>
|
||||
<string>100pt</string>
|
||||
<key>Tabs</key>
|
||||
<array>
|
||||
<dict>
|
||||
@ -677,7 +558,7 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {952, 90}}</string>
|
||||
<string>{{10, 27}, {876, 88}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>XCDetailModule</string>
|
||||
@ -693,7 +574,9 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {952, 212}}</string>
|
||||
<string>{{10, 27}, {876, 73}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>11 76 1256 702 0 0 1280 778 </string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXProjectFindModule</string>
|
||||
@ -731,9 +614,7 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{10, 27}, {952, 82}}</string>
|
||||
<key>RubberWindowFrame</key>
|
||||
<string>11 76 1256 702 0 0 1280 778 </string>
|
||||
<string>{{10, 27}, {876, 125}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXBuildResultsModule</string>
|
||||
@ -742,7 +623,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>Proportion</key>
|
||||
<string>952pt</string>
|
||||
<string>876pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
@ -761,11 +642,11 @@
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>6BCF32211104C9F0009445BF</string>
|
||||
<string>6BF7BDEC110EF674002B3F46</string>
|
||||
<string>1CA23ED40692098700951B8B</string>
|
||||
<string>6BCF32221104C9F0009445BF</string>
|
||||
<string>6BF7BDED110EF674002B3F46</string>
|
||||
<string>6B8632A30F78115100E2684A</string>
|
||||
<string>6BCF32231104C9F0009445BF</string>
|
||||
<string>6BF7BDEE110EF674002B3F46</string>
|
||||
<string>1CA23EDF0692099D00951B8B</string>
|
||||
<string>1CA23EE00692099D00951B8B</string>
|
||||
<string>1CA23EE10692099D00951B8B</string>
|
||||
@ -816,12 +697,12 @@
|
||||
<key>GeometryConfiguration</key>
|
||||
<dict>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 0}, {1256, 209}}</string>
|
||||
<string>{{0, 0}, {1256, 367}}</string>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXDebugCLIModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>209pt</string>
|
||||
<string>367pt</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>ContentConfiguration</key>
|
||||
@ -840,8 +721,8 @@
|
||||
<string>yes</string>
|
||||
<key>sizes</key>
|
||||
<array>
|
||||
<string>{{0, 0}, {627, 93}}</string>
|
||||
<string>{{627, 0}, {629, 93}}</string>
|
||||
<string>{{0, 0}, {623, 80}}</string>
|
||||
<string>{{623, 0}, {633, 80}}</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>VerticalSplitView</key>
|
||||
@ -856,8 +737,8 @@
|
||||
<string>yes</string>
|
||||
<key>sizes</key>
|
||||
<array>
|
||||
<string>{{0, 0}, {1256, 93}}</string>
|
||||
<string>{{0, 93}, {1256, 354}}</string>
|
||||
<string>{{0, 0}, {1256, 80}}</string>
|
||||
<string>{{0, 76}, {1256, 213}}</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
@ -877,7 +758,7 @@
|
||||
<key>DebugSTDIOWindowFrame</key>
|
||||
<string>{{200, 200}, {500, 300}}</string>
|
||||
<key>Frame</key>
|
||||
<string>{{0, 214}, {1256, 447}}</string>
|
||||
<string>{{0, 372}, {1256, 289}}</string>
|
||||
<key>PBXDebugSessionStackFrameViewKey</key>
|
||||
<dict>
|
||||
<key>DebugVariablesTableConfiguration</key>
|
||||
@ -887,16 +768,16 @@
|
||||
<string>Value</string>
|
||||
<real>85</real>
|
||||
<string>Summary</string>
|
||||
<real>399</real>
|
||||
<real>403</real>
|
||||
</array>
|
||||
<key>Frame</key>
|
||||
<string>{{627, 0}, {629, 93}}</string>
|
||||
<string>{{623, 0}, {633, 80}}</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>Module</key>
|
||||
<string>PBXDebugSessionModule</string>
|
||||
<key>Proportion</key>
|
||||
<string>447pt</string>
|
||||
<string>289pt</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>Name</key>
|
||||
@ -914,14 +795,14 @@
|
||||
</array>
|
||||
<key>TableOfContents</key>
|
||||
<array>
|
||||
<string>6BCF32241104C9F0009445BF</string>
|
||||
<string>6BF7BDFC110EF76D002B3F46</string>
|
||||
<string>1CCC7628064C1048000F2A68</string>
|
||||
<string>1CCC7629064C1048000F2A68</string>
|
||||
<string>6BCF32251104C9F0009445BF</string>
|
||||
<string>6BCF32261104C9F0009445BF</string>
|
||||
<string>6BCF32271104C9F0009445BF</string>
|
||||
<string>6BCF32281104C9F0009445BF</string>
|
||||
<string>6BCF32291104C9F0009445BF</string>
|
||||
<string>6BF7BDFD110EF76D002B3F46</string>
|
||||
<string>6BF7BDFE110EF76D002B3F46</string>
|
||||
<string>6BF7BDFF110EF76D002B3F46</string>
|
||||
<string>6BF7BE00110EF76D002B3F46</string>
|
||||
<string>6BF7BE01110EF76D002B3F46</string>
|
||||
</array>
|
||||
<key>ToolbarConfigUserDefaultsMinorVersion</key>
|
||||
<string>2</string>
|
||||
@ -953,8 +834,8 @@
|
||||
<integer>5</integer>
|
||||
<key>WindowOrderList</key>
|
||||
<array>
|
||||
<string>6BCF32991104D1B2009445BF</string>
|
||||
<string>6BCF329A1104D1B2009445BF</string>
|
||||
<string>6BF7BE0B110EF794002B3F46</string>
|
||||
<string>6BF7BE0C110EF794002B3F46</string>
|
||||
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
|
||||
</array>
|
||||
<key>WindowString</key>
|
||||
|
@ -35,7 +35,8 @@ class NavMeshTesterTool : public SampleTool
|
||||
|
||||
enum ToolMode
|
||||
{
|
||||
TOOLMODE_PATHFIND,
|
||||
TOOLMODE_PATHFIND_ITER,
|
||||
TOOLMODE_PATHFIND_STRAIGHT,
|
||||
TOOLMODE_RAYCAST,
|
||||
TOOLMODE_DISTANCE_TO_WALL,
|
||||
TOOLMODE_FIND_POLYS_AROUND,
|
||||
|
@ -29,6 +29,7 @@ class OffMeshConnectionTool : public SampleTool
|
||||
float m_hitPos[3];
|
||||
bool m_hitPosSet;
|
||||
bool m_bidir;
|
||||
unsigned char m_oldFlags;
|
||||
|
||||
public:
|
||||
OffMeshConnectionTool();
|
||||
|
@ -89,6 +89,7 @@ public:
|
||||
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
||||
virtual void handleMeshChanged(class InputGeom* geom);
|
||||
virtual bool handleBuild();
|
||||
// virtual void handleNavMeshChanged();
|
||||
|
||||
virtual class InputGeom* getInputGeom() { return m_geom; }
|
||||
virtual class dtNavMesh* getNavMesh() { return m_navMesh; }
|
||||
|
@ -183,8 +183,8 @@ void InputGeom::deleteOffMeshConnection(int i)
|
||||
|
||||
void InputGeom::drawOffMeshConnections(duDebugDraw* dd, bool hilight)
|
||||
{
|
||||
unsigned int conColor = duRGBA(192,192,192,hilight?192:64);
|
||||
unsigned int baseColor = duRGBA(0,0,0,hilight?192:64);
|
||||
unsigned int conColor = duRGBA(192,0,128,192);
|
||||
unsigned int baseColor = duRGBA(0,0,0,64);
|
||||
dd->depthMask(false);
|
||||
|
||||
dd->begin(DU_DRAW_LINES, 2.0f);
|
||||
@ -200,9 +200,12 @@ void InputGeom::drawOffMeshConnections(duDebugDraw* dd, bool hilight)
|
||||
|
||||
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);
|
||||
|
||||
if (hilight)
|
||||
{
|
||||
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();
|
||||
|
||||
|
@ -49,7 +49,7 @@ NavMeshTesterTool::NavMeshTesterTool() :
|
||||
m_navMesh(0),
|
||||
m_agentRadius(0),
|
||||
m_agentHeight(0),
|
||||
m_toolMode(TOOLMODE_PATHFIND),
|
||||
m_toolMode(TOOLMODE_PATHFIND_ITER),
|
||||
m_startRef(0),
|
||||
m_endRef(0),
|
||||
m_npolys(0),
|
||||
@ -87,7 +87,7 @@ void NavMeshTesterTool::init(Sample* sample)
|
||||
m_navMesh = sample->getNavMesh();
|
||||
recalc();
|
||||
|
||||
if (m_toolMode == TOOLMODE_PATHFIND)
|
||||
if (m_toolMode == TOOLMODE_PATHFIND_ITER || m_toolMode == TOOLMODE_PATHFIND_STRAIGHT)
|
||||
{
|
||||
unsigned char flags = DU_DRAWNAVMESH_CLOSEDLIST;
|
||||
if (m_navMesh)
|
||||
@ -99,9 +99,14 @@ void NavMeshTesterTool::init(Sample* sample)
|
||||
|
||||
void NavMeshTesterTool::handleMenu()
|
||||
{
|
||||
if (imguiCheck("Pathfind", m_toolMode == TOOLMODE_PATHFIND))
|
||||
if (imguiCheck("Pathfind Iter", m_toolMode == TOOLMODE_PATHFIND_ITER))
|
||||
{
|
||||
m_toolMode = TOOLMODE_PATHFIND;
|
||||
m_toolMode = TOOLMODE_PATHFIND_ITER;
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Pathfind Straight", m_toolMode == TOOLMODE_PATHFIND_STRAIGHT))
|
||||
{
|
||||
m_toolMode = TOOLMODE_PATHFIND_STRAIGHT;
|
||||
recalc();
|
||||
}
|
||||
if (imguiCheck("Distance to Wall", m_toolMode == TOOLMODE_DISTANCE_TO_WALL))
|
||||
@ -148,7 +153,7 @@ void NavMeshTesterTool::handleMenu()
|
||||
recalc();
|
||||
}
|
||||
|
||||
if (m_toolMode == TOOLMODE_PATHFIND)
|
||||
if (m_toolMode == TOOLMODE_PATHFIND_ITER || m_toolMode == TOOLMODE_PATHFIND_STRAIGHT)
|
||||
{
|
||||
unsigned char flags = DU_DRAWNAVMESH_CLOSEDLIST;
|
||||
if (m_navMesh)
|
||||
@ -243,22 +248,16 @@ void NavMeshTesterTool::recalc()
|
||||
else
|
||||
m_endRef = 0;
|
||||
|
||||
if (m_toolMode == TOOLMODE_PATHFIND)
|
||||
if (m_toolMode == TOOLMODE_PATHFIND_ITER)
|
||||
{
|
||||
if (m_sposSet && m_eposSet && m_startRef && m_endRef)
|
||||
{
|
||||
m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS);
|
||||
|
||||
m_nstraightPath = 0;
|
||||
m_nsmoothPath = 0;
|
||||
|
||||
if (m_npolys)
|
||||
{
|
||||
m_nstraightPath = m_navMesh->findStraightPath(m_spos, m_epos, m_polys, m_npolys,
|
||||
m_straightPath, m_straightPathFlags,
|
||||
m_straightPathPolys, MAX_POLYS);
|
||||
|
||||
|
||||
// Iterate over the path to find smooth path on the detail mesh surface.
|
||||
const dtPolyRef* polys = m_polys;
|
||||
int npolys = m_npolys;
|
||||
@ -380,10 +379,28 @@ void NavMeshTesterTool::recalc()
|
||||
else
|
||||
{
|
||||
m_npolys = 0;
|
||||
m_nstraightPath = 0;
|
||||
m_nsmoothPath = 0;
|
||||
}
|
||||
}
|
||||
else if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT)
|
||||
{
|
||||
if (m_sposSet && m_eposSet && m_startRef && m_endRef)
|
||||
{
|
||||
m_npolys = m_navMesh->findPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, m_polys, MAX_POLYS);
|
||||
m_nstraightPath = 0;
|
||||
if (m_npolys)
|
||||
{
|
||||
m_nstraightPath = m_navMesh->findStraightPath(m_spos, m_epos, m_polys, m_npolys,
|
||||
m_straightPath, m_straightPathFlags,
|
||||
m_straightPathPolys, MAX_POLYS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_npolys = 0;
|
||||
m_nstraightPath = 0;
|
||||
}
|
||||
}
|
||||
else if (m_toolMode == TOOLMODE_RAYCAST)
|
||||
{
|
||||
m_nstraightPath = 0;
|
||||
@ -463,7 +480,27 @@ void NavMeshTesterTool::handleRender()
|
||||
if (m_eposSet)
|
||||
drawAgent(m_epos, m_agentRadius, m_agentHeight, 0/*m_agentMaxClimb*/, endCol);
|
||||
|
||||
if (m_toolMode == TOOLMODE_PATHFIND)
|
||||
if (m_toolMode == TOOLMODE_PATHFIND_ITER)
|
||||
{
|
||||
duDebugDrawNavMeshPoly(&dd, m_navMesh, m_startRef, startCol);
|
||||
duDebugDrawNavMeshPoly(&dd, m_navMesh, m_endRef, endCol);
|
||||
|
||||
if (m_npolys)
|
||||
{
|
||||
for (int i = 1; i < m_npolys-1; ++i)
|
||||
duDebugDrawNavMeshPoly(&dd, m_navMesh, m_polys[i], pathCol);
|
||||
}
|
||||
|
||||
if (m_nsmoothPath)
|
||||
{
|
||||
const unsigned int pathCol = duRGBA(0,0,0,220);
|
||||
dd.begin(DU_DRAW_LINES, 3.0f);
|
||||
for (int i = 0; i < m_nsmoothPath; ++i)
|
||||
dd.vertex(m_smoothPath[i*3], m_smoothPath[i*3+1]+0.1f, m_smoothPath[i*3+2], pathCol);
|
||||
dd.end();
|
||||
}
|
||||
}
|
||||
else if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT)
|
||||
{
|
||||
duDebugDrawNavMeshPoly(&dd, m_navMesh, m_startRef, startCol);
|
||||
duDebugDrawNavMeshPoly(&dd, m_navMesh, m_endRef, endCol);
|
||||
@ -506,19 +543,6 @@ void NavMeshTesterTool::handleRender()
|
||||
dd.vertex(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2], pathCol);
|
||||
}
|
||||
dd.end();
|
||||
|
||||
/* for (int i = 1; i < m_nstraightPath-1; ++i)
|
||||
{
|
||||
duDebugDrawNavMeshPoly(&dd, m_navMesh, m_straightPathPolys[i], duRGBA(255,255,255,64));
|
||||
}*/
|
||||
}
|
||||
if (m_nsmoothPath)
|
||||
{
|
||||
const unsigned int pathCol = duRGBA(0,0,0,220);
|
||||
dd.begin(DU_DRAW_LINES, 3.0f);
|
||||
for (int i = 0; i < m_nsmoothPath; ++i)
|
||||
dd.vertex(m_smoothPath[i*3], m_smoothPath[i*3+1]+0.1f, m_smoothPath[i*3+2], pathCol);
|
||||
dd.end();
|
||||
}
|
||||
}
|
||||
else if (m_toolMode == TOOLMODE_RAYCAST)
|
||||
|
@ -38,19 +38,27 @@
|
||||
OffMeshConnectionTool::OffMeshConnectionTool() :
|
||||
m_sample(0),
|
||||
m_hitPosSet(0),
|
||||
m_bidir(true)
|
||||
m_bidir(true),
|
||||
m_oldFlags(0)
|
||||
{
|
||||
}
|
||||
|
||||
OffMeshConnectionTool::~OffMeshConnectionTool()
|
||||
{
|
||||
if (m_sample)
|
||||
{
|
||||
m_sample->setNavMeshDrawFlags(m_oldFlags);
|
||||
}
|
||||
}
|
||||
|
||||
void OffMeshConnectionTool::init(Sample* sample)
|
||||
{
|
||||
m_sample = sample;
|
||||
if (m_sample)
|
||||
m_sample->setNavMeshDrawFlags(0);
|
||||
{
|
||||
m_oldFlags = m_sample->getNavMeshDrawFlags();
|
||||
m_sample->setNavMeshDrawFlags(m_oldFlags & ~DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
}
|
||||
}
|
||||
|
||||
void OffMeshConnectionTool::reset()
|
||||
@ -104,6 +112,8 @@ void OffMeshConnectionTool::handleClick(const float* p, bool shift)
|
||||
{
|
||||
geom->deleteOffMeshConnection(nearestIndex);
|
||||
}
|
||||
|
||||
// geom->updateOffMeshConnectionVisibility(m_sample->getNavMesh());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -117,6 +127,7 @@ void OffMeshConnectionTool::handleClick(const float* p, bool shift)
|
||||
{
|
||||
geom->addOffMeshConnection(m_hitPos, p, m_sample->getAgentRadius(), m_bidir ? 1 : 0);
|
||||
m_hitPosSet = false;
|
||||
// geom->updateOffMeshConnectionVisibility(m_sample->getNavMesh());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ void DebugDrawGL::end()
|
||||
Sample::Sample() :
|
||||
m_geom(0),
|
||||
m_navMesh(0),
|
||||
m_navMeshDrawFlags(DU_DRAWNAVMESH_CLOSEDLIST),
|
||||
m_navMeshDrawFlags(DU_DRAWNAVMESH_CLOSEDLIST|DU_DRAWNAVMESH_OFFMESHCONS),
|
||||
m_tool(0)
|
||||
{
|
||||
resetCommonSettings();
|
||||
@ -209,3 +209,11 @@ bool Sample::handleBuild()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
void Sample::handleNavMeshChanged()
|
||||
{
|
||||
if (m_geom)
|
||||
m_geom->updateOffMeshConnectionVisibility(m_navMesh);
|
||||
}
|
||||
*/
|
@ -197,16 +197,14 @@ 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);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
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);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
}
|
||||
|
||||
glDisable(GL_FOG);
|
||||
@ -312,8 +310,10 @@ void Sample_SoloMeshSimple::handleRenderOverlay(double* proj, double* model, int
|
||||
void Sample_SoloMeshSimple::handleMeshChanged(class InputGeom* geom)
|
||||
{
|
||||
Sample::handleMeshChanged(geom);
|
||||
|
||||
delete m_navMesh;
|
||||
m_navMesh = 0;
|
||||
|
||||
if (m_tool)
|
||||
{
|
||||
m_tool->reset();
|
||||
@ -638,8 +638,6 @@ 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);
|
||||
|
@ -231,16 +231,14 @@ 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);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
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);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
}
|
||||
|
||||
glDisable(GL_FOG);
|
||||
@ -556,8 +554,13 @@ void Sample_SoloMeshTiled::handleRenderOverlay(double* proj, double* model, int*
|
||||
void Sample_SoloMeshTiled::handleMeshChanged(class InputGeom* geom)
|
||||
{
|
||||
Sample::handleMeshChanged(geom);
|
||||
|
||||
delete m_navMesh;
|
||||
m_navMesh = 0;
|
||||
|
||||
m_statTimePerTileSamples = 0;
|
||||
m_statPolysPerTileSamples = 0;
|
||||
|
||||
if (m_tool)
|
||||
{
|
||||
m_tool->reset();
|
||||
@ -937,10 +940,10 @@ bool Sample_SoloMeshTiled::handleBuild()
|
||||
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.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;
|
||||
@ -1013,8 +1016,6 @@ 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);
|
||||
|
||||
|
@ -311,8 +311,7 @@ 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);
|
||||
if ((m_navMeshDrawFlags & DU_DRAWNAVMESH_OFFMESHCONS) == 0)
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
@ -363,9 +362,10 @@ void Sample_TileMesh::handleMeshChanged(class InputGeom* geom)
|
||||
Sample::handleMeshChanged(geom);
|
||||
|
||||
cleanup();
|
||||
|
||||
delete m_navMesh;
|
||||
m_navMesh = 0;
|
||||
|
||||
|
||||
if (m_tool)
|
||||
{
|
||||
m_tool->reset();
|
||||
@ -404,8 +404,6 @@ bool Sample_TileMesh::handleBuild()
|
||||
if (m_buildAll)
|
||||
buildAllTiles();
|
||||
|
||||
setNavMeshDrawFlags(DU_DRAWNAVMESH_OFFMESHCONS);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->init(this);
|
||||
|
||||
@ -796,10 +794,10 @@ unsigned char* Sample_TileMesh::buildTileMesh(const float* bmin, const float* bm
|
||||
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.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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user