diff --git a/Detour/Include/DetourCommon.h b/Detour/Include/DetourCommon.h index 3bd2c09a..d824efc0 100644 --- a/Detour/Include/DetourCommon.h +++ b/Detour/Include/DetourCommon.h @@ -153,6 +153,8 @@ inline bool checkOverlapBox(const unsigned short amin[3], const unsigned short a void closestPtPointTriangle(float* closest, const float* p, const float* a, const float* b, const float* c); +bool closestHeightPointTriangle(const float* p, const float* a, const float* b, const float* c, float& h); + bool intersectSegmentPoly2D(const float* p0, const float* p1, const float* verts, int nverts, float& tmin, float& tmax, diff --git a/Detour/Include/DetourStatNavMesh.h b/Detour/Include/DetourStatNavMesh.h index a84eb6ae..71ee4cb0 100755 --- a/Detour/Include/DetourStatNavMesh.h +++ b/Detour/Include/DetourStatNavMesh.h @@ -34,8 +34,16 @@ struct dtStatPoly unsigned char flags; // Flags (not used). }; +struct dtStatPolyDetail +{ + unsigned short vbase; // Offset to detail vertex array. + unsigned short nverts; // Number of vertices in the detail mesh. + unsigned short tbase; // Offset to detail triangle array. + unsigned short ntris; // Number of triangles. +}; + const int DT_STAT_NAVMESH_MAGIC = 'NAVM'; -const int DT_STAT_NAVMESH_VERSION = 2; +const int DT_STAT_NAVMESH_VERSION = 3; struct dtStatBVNode { @@ -50,11 +58,17 @@ struct dtStatNavMeshHeader int npolys; int nverts; int nnodes; + int ndmeshes; + int ndverts; + int ndtris; float cs; float bmin[3], bmax[3]; dtStatPoly* polys; float* verts; dtStatBVNode* bvtree; + dtStatPolyDetail* dmeshes; + float* dverts; + unsigned char* dtris; }; class dtStatNavMesh @@ -160,8 +174,18 @@ public: // Returns: true if closest point found. bool closestPointToPoly(dtStatPolyRef ref, const float* pos, float* closest) const; + // Returns height of the polygon at specified location. + // Params: + // ref - (in) ref to the polygon. + // pos - (in) the point where to locate the height. + // height - (out) height at the location. + // Returns: true if oer polygon. + bool getPolyHeight(dtStatPolyRef ref, const float* pos, float* height) const; + // Returns pointer to a polygon based on ref. const dtStatPoly* getPolyByRef(dtStatPolyRef ref) const; + // Returns polygon index based on ref, or -1 if failed. + int getPolyIndexByRef(dtStatPolyRef ref) const; // Returns number of navigation polygons. inline int getPolyCount() const { return m_header ? m_header->npolys : 0; } // Rerturns pointer to specified navigation polygon. @@ -170,6 +194,14 @@ public: inline int getVertexCount() const { return m_header ? m_header->nverts : 0; } // Returns pointer to specified vertex. inline const float* getVertex(int i) const { return &m_header->verts[i*3]; } + // Returns number of navigation polygons details. + inline int getPolyDetailCount() const { return m_header ? m_header->ndmeshes : 0; } + // Rerturns pointer to specified navigation polygon detail. + const dtStatPolyDetail* getPolyDetail(int i) const { return &m_header->dmeshes[i]; } + // Returns pointer to specified vertex. + inline const float* getDetailVertex(int i) const { return &m_header->dverts[i*3]; } + // Returns pointer to specified vertex. + inline const unsigned char* getDetailTri(int i) const { return &m_header->dtris[i*4]; } bool isInClosedList(dtStatPolyRef ref) const; diff --git a/Detour/Include/DetourStatNavMeshBuilder.h b/Detour/Include/DetourStatNavMeshBuilder.h index 34e8dc07..3b8f7519 100755 --- a/Detour/Include/DetourStatNavMeshBuilder.h +++ b/Detour/Include/DetourStatNavMeshBuilder.h @@ -22,6 +22,8 @@ bool dtCreateNavMeshData(const unsigned short* verts, const int nverts, const unsigned short* polys, const int npolys, const int nvp, const float* bmin, const float* bmax, float cs, float ch, + const unsigned short* dmeshes, const float* dverts, const int ndverts, + const unsigned char* dtris, const int ndtris, unsigned char** outData, int* outDataSize); #endif // DETOURSTATNAVMESHBUILDER_H \ No newline at end of file diff --git a/Detour/Include/DetourTileNavMesh.h b/Detour/Include/DetourTileNavMesh.h index 6b330e6f..d615b174 100644 --- a/Detour/Include/DetourTileNavMesh.h +++ b/Detour/Include/DetourTileNavMesh.h @@ -37,7 +37,7 @@ static const int DT_MAX_TILES = 1 << DT_TILE_REF_TILE_BITS; static const int DT_MAX_POLYGONS = 1 << DT_TILE_REF_POLY_BITS; static const int DT_TILE_NAVMESH_MAGIC = 'NAVT'; -static const int DT_TILE_NAVMESH_VERSION = 1; +static const int DT_TILE_NAVMESH_VERSION = 2; // Structure holding the navigation polygon data. struct dtTilePoly @@ -50,6 +50,14 @@ struct dtTilePoly unsigned char flags; // Flags (not used). }; +struct dtTilePolyDetail +{ + unsigned short vbase; // Offset to detail vertex array. + unsigned short nverts; // Number of vertices in the detail mesh. + unsigned short tbase; // Offset to detail triangle array. + unsigned short ntris; // Number of triangles. +}; + // Stucture holding a link to another polygon. struct dtTileLink { @@ -68,10 +76,16 @@ struct dtTileHeader int nverts; // Number of vertices in the tile. int nlinks; // Number of links in the tile (will be updated when tile is added). int maxlinks; // Number of allocated links. + int ndmeshes; + int ndverts; + int ndtris; float bmin[3], bmax[3]; // Bounding box of the tile. dtTilePoly* polys; // Pointer to the polygons (will be updated when tile is added). float* verts; // Pointer to the vertices (will be updated when tile added). dtTileLink* links; // Pointer to the links (will be updated when tile added). + dtTilePolyDetail* dmeshes; + float* dverts; + unsigned char* dtris; }; struct dtTile @@ -236,6 +250,14 @@ public: // Returns: true if closest point found. bool closestPointToPoly(dtTilePolyRef ref, const float* pos, float* closest) const; + // Returns height of the polygon at specified location. + // Params: + // ref - (in) ref to the polygon. + // pos - (in) the point where to locate the height. + // height - (out) height at the location. + // Returns: true if over polygon. + bool getPolyHeight(dtTilePolyRef ref, const float* pos, float* height) const; + // Returns pointer to a polygon based on ref. const dtTilePoly* getPolyByRef(dtTilePolyRef ref) const; diff --git a/Detour/Include/DetourTileNavMeshBuilder.h b/Detour/Include/DetourTileNavMeshBuilder.h index fc90bc55..643dec1e 100644 --- a/Detour/Include/DetourTileNavMeshBuilder.h +++ b/Detour/Include/DetourTileNavMeshBuilder.h @@ -21,6 +21,8 @@ bool dtCreateNavMeshTileData(const unsigned short* verts, const int nverts, const unsigned short* polys, const int npolys, const int nvp, + const unsigned short* dmeshes, const float* dverts, const int ndverts, + const unsigned char* dtris, const int ndtris, const float* bmin, const float* bmax, float cs, float ch, int tileSize, int walkableClimb, unsigned char** outData, int* outDataSize); diff --git a/Detour/Source/DetourCommon.cpp b/Detour/Source/DetourCommon.cpp index 1e34a52f..e55ce5e6 100644 --- a/Detour/Source/DetourCommon.cpp +++ b/Detour/Source/DetourCommon.cpp @@ -203,3 +203,42 @@ void calcPolyCenter(float* tc, const unsigned short* idx, int nidx, const float* tc[1] *= s; tc[2] *= s; } + +inline float vdot2(const float* a, const float* b) +{ + return a[0]*b[0] + a[2]*b[2]; +} + +#include + +bool closestHeightPointTriangle(const float* p, const float* a, const float* b, const float* c, float& h) +{ + float v0[3], v1[3], v2[3]; + vsub(v0, c,a); + vsub(v1, b,a); + vsub(v2, p,a); + + const float dot00 = vdot2(v0, v0); + const float dot01 = vdot2(v0, v1); + const float dot02 = vdot2(v0, v2); + const float dot11 = vdot2(v1, v1); + const float dot12 = vdot2(v1, v2); + + // Compute barycentric coordinates + float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); + float u = (dot11 * dot02 - dot01 * dot12) * invDenom; + float v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + // The (sloppy) epsilon is needed to allow to get height of points which + // are interpolated along the edges of the triangles. + static const float EPS = 1e-4f; + + // If point lies inside the triangle, return interpolated ycoord. + if (u >= -EPS && v >= -EPS && (u+v) <= 1+EPS) + { + h = a[1] + v0[1]*u + v1[1]*v; + return true; + } + + return false; +} diff --git a/Detour/Source/DetourDebugDraw.cpp b/Detour/Source/DetourDebugDraw.cpp index 1c0f3805..25f32f12 100755 --- a/Detour/Source/DetourDebugDraw.cpp +++ b/Detour/Source/DetourDebugDraw.cpp @@ -23,24 +23,47 @@ void dtDebugDrawStatNavMeshPoly(const dtStatNavMesh* mesh, dtStatPolyRef ref, const float* col) { - const dtStatPoly* p = mesh->getPolyByRef(ref); - if (!p) - return; + int idx = mesh->getPolyIndexByRef(ref); + if (idx == -1) return; + glColor4f(col[0],col[1],col[2],0.25f); - glBegin(GL_TRIANGLES); - unsigned short vi[3]; - for (int j = 2; j < (int)p->nv; ++j) + + if (mesh->getPolyDetailCount()) { - vi[0] = p->v[0]; - vi[1] = p->v[j-1]; - vi[2] = p->v[j]; - for (int k = 0; k < 3; ++k) + const dtStatPoly* p = mesh->getPoly(idx); + const dtStatPolyDetail* pd = mesh->getPolyDetail(idx); + glBegin(GL_TRIANGLES); + for (int j = 0; j < pd->ntris; ++j) { - const float* v = mesh->getVertex(vi[k]); - glVertex3f(v[0], v[1]+0.2f, v[2]); + const unsigned char* t = mesh->getDetailTri(pd->tbase+j); + for (int k = 0; k < 3; ++k) + { + if (t[k] < p->nv) + glVertex3fv(mesh->getVertex(p->v[t[k]])); + else + glVertex3fv(mesh->getDetailVertex(pd->vbase+(t[k]-p->nv))); + } } + glEnd(); + } + else + { + const dtStatPoly* p = mesh->getPoly(idx); + glBegin(GL_TRIANGLES); + unsigned short vi[3]; + for (int j = 2; j < (int)p->nv; ++j) + { + vi[0] = p->v[0]; + vi[1] = p->v[j-1]; + vi[2] = p->v[j]; + for (int k = 0; k < 3; ++k) + { + const float* v = mesh->getVertex(vi[k]); + glVertex3f(v[0], v[1]+0.2f, v[2]); + } + } + glEnd(); } - glEnd(); } static void drawBoxWire(float minx, float miny, float minz, float maxx, float maxy, float maxz, const float* col) @@ -103,76 +126,113 @@ void dtDebugDrawStatNavMeshBVTree(const dtStatNavMesh* mesh) glEnd(); } -void dtDebugDrawStatNavMesh(const dtStatNavMesh* mesh, bool drawClosedList) + +static float distancePtLine2d(const float* pt, const float* p, const float* q) { - glBegin(GL_TRIANGLES); + float pqx = q[0] - p[0]; + float pqz = q[2] - p[2]; + float dx = pt[0] - p[0]; + float dz = pt[2] - p[2]; + float d = pqx*pqx + pqz*pqz; + float t = pqx*dx + pqz*dz; + if (d != 0) t /= d; + dx = p[0] + t*pqx - pt[0]; + dz = p[2] + t*pqz - pt[2]; + return dx*dx + dz*dz; +} + +static void drawStatMeshPolyBoundaries(const dtStatNavMesh* mesh, bool inner) +{ + static const float thr = 0.01f*0.01f; + + glBegin(GL_LINES); for (int i = 0; i < mesh->getPolyCount(); ++i) { const dtStatPoly* p = mesh->getPoly(i); + const dtStatPolyDetail* pd = mesh->getPolyDetail(i); + + for (int j = 0, nj = (int)p->nv; j < nj; ++j) + { + if (inner) + { + // Skip non-connected edges. + if (p->n[j] == 0) continue; + } + else + { + // Skip connected edges. + if (p->n[j] != 0) continue; + } + + const float* v0 = mesh->getVertex(p->v[j]); + const float* v1 = mesh->getVertex(p->v[(j+1) % nj]); + + // Draw detail mesh edges which align with the actual poly edge. + // This is really slow. + for (int k = 0; k < pd->ntris; ++k) + { + const unsigned char* t = mesh->getDetailTri(pd->tbase+k); + const float* tv[3]; + for (int m = 0; m < 3; ++m) + { + if (t[m] < p->nv) + tv[m] = mesh->getVertex(p->v[t[m]]); + else + tv[m] = mesh->getDetailVertex(pd->vbase+(t[m]-p->nv)); + } + for (int m = 0, n = 2; m < 3; n=m++) + { + if (((t[3] >> (n*2)) & 0x3) == 0) continue; // Skip inner edges. + if (distancePtLine2d(tv[n],v0,v1) < thr && + distancePtLine2d(tv[m],v0,v1) < thr) + { + glVertex3fv(tv[n]); + glVertex3fv(tv[m]); + } + } + } + } + } + glEnd(); +} + +void dtDebugDrawStatNavMesh(const dtStatNavMesh* mesh, bool drawClosedList) +{ + glBegin(GL_TRIANGLES); + for (int i = 0; i < mesh->getPolyDetailCount(); ++i) + { + const dtStatPoly* p = mesh->getPoly(i); + const dtStatPolyDetail* pd = mesh->getPolyDetail(i); if (drawClosedList && mesh->isInClosedList(i+1)) glColor4ub(255,196,0,64); else glColor4ub(0,196,255,64); - - unsigned short vi[3]; - for (int j = 2; j < (int)p->nv; ++j) + + for (int j = 0; j < pd->ntris; ++j) { - vi[0] = p->v[0]; - vi[1] = p->v[j-1]; - vi[2] = p->v[j]; + const unsigned char* t = mesh->getDetailTri(pd->tbase+j); for (int k = 0; k < 3; ++k) { - const float* v = mesh->getVertex(vi[k]); - glVertex3f(v[0], v[1]+0.2f, v[2]); + if (t[k] < p->nv) + glVertex3fv(mesh->getVertex(p->v[t[k]])); + else + glVertex3fv(mesh->getDetailVertex(pd->vbase+(t[k]-p->nv))); } } } glEnd(); - // Draw tri boundaries + // Draw inter poly boundaries glColor4ub(0,48,64,32); glLineWidth(1.5f); - glBegin(GL_LINES); - for (int i = 0; i < mesh->getPolyCount(); ++i) - { - const dtStatPoly* p = mesh->getPoly(i); - for (int j = 0, nj = (int)p->nv; j < nj; ++j) - { - if (p->n[j] == 0) continue; - int vi[2]; - vi[0] = p->v[j]; - vi[1] = p->v[(j+1) % nj]; - for (int k = 0; k < 2; ++k) - { - const float* v = mesh->getVertex(vi[k]); - glVertex3f(v[0], v[1]+0.21f, v[2]); - } - } - } - glEnd(); + drawStatMeshPolyBoundaries(mesh, true); - // Draw boundaries + // Draw outer poly boundaries glLineWidth(2.5f); glColor4ub(0,48,64,220); - glBegin(GL_LINES); - for (int i = 0; i < mesh->getPolyCount(); ++i) - { - const dtStatPoly* p = mesh->getPoly(i); - for (int j = 0, nj = (int)p->nv; j < nj; ++j) - { - if (p->n[j] != 0) continue; - int vi[2]; - vi[0] = p->v[j]; - vi[1] = p->v[(j+1) % nj]; - for (int k = 0; k < 2; ++k) - { - const float* v = mesh->getVertex(vi[k]); - glVertex3f(v[0], v[1]+0.21f, v[2]); - } - } - } - glEnd(); + drawStatMeshPolyBoundaries(mesh, false); + glLineWidth(1.0f); glPointSize(3.0f); @@ -181,116 +241,120 @@ void dtDebugDrawStatNavMesh(const dtStatNavMesh* mesh, bool drawClosedList) for (int i = 0; i < mesh->getVertexCount(); ++i) { const float* v = mesh->getVertex(i); - glVertex3f(v[0], v[1]+0.21f, v[2]); + glVertex3f(v[0], v[1], v[2]); } glEnd(); glPointSize(1.0f); } +static void drawTilePolyBoundaries(const dtTileHeader* header, bool inner) +{ + static const float thr = 0.01f*0.01f; + + glBegin(GL_LINES); + for (int i = 0; i < header->npolys; ++i) + { + const dtTilePoly* p = &header->polys[i]; + const dtTilePolyDetail* pd = &header->dmeshes[i]; + + for (int j = 0, nj = (int)p->nv; j < nj; ++j) + { + if (inner) + { + if (p->n[j] == 0) continue; + if (p->n[j] & 0x8000) + { + bool con = false; + for (int k = 0; k < p->nlinks; ++k) + { + if (header->links[p->links+k].e == j) + { + con = true; + break; + } + } + if (con) + glColor4ub(255,255,255,128); + else + glColor4ub(0,0,0,128); + } + else + glColor4ub(0,48,64,32); + } + else + { + if (p->n[j] != 0) continue; + } + + const float* v0 = &header->verts[p->v[j]*3]; + const float* v1 = &header->verts[p->v[(j+1)%nj]*3]; + + // Draw detail mesh edges which align with the actual poly edge. + // This is really slow. + for (int k = 0; k < pd->ntris; ++k) + { + const unsigned char* t = &header->dtris[(pd->tbase+k)*4]; + const float* tv[3]; + for (int m = 0; m < 3; ++m) + { + if (t[m] < p->nv) + tv[m] = &header->verts[p->v[t[m]]*3]; + else + tv[m] = &header->dverts[(pd->vbase+(t[m]-p->nv))*3]; + } + for (int m = 0, n = 2; m < 3; n=m++) + { + if (((t[3] >> (n*2)) & 0x3) == 0) continue; // Skip inner detail edges. + if (distancePtLine2d(tv[n],v0,v1) < thr && + distancePtLine2d(tv[m],v0,v1) < thr) + { + glVertex3fv(tv[n]); + glVertex3fv(tv[m]); + } + } + } + } + } + glEnd(); +} + static void drawTile(const dtTileHeader* header) { glBegin(GL_TRIANGLES); for (int i = 0; i < header->npolys; ++i) { const dtTilePoly* p = &header->polys[i]; + const dtTilePolyDetail* pd = &header->dmeshes[i]; glColor4ub(0,196,255,64); - unsigned short vi[3]; - for (int j = 2; j < (int)p->nv; ++j) + for (int j = 0; j < pd->ntris; ++j) { - vi[0] = p->v[0]; - vi[1] = p->v[j-1]; - vi[2] = p->v[j]; + const unsigned char* t = &header->dtris[(pd->tbase+j)*4]; for (int k = 0; k < 3; ++k) { - const float* v = &header->verts[vi[k]*3]; - glVertex3f(v[0], v[1]+0.2f, v[2]); - } - } - } - glEnd(); - - // Draw tri boundaries - glLineWidth(1.5f); - glBegin(GL_LINES); - for (int i = 0; i < header->npolys; ++i) - { - const dtTilePoly* p = &header->polys[i]; - for (int j = 0, nj = (int)p->nv; j < nj; ++j) - { - if (p->n[j] == 0) continue; - if (p->n[j] & 0x8000) - { - bool con = false; - for (int k = 0; k < p->nlinks; ++k) - { - if (header->links[p->links+k].e == j) - { - con = true; - break; - } - } - if (con) - glColor4ub(255,255,255,128); + if (t[k] < p->nv) + glVertex3fv(&header->verts[p->v[t[k]]*3]); else - glColor4ub(0,0,0,128); - } - else - glColor4ub(0,48,64,32); - /* - { - // Portal - int side = (p->n[j] >> 13) & 3; - int i = p->n[j] & 0x1fff; - if (!header->portals[side][i].ncon) continue; - }*/ - - int vi[2]; - vi[0] = p->v[j]; - vi[1] = p->v[(j+1) % nj]; - for (int k = 0; k < 2; ++k) - { - const float* v = &header->verts[vi[k]*3]; - glVertex3f(v[0], v[1]+0.21f, v[2]); + glVertex3fv(&header->dverts[(pd->vbase+t[k]-p->nv)*3]); } } } glEnd(); - // Draw boundaries + // Draw inter poly boundaries + glColor4ub(0,48,64,32); + glLineWidth(1.5f); + + drawTilePolyBoundaries(header, true); + + // Draw outer poly boundaries glLineWidth(2.5f); glColor4ub(0,48,64,220); - glBegin(GL_LINES); - for (int i = 0; i < header->npolys; ++i) - { - const dtTilePoly* p = &header->polys[i]; - for (int j = 0, nj = (int)p->nv; j < nj; ++j) - { - if (p->n[j] != 0) - { -/* if (p->n[j] & 0x8000) - { - // Portal - int side = (p->n[j] >> 13) & 3; - int i = p->n[j] & 0x1fff; - if (header->portals[side][i].ncon) continue; - } - else*/ - continue; - } - int vi[2]; - vi[0] = p->v[j]; - vi[1] = p->v[(j+1) % nj]; - for (int k = 0; k < 2; ++k) - { - const float* v = &header->verts[vi[k]*3]; - glVertex3f(v[0], v[1]+0.21f, v[2]); - } - } - } - glEnd(); + + drawTilePolyBoundaries(header, false); + glLineWidth(1.0f); glPointSize(3.0f); @@ -299,10 +363,10 @@ static void drawTile(const dtTileHeader* header) for (int i = 0; i < header->nverts; ++i) { const float* v = &header->verts[i*3]; - glVertex3f(v[0], v[1]+0.21f, v[2]); + glVertex3f(v[0], v[1], v[2]); } glEnd(); - glPointSize(1.0f); + glPointSize(1.0f); // Draw portals /* glBegin(GL_LINES); @@ -401,21 +465,30 @@ void dtDebugDrawTiledNavMesh(const dtTiledNavMesh* mesh) void dtDebugDrawTiledNavMeshPoly(const dtTiledNavMesh* mesh, dtTilePolyRef ref, const float* col) { - const dtTilePoly* p = mesh->getPolyByRef(ref); - if (!p) return; - const float* verts = mesh->getPolyVertsByRef(ref); + unsigned int salt, it, ip; + dtDecodeTileId(ref, salt, it, ip); + if (it >= DT_MAX_TILES) return; + const dtTile* tile = mesh->getTile(it); + if (tile->salt != salt || tile->header == 0) return; + const dtTileHeader* header = tile->header; + + if (ip >= (unsigned int)header->npolys) return; + glColor4f(col[0],col[1],col[2],0.25f); + + const dtTilePoly* p = &header->polys[ip]; + const dtTilePolyDetail* pd = &header->dmeshes[ip]; + glBegin(GL_TRIANGLES); - unsigned short vi[3]; - for (int j = 2; j < (int)p->nv; ++j) + for (int i = 0; i < pd->ntris; ++i) { - vi[0] = p->v[0]; - vi[1] = p->v[j-1]; - vi[2] = p->v[j]; - for (int k = 0; k < 3; ++k) + const unsigned char* t = &header->dtris[(pd->tbase+i)*4]; + for (int j = 0; j < 3; ++j) { - const float* v = &verts[vi[k]*3]; - glVertex3f(v[0], v[1]+0.2f, v[2]); + if (t[j] < p->nv) + glVertex3fv(&header->verts[p->v[t[j]]*3]); + else + glVertex3fv(&header->dverts[(pd->vbase+t[j]-p->nv)*3]); } } glEnd(); diff --git a/Detour/Source/DetourStatNavMesh.cpp b/Detour/Source/DetourStatNavMesh.cpp index 25c98d95..bf59cd89 100755 --- a/Detour/Source/DetourStatNavMesh.cpp +++ b/Detour/Source/DetourStatNavMesh.cpp @@ -55,10 +55,19 @@ bool dtStatNavMesh::init(unsigned char* data, int dataSize, bool ownsData) const int headerSize = sizeof(dtStatNavMeshHeader); const int vertsSize = sizeof(float)*3*header->nverts; const int polysSize = sizeof(dtStatPoly)*header->npolys; + const int nodesSize = sizeof(dtStatBVNode)*header->npolys*2; + const int detailMeshesSize = sizeof(dtStatPolyDetail)*header->ndmeshes; + const int detailVertsSize = sizeof(float)*3*header->ndverts; + const int detailTrisSize = sizeof(unsigned char)*4*header->ndtris; - header->verts = (float*)(data + headerSize); - header->polys = (dtStatPoly*)(data + headerSize + vertsSize); - header->bvtree = (dtStatBVNode*)(data + headerSize + vertsSize + polysSize); + + unsigned char* d = data + headerSize; + header->verts = (float*)d; d += vertsSize; + header->polys = (dtStatPoly*)d; d += polysSize; + header->bvtree = (dtStatBVNode*)d; d += nodesSize; + header->dmeshes = (dtStatPolyDetail*)d; d += detailMeshesSize; + header->dverts = (float*)d; d += detailVertsSize; + header->dtris = (unsigned char*)d; d += detailTrisSize; m_nodePool = new dtNodePool(2048, 256); if (!m_nodePool) @@ -85,6 +94,12 @@ const dtStatPoly* dtStatNavMesh::getPolyByRef(dtStatPolyRef ref) const return &m_header->polys[ref-1]; } +int dtStatNavMesh::getPolyIndexByRef(dtStatPolyRef ref) const +{ + if (!m_header || ref == 0 || (int)ref > m_header->npolys) return -1; + return (int)ref-1; +} + int dtStatNavMesh::findPath(dtStatPolyRef startRef, dtStatPolyRef endRef, const float* startPos, const float* endPos, dtStatPolyRef* path, const int maxPathSize) @@ -219,20 +234,27 @@ int dtStatNavMesh::findPath(dtStatPolyRef startRef, dtStatPolyRef endRef, bool dtStatNavMesh::closestPointToPoly(dtStatPolyRef ref, const float* pos, float* closest) const { - const dtStatPoly* poly = getPolyByRef(ref); - if (!poly) + int idx = getPolyIndexByRef(ref); + if (idx == -1) return false; float closestDistSqr = FLT_MAX; + const dtStatPoly* p = getPoly(idx); + const dtStatPolyDetail* pd = getPolyDetail(idx); - for (int i = 2; i < (int)poly->nv; ++i) + for (int j = 0; j < pd->ntris; ++j) { - const float* v0 = getVertex(poly->v[0]); - const float* v1 = getVertex(poly->v[i-1]); - const float* v2 = getVertex(poly->v[i]); - + const unsigned char* t = getDetailTri(pd->tbase+j); + const float* v[3]; + for (int k = 0; k < 3; ++k) + { + if (t[k] < p->nv) + v[k] = getVertex(p->v[t[k]]); + else + v[k] = getDetailVertex(pd->vbase+(t[k]-p->nv)); + } float pt[3]; - closestPtPointTriangle(pt, pos, v0, v1, v2); + closestPtPointTriangle(pt, pos, v[0], v[1], v[2]); float d = vdistSqr(pos, pt); if (d < closestDistSqr) { @@ -244,6 +266,38 @@ bool dtStatNavMesh::closestPointToPoly(dtStatPolyRef ref, const float* pos, floa return true; } +bool dtStatNavMesh::getPolyHeight(dtStatPolyRef ref, const float* pos, float* height) const +{ + int idx = getPolyIndexByRef(ref); + if (idx == -1) + return false; + + const dtStatPoly* p = getPoly(idx); + const dtStatPolyDetail* pd = getPolyDetail(idx); + + for (int i = 0; i < pd->ntris; ++i) + { + const unsigned char* t = getDetailTri(pd->tbase+i); + const float* v[3]; + for (int j = 0; j < 3; ++j) + { + if (t[j] < p->nv) + v[j] = getVertex(p->v[t[j]]); + else + v[j] = getDetailVertex(pd->vbase+(t[j]-p->nv)); + } + float h; + if (closestHeightPointTriangle(pos, v[0], v[1], v[2], h)) + { + if (height) + *height = h; + return true; + } + } + + return false; +} + int dtStatNavMesh::findStraightPath(const float* startPos, const float* endPos, const dtStatPolyRef* path, const int pathSize, float* straightPath, const int maxStraightPathSize) diff --git a/Detour/Source/DetourStatNavMeshBuilder.cpp b/Detour/Source/DetourStatNavMeshBuilder.cpp index 39065a9f..a2bfb94e 100755 --- a/Detour/Source/DetourStatNavMeshBuilder.cpp +++ b/Detour/Source/DetourStatNavMeshBuilder.cpp @@ -209,6 +209,8 @@ static int createBVTree(const unsigned short* verts, const int nverts, bool dtCreateNavMeshData(const unsigned short* verts, const int nverts, const unsigned short* polys, const int npolys, const int nvp, const float* bmin, const float* bmax, float cs, float ch, + const unsigned short* dmeshes, const float* dverts, const int ndverts, + const unsigned char* dtris, const int ndtris, unsigned char** outData, int* outDataSize) { if (nvp > DT_STAT_VERTS_PER_POLYGON) @@ -220,23 +222,52 @@ bool dtCreateNavMeshData(const unsigned short* verts, const int nverts, return false; if (!npolys) return false; + if (!dmeshes || !dverts || ! dtris) + return false; + + // Find unique detail vertices. + int uniqueDetailVerts = 0; + if (dmeshes) + { + for (int i = 0; i < npolys; ++i) + { + const unsigned short* p = &polys[i*nvp*2]; + int ndv = dmeshes[i*4+1]; + int nv = 0; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == 0xffff) break; + nv++; + } + ndv -= nv; + uniqueDetailVerts += ndv; + } + } // Calculate data size const int headerSize = sizeof(dtStatNavMeshHeader); const int vertsSize = sizeof(float)*3*nverts; const int polysSize = sizeof(dtStatPoly)*npolys; const int nodesSize = sizeof(dtStatBVNode)*npolys*2; + const int detailMeshesSize = sizeof(dtStatPolyDetail)*npolys; + const int detailVertsSize = sizeof(float)*3*uniqueDetailVerts; + const int detailTrisSize = sizeof(unsigned char)*4*ndtris; - const int dataSize = headerSize + vertsSize + polysSize + nodesSize; + const int dataSize = headerSize + vertsSize + polysSize + nodesSize + + detailMeshesSize + detailVertsSize + detailTrisSize; unsigned char* data = new unsigned char[dataSize]; if (!data) return false; memset(data, 0, dataSize); - - dtStatNavMeshHeader* header = (dtStatNavMeshHeader*)(data); - float* navVerts = (float*)(data + headerSize); - dtStatPoly* navPolys = (dtStatPoly*)(data + headerSize + vertsSize); - dtStatBVNode* nodes = (dtStatBVNode*)(data + headerSize + vertsSize + polysSize); + + unsigned char* d = data; + dtStatNavMeshHeader* header = (dtStatNavMeshHeader*)d; d += headerSize; + float* navVerts = (float*)d; d += vertsSize; + dtStatPoly* navPolys = (dtStatPoly*)d; d += polysSize; + dtStatBVNode* navNodes = (dtStatBVNode*)d; d += nodesSize; + dtStatPolyDetail* navDMeshes = (dtStatPolyDetail*)d; d += detailMeshesSize; + float* navDVerts = (float*)d; d += detailVertsSize; + unsigned char* navDTris = (unsigned char*)d; d += detailTrisSize; // Store header header->magic = DT_STAT_NAVMESH_MAGIC; @@ -250,6 +281,9 @@ bool dtCreateNavMeshData(const unsigned short* verts, const int nverts, header->bmax[0] = bmax[0]; header->bmax[1] = bmax[1]; header->bmax[2] = bmax[2]; + header->ndmeshes = dmeshes ? npolys : 0; + header->ndverts = dmeshes ? uniqueDetailVerts : 0; + header->ndtris = dmeshes ? ndtris : 0; // Store vertices for (int i = 0; i < nverts; ++i) @@ -278,7 +312,32 @@ bool dtCreateNavMeshData(const unsigned short* verts, const int nverts, } header->nnodes = createBVTree(verts, nverts, polys, npolys, nvp, - cs, ch, npolys*2, nodes); + cs, ch, npolys*2, navNodes); + + + // Store detail meshes and vertices. + // The nav polygon vertices are stored as the first vertices on each mesh. + // We compress the mesh data by skipping them and using the navmesh coordinates. + unsigned short vbase = 0; + for (int i = 0; i < npolys; ++i) + { + dtStatPolyDetail& dtl = navDMeshes[i]; + const int vb = dmeshes[i*4+0]; + const int ndv = dmeshes[i*4+1]; + const int nv = navPolys[i].nv; + dtl.vbase = vbase; + dtl.nverts = ndv-nv; + dtl.tbase = dmeshes[i*4+2]; + dtl.ntris = dmeshes[i*4+3]; + // Copy vertices except the first 'nv' verts which are equal to nav poly verts. + if (ndv-nv) + { + memcpy(&navDVerts[vbase*3], &dverts[(vb+nv)*3], sizeof(float)*3*(ndv-nv)); + vbase += ndv-nv; + } + } + // Store triangles. + memcpy(navDTris, dtris, sizeof(unsigned char)*4*ndtris); *outData = data; *outDataSize = dataSize; diff --git a/Detour/Source/DetourTileNavMesh.cpp b/Detour/Source/DetourTileNavMesh.cpp index 0eed8977..0813c775 100644 --- a/Detour/Source/DetourTileNavMesh.cpp +++ b/Detour/Source/DetourTileNavMesh.cpp @@ -363,9 +363,18 @@ bool dtTiledNavMesh::addTileAt(int x, int y, unsigned char* data, int dataSize, const int headerSize = sizeof(dtTileHeader); const int vertsSize = sizeof(float)*3*header->nverts; const int polysSize = sizeof(dtTilePoly)*header->npolys; - header->verts = (float*)(data + headerSize); - header->polys = (dtTilePoly*)(data + headerSize + vertsSize); - header->links = (dtTileLink*)(data + headerSize + vertsSize + polysSize); + const int linksSize = sizeof(dtTileLink)*(header->maxlinks); + const int detailMeshesSize = sizeof(dtTilePolyDetail)*header->ndmeshes; + const int detailVertsSize = sizeof(float)*3*header->ndverts; + const int detailTrisSize = sizeof(unsigned char)*4*header->ndtris; + + unsigned char* d = data + headerSize; + header->verts = (float*)d; d += vertsSize; + header->polys = (dtTilePoly*)d; d += polysSize; + header->links = (dtTileLink*)d; d += linksSize; + header->dmeshes = (dtTilePolyDetail*)d; d += detailMeshesSize; + header->dverts = (float*)d; d += detailVertsSize; + header->dtris = (unsigned char*)d; d += detailTrisSize; // Init tile. tile->header = header; @@ -492,21 +501,27 @@ bool dtTiledNavMesh::closestPointToPoly(dtTilePolyRef ref, const float* pos, flo dtDecodeTileId(ref, salt, it, ip); if (it >= DT_MAX_TILES) return false; if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false; - const dtTileHeader* h = m_tiles[it].header; + const dtTileHeader* header = m_tiles[it].header; - if (ip >= (unsigned int)h->npolys) return false; - const dtTilePoly* poly = &h->polys[ip]; + if (ip >= (unsigned int)header->npolys) return false; + const dtTilePoly* poly = &header->polys[ip]; float closestDistSqr = FLT_MAX; + const dtTilePolyDetail* pd = &header->dmeshes[ip]; - for (int i = 2; i < (int)poly->nv; ++i) + for (int j = 0; j < pd->ntris; ++j) { - const float* v0 = &h->verts[poly->v[0]*3]; - const float* v1 = &h->verts[poly->v[i-1]*3]; - const float* v2 = &h->verts[poly->v[i]*3]; - + 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, v0, v1, v2); + closestPtPointTriangle(pt, pos, v[0], v[1], v[2]); float d = vdistSqr(pos, pt); if (d < closestDistSqr) { @@ -518,6 +533,42 @@ bool dtTiledNavMesh::closestPointToPoly(dtTilePolyRef ref, const float* pos, flo return true; } +bool dtTiledNavMesh::getPolyHeight(dtTilePolyRef ref, const float* pos, float* height) const +{ + unsigned int salt, it, ip; + dtDecodeTileId(ref, salt, it, ip); + if (it >= DT_MAX_TILES) return false; + if (m_tiles[it].salt != salt || m_tiles[it].header == 0) return false; + const dtTileHeader* header = m_tiles[it].header; + + if (ip >= (unsigned int)header->npolys) return false; + const dtTilePoly* poly = &header->polys[ip]; + + const dtTilePolyDetail* 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 h; + if (closestHeightPointTriangle(pos, v[0], v[1], v[2], h)) + { + if (height) + *height = h; + return true; + } + } + + return false; +} + + dtTilePolyRef dtTiledNavMesh::findNearestPoly(const float* center, const float* extents) { // Get nearby polygons from proximity grid. @@ -666,12 +717,12 @@ int dtTiledNavMesh::findPath(dtTilePolyRef startRef, dtTilePolyRef endRef, unsigned int salt, it, ip; dtDecodeTileId(bestNode->id, salt, it, ip); // The API input has been cheked already, skip checking internal data. - const dtTileHeader* h = m_tiles[it].header; - const dtTilePoly* poly = &h->polys[ip]; + const dtTileHeader* header = m_tiles[it].header; + const dtTilePoly* poly = &header->polys[ip]; for (int i = 0; i < poly->nlinks; ++i) { - dtTilePolyRef neighbour = h->links[poly->links+i].ref; + dtTilePolyRef neighbour = header->links[poly->links+i].ref; if (neighbour) { // Skip parent node. @@ -992,14 +1043,14 @@ int dtTiledNavMesh::raycast(dtTilePolyRef centerRef, const float* startPos, cons // The API input has been cheked already, skip checking internal data. unsigned int salt, it, ip; dtDecodeTileId(curRef, salt, it, ip); - const dtTileHeader* h = m_tiles[it].header; - const dtTilePoly* poly = &h->polys[ip]; + const dtTileHeader* header = m_tiles[it].header; + const dtTilePoly* poly = &header->polys[ip]; // Collect vertices. int nv = 0; for (int i = 0; i < (int)poly->nv; ++i) { - vcopy(&verts[nv*3], &h->verts[poly->v[i]*3]); + vcopy(&verts[nv*3], &header->verts[poly->v[i]*3]); nv++; } if (nv < 3) @@ -1026,7 +1077,7 @@ int dtTiledNavMesh::raycast(dtTilePolyRef centerRef, const float* startPos, cons dtTilePolyRef nextRef = 0; for (int i = 0; i < poly->nlinks; ++i) { - const dtTileLink* link = &h->links[poly->links+i]; + const dtTileLink* link = &header->links[poly->links+i]; if ((int)link->e == segMax) { // If the link is internal, just return the ref. @@ -1039,8 +1090,8 @@ int dtTiledNavMesh::raycast(dtTilePolyRef centerRef, const float* startPos, cons // If the link is at tile boundary, const int v0 = poly->v[link->e]; const int v1 = poly->v[(link->e+1) % poly->nv]; - const float* left = &h->verts[v0*3]; - const float* right = &h->verts[v1*3]; + const float* left = &header->verts[v0*3]; + const float* right = &header->verts[v1*3]; // Check that the intersection lies inside the link portal. if (link->side == 0 || link->side == 2) @@ -1132,12 +1183,12 @@ int dtTiledNavMesh::findPolysAround(dtTilePolyRef centerRef, const float* center unsigned int salt, it, ip; dtDecodeTileId(bestNode->id, salt, it, ip); // The API input has been cheked already, skip checking internal data. - const dtTileHeader* h = m_tiles[it].header; - const dtTilePoly* poly = &h->polys[ip]; + const dtTileHeader* header = m_tiles[it].header; + const dtTilePoly* poly = &header->polys[ip]; for (int i = 0; i < poly->nlinks; ++i) { - const dtTileLink* link = &h->links[poly->links+i]; + const dtTileLink* link = &header->links[poly->links+i]; dtTilePolyRef neighbour = link->ref; if (neighbour) { @@ -1146,8 +1197,8 @@ int dtTiledNavMesh::findPolysAround(dtTilePolyRef centerRef, const float* center continue; // Calc distance to the edge. - const float* va = &h->verts[poly->v[link->e]*3]; - const float* vb = &h->verts[poly->v[(link->e+1)%poly->nv]*3]; + const float* va = &header->verts[poly->v[link->e]*3]; + const float* vb = &header->verts[poly->v[(link->e+1)%poly->nv]*3]; float tseg; float distSqr = distancePtSegSqr2D(centerPos, va, vb, tseg); @@ -1235,8 +1286,8 @@ float dtTiledNavMesh::findDistanceToWall(dtTilePolyRef centerRef, const float* c unsigned int salt, it, ip; dtDecodeTileId(bestNode->id, salt, it, ip); // The API input has been cheked already, skip checking internal data. - const dtTileHeader* h = m_tiles[it].header; - const dtTilePoly* poly = &h->polys[ip]; + const dtTileHeader* header = m_tiles[it].header; + const dtTilePoly* poly = &header->polys[ip]; // Hit test walls. for (int i = 0, j = (int)poly->nv-1; i < (int)poly->nv; j = i++) @@ -1248,7 +1299,7 @@ float dtTiledNavMesh::findDistanceToWall(dtTilePolyRef centerRef, const float* c bool solid = true; for (int i = 0; i < poly->nlinks; ++i) { - const dtTileLink* link = &h->links[poly->links+i]; + const dtTileLink* link = &header->links[poly->links+i]; if (link->e == j && link->ref != 0) { solid = false; @@ -1264,8 +1315,8 @@ float dtTiledNavMesh::findDistanceToWall(dtTilePolyRef centerRef, const float* c } // Calc distance to the edge. - const float* vj = &h->verts[poly->v[j]*3]; - const float* vi = &h->verts[poly->v[i]*3]; + const float* vj = &header->verts[poly->v[j]*3]; + const float* vi = &header->verts[poly->v[i]*3]; float tseg; float distSqr = distancePtSegSqr2D(centerPos, vj, vi, tseg); @@ -1283,7 +1334,7 @@ float dtTiledNavMesh::findDistanceToWall(dtTilePolyRef centerRef, const float* c for (int i = 0; i < poly->nlinks; ++i) { - const dtTileLink* link = &h->links[poly->links+i]; + const dtTileLink* link = &header->links[poly->links+i]; dtTilePolyRef neighbour = link->ref; if (neighbour) { @@ -1292,8 +1343,8 @@ float dtTiledNavMesh::findDistanceToWall(dtTilePolyRef centerRef, const float* c continue; // Calc distance to the edge. - const float* va = &h->verts[poly->v[link->e]*3]; - const float* vb = &h->verts[poly->v[(link->e+1)%poly->nv]*3]; + const float* va = &header->verts[poly->v[link->e]*3]; + const float* vb = &header->verts[poly->v[(link->e+1)%poly->nv]*3]; float tseg; float distSqr = distancePtSegSqr2D(centerPos, va, vb, tseg); diff --git a/Detour/Source/DetourTileNavMeshBuilder.cpp b/Detour/Source/DetourTileNavMeshBuilder.cpp index d7468707..95dd34b0 100644 --- a/Detour/Source/DetourTileNavMeshBuilder.cpp +++ b/Detour/Source/DetourTileNavMeshBuilder.cpp @@ -25,6 +25,8 @@ bool dtCreateNavMeshTileData(const unsigned short* verts, const int nverts, const unsigned short* polys, const int npolys, const int nvp, + const unsigned short* dmeshes, const float* dverts, const int ndverts, + const unsigned char* dtris, const int ndtris, const float* bmin, const float* bmax, float cs, float ch, int tileSize, int walkableClimb, unsigned char** outData, int* outDataSize) { @@ -37,6 +39,8 @@ bool dtCreateNavMeshTileData(const unsigned short* verts, const int nverts, return false; if (!npolys) return false; + if (!dmeshes || !dverts || ! dtris) + return false; // Find portal edges which are at tile borders. int nedges = 0; @@ -64,34 +68,70 @@ bool dtCreateNavMeshTileData(const unsigned short* verts, const int nverts, nportals++; // z- } } + + const int maxLinks = nedges + nportals*2; + + + // Find unique detail vertices. + int uniqueDetailVerts = 0; + if (dmeshes) + { + for (int i = 0; i < npolys; ++i) + { + const unsigned short* p = &polys[i*nvp*2]; + int ndv = dmeshes[i*4+1]; + int nv = 0; + for (int j = 0; j < nvp; ++j) + { + if (p[j] == 0xffff) break; + nv++; + } + ndv -= nv; + uniqueDetailVerts += ndv; + } + } // Calculate data size const int headerSize = sizeof(dtTileHeader); const int vertsSize = sizeof(float)*3*nverts; const int polysSize = sizeof(dtTilePoly)*npolys; - const int linksSize = sizeof(dtTileLink)*(nedges + nportals*2); - const int dataSize = headerSize + vertsSize + polysSize + linksSize; + const int linksSize = sizeof(dtTileLink)*maxLinks; + const int detailMeshesSize = sizeof(dtTilePolyDetail)*npolys; + const int detailVertsSize = sizeof(float)*3*uniqueDetailVerts; + const int detailTrisSize = sizeof(unsigned char)*4*ndtris; + + const int dataSize = headerSize + vertsSize + polysSize + linksSize + + detailMeshesSize + detailVertsSize + detailTrisSize; unsigned char* data = new unsigned char[dataSize]; if (!data) return false; memset(data, 0, dataSize); - dtTileHeader* header = (dtTileHeader*)(data); - float* navVerts = (float*)(data + headerSize); - dtTilePoly* navPolys = (dtTilePoly*)(data + headerSize + vertsSize); + unsigned char* d = data; + dtTileHeader* header = (dtTileHeader*)d; d += headerSize; + float* navVerts = (float*)d; d += vertsSize; + dtTilePoly* navPolys = (dtTilePoly*)d; d += polysSize; + d += linksSize; + dtTilePolyDetail* navDMeshes = (dtTilePolyDetail*)d; d += detailMeshesSize; + float* navDVerts = (float*)d; d += detailVertsSize; + unsigned char* navDTris = (unsigned char*)d; d += detailTrisSize; + // Store header header->magic = DT_TILE_NAVMESH_MAGIC; header->version = DT_TILE_NAVMESH_VERSION; header->npolys = npolys; header->nverts = nverts; - header->maxlinks = nedges + nportals*2; + header->maxlinks = maxLinks; header->bmin[0] = bmin[0]; header->bmin[1] = bmin[1]; header->bmin[2] = bmin[2]; header->bmax[0] = bmax[0]; header->bmax[1] = bmax[1]; header->bmax[2] = bmax[2]; + header->ndmeshes = npolys; + header->ndverts = uniqueDetailVerts; + header->ndtris = ndtris; // Store vertices for (int i = 0; i < nverts; ++i) @@ -141,6 +181,30 @@ bool dtCreateNavMeshTileData(const unsigned short* verts, const int nverts, poly->n[j] = 0x8000 | 3; } } + + // Store detail meshes and vertices. + // The nav polygon vertices are stored as the first vertices on each mesh. + // We compress the mesh data by skipping them and using the navmesh coordinates. + unsigned short vbase = 0; + for (int i = 0; i < npolys; ++i) + { + dtTilePolyDetail& dtl = navDMeshes[i]; + const int vb = dmeshes[i*4+0]; + const int ndv = dmeshes[i*4+1]; + const int nv = navPolys[i].nv; + dtl.vbase = vbase; + dtl.nverts = ndv-nv; + dtl.tbase = dmeshes[i*4+2]; + dtl.ntris = dmeshes[i*4+3]; + // Copy vertices except the first 'nv' verts which are equal to nav poly verts. + if (ndv-nv) + { + memcpy(&navDVerts[vbase*3], &dverts[(vb+nv)*3], sizeof(float)*3*(ndv-nv)); + vbase += ndv-nv; + } + } + // Store triangles. + memcpy(navDTris, dtris, sizeof(unsigned char)*4*ndtris); *outData = data; *outDataSize = dataSize; diff --git a/Recast/Include/Recast.h b/Recast/Include/Recast.h index f02a700a..70c6066a 100644 --- a/Recast/Include/Recast.h +++ b/Recast/Include/Recast.h @@ -19,22 +19,26 @@ #ifndef RECAST_H #define RECAST_H +// The units of the parameters are specified in parenthesis as follows: +// (vx) voxels, (wu) world units struct rcConfig { - int width, height; // Dimensions of the rasterized heighfield - int tileSize; // Size if a tile. - int borderSize; // Non-navigable Border around the heightfield. - float cs, ch; // Grid cell size and height. - float bmin[3], bmax[3]; // Grid bounds. + int width, height; // Dimensions of the rasterized heighfield (vx) + int tileSize; // Width and Height of a tile (vx) + int borderSize; // Non-navigable Border around the heightfield (vx) + float cs, ch; // Grid cell size and height (wu) + float bmin[3], bmax[3]; // Grid bounds (wu) float walkableSlopeAngle; // Maximum walkble slope angle in degrees. - int walkableHeight; // Minimum height where the agent can still walk. - int walkableClimb; // Maximum height between grid cells the agent can climb. - int walkableRadius; // Radius of the agent in cells. - int maxEdgeLen; // Maximum contour edge length in cells. - float maxSimplificationError; // Maximum distance error from contour to cells. - int minRegionSize; // Minimum regions size. Smaller regions will be deleted. - int mergeRegionSize; // Minimum regions size. Smaller regions will be merged. - int maxVertsPerPoly; // Max number of vertices per polygon. + int walkableHeight; // Minimum height where the agent can still walk (vx) + int walkableClimb; // Maximum height between grid cells the agent can climb (vx) + int walkableRadius; // Radius of the agent in cells (vx) + int maxEdgeLen; // Maximum contour edge length (vx) + float maxSimplificationError; // Maximum distance error from contour to cells (vx) + int minRegionSize; // Minimum regions size. Smaller regions will be deleted (vx) + int mergeRegionSize; // Minimum regions size. Smaller regions will be merged (vx) + int maxVertsPerPoly; // Max number of vertices per polygon + float detailSampleDist; // Detail mesh sample spacing. + float detailSampleMaxError; // Detail mesh simplification max sample error. }; // Heightfield span. @@ -126,8 +130,10 @@ struct rcContourSet { inline rcContourSet() : conts(0), nconts(0) {} inline ~rcContourSet() { delete [] conts; } - rcContour* conts; // Pointer to all contours. - int nconts; // Number of contours. + rcContour* conts; // Pointer to all contours. + int nconts; // Number of contours. + float bmin[3], bmax[3]; // Bounding box of the heightfield. + float cs, ch; // Cell size and height. }; // Polymesh store a connected mesh of polygons. @@ -138,15 +144,16 @@ struct rcContourSet // are set os 0xffff. If an polygon edge does not have a neighbour // the neighbour index is set to 0xffff. // Vertices can be transformed into world space as follows: -// x = bmin[0] + verts[i*3+0]*cs; -// y = bmin[1] + verts[i*3+1]*ch; -// z = bmin[2] + verts[i*3+2]*cs; +// x = bmin[0] + verts[i*3+0]*cs; +// y = bmin[1] + verts[i*3+1]*ch; +// z = bmin[2] + verts[i*3+2]*cs; struct rcPolyMesh { - inline rcPolyMesh() : verts(0), polys(0), nverts(0), npolys(0), nvp(3) {} - inline ~rcPolyMesh() { delete [] verts; delete [] polys; } + inline rcPolyMesh() : verts(0), polys(0), regs(0), nverts(0), npolys(0), nvp(3) {} + inline ~rcPolyMesh() { delete [] verts; delete [] polys; delete [] regs; } unsigned short* verts; // Vertices of the mesh, 3 elements per vertex. unsigned short* polys; // Polygons of the mesh, nvp*2 elements per polygon. + unsigned short* regs; // Regions of the polygons. int nverts; // Number of vertices. int npolys; // Number of polygons. int nvp; // Max number of vertices per polygon. @@ -154,6 +161,35 @@ struct rcPolyMesh float cs, ch; // Cell size and height. }; +// Detail mesh generated from a rcPolyMesh. +// Each submesh represents a polygon in the polymesh and they are stored in +// excatly same order. Each submesh is described as 4 values: +// base vertex, vertex count, base triangle, triangle count. That is, +// const unsigned char* t = &dtl.tris[(tbase+i)*3]; and +// const float* v = &dtl.verts[(vbase+t[j])*3]; +// If the input polygon has 'n' vertices, those vertices are first in the +// submesh vertex list. This allows to compres the mesh by not storing the +// first vertices and using the polymesh vertices instead. + +struct rcPolyMeshDetail +{ + inline rcPolyMeshDetail() : + meshes(0), verts(0), tris(0), + nmeshes(0), nverts(0), ntris(0) {} + inline ~rcPolyMeshDetail() + { + delete [] meshes; delete [] verts; delete [] tris; + } + + unsigned short* meshes; // Pointer to all mesh data. + float* verts; // Pointer to all vertex data. + unsigned char* tris; // Pointer to all triangle data. + int nmeshes; // Number of meshes. + int nverts; // Number of total vertices. + int ntris; // Number of triangles. +}; + + // Simple dynamic array ints. class rcIntArray { @@ -425,39 +461,32 @@ bool rcBuildRegions(rcCompactHeightfield& chf, // cset - (out) Resulting contour set. // Returns false if operation ran out of memory. bool rcBuildContours(rcCompactHeightfield& chf, - float maxError, int maxEdgeLen, + const float maxError, const int maxEdgeLen, rcContourSet& cset); -// Ensures that connected contour sets A and B share the same vertices at the shared edges. -// Params: -// cseta - (in) contour set A. -// csetb - (in) contour set B. -// walkableHeight - (in) minimum height where the agent can still walk -// edgex, edgez - (in) defines the planes where the edges can be merged -// orig - (in) origin of the contour set A. -// cs - (in) grid cell size -// ch - (in) grid cell height -bool rcFixupAdjacentContours(rcContourSet* cseta, rcContourSet* csetb, - const int walkableClimb, const int edgex, const int edgez); - -// Translates the cordinates of the contour set. -// Params: -// cset - (in) contour set to translate. -// dx - (in) delta X. -// dy - (in) delta Y. -// dz - (in) delta Z. -void rcTranslateContours(rcContourSet* cset, int dx, int dy, int dz); - // Builds connected convex polygon mesh from contour polygons. // Params: // cset - (in) contour set. +// nvp - (in) maximum number of vertices per polygon. // mesh - (out) poly mesh. -// nvp - (int) maximum number of vertices per polygon. // Returns false if operation ran out of memory. -bool rcBuildPolyMesh(rcContourSet& cset, - const float* bmin, const float* bmax, - const float cs, const float ch, int nvp, - rcPolyMesh& mesh); +bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh); + +bool rcMergePolyMeshes(rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh); + +// Builds detail triangle mesh for each polygon in the poly mesh. +// Params: +// mesh - (in) poly mesh to detail. +// chf - (in) compacy height field, used to query height for new vertices. +// sampleDist - (in) spacing between height samples used to generate more detail into mesh. +// sampleMaxError - (in) maximum allowed distance between simplified detail mesh and height sample. +// pmdtl - (out) detail mesh. +// Returns false if operation ran out of memory. +bool rcBuildPolyMeshDetail(const rcPolyMesh& mesh, const rcCompactHeightfield& chf, + const float sampleDist, const float sampleMaxError, + rcPolyMeshDetail& dmesh); + +bool rcMergePolyMeshDetails(rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh); #endif // RECAST_H diff --git a/Recast/Include/RecastDebugDraw.h b/Recast/Include/RecastDebugDraw.h index f40064ec..27ba0a1a 100644 --- a/Recast/Include/RecastDebugDraw.h +++ b/Recast/Include/RecastDebugDraw.h @@ -44,10 +44,11 @@ void rcDebugDrawCompactHeightfieldSolid(const struct rcCompactHeightfield& chf); void rcDebugDrawCompactHeightfieldRegions(const struct rcCompactHeightfield& chf); void rcDebugDrawCompactHeightfieldDistance(const struct rcCompactHeightfield& chf); -void rcDebugDrawRegionConnections(const struct rcContourSet& cset, const float* orig, float cs, float ch, const float alpha = 1.0f); -void rcDebugDrawRawContours(const struct rcContourSet& cset, const float* orig, float cs, float ch, const float alpha = 1.0f); -void rcDebugDrawContours(const struct rcContourSet& cset, const float* orig, float cs, float ch); +void rcDebugDrawRegionConnections(const struct rcContourSet& cset, const float alpha = 1.0f); +void rcDebugDrawRawContours(const struct rcContourSet& cset, const float alpha = 1.0f); +void rcDebugDrawContours(const struct rcContourSet& cset, const float alpha = 1.0f); void rcDebugDrawPolyMesh(const struct rcPolyMesh& mesh); +void rcDebugDrawPolyMeshDetail(const struct rcPolyMeshDetail& dmesh); void rcDebugDrawCylinderWire(float minx, float miny, float minz, float maxx, float maxy, float maxz, const float* col); void rcDebugDrawBoxWire(float minx, float miny, float minz, float maxx, float maxy, float maxz, const float* col); diff --git a/Recast/Include/RecastLog.h b/Recast/Include/RecastLog.h index a90f5af3..026ef73a 100644 --- a/Recast/Include/RecastLog.h +++ b/Recast/Include/RecastLog.h @@ -66,7 +66,9 @@ struct rcBuildTimes int buildRegionsExp; int buildRegionsFlood; int buildRegionsFilter; - int fixupContours; + int buildDetailMesh; + int mergePolyMesh; + int mergePolyMeshDetail; }; void rcSetLog(rcLog* log); diff --git a/Recast/Source/Recast.cpp b/Recast/Source/Recast.cpp index f37ac566..4bd8b7a1 100644 --- a/Recast/Source/Recast.cpp +++ b/Recast/Source/Recast.cpp @@ -40,7 +40,7 @@ void rcIntArray::resize(int n) } m_size = n; } - + void rcCalcBounds(const float* verts, int nv, float* bmin, float* bmax) { // Calculate bounding box. @@ -77,20 +77,6 @@ bool rcCreateHeightfield(rcHeightfield& hf, int width, int height, return true; } -/*void rcMarkWalkableTriangles(const float walkableSlopeAngle, - const int* tris, const float* norms, int nt, - unsigned char* flags) -{ - const float walkableThr = cosf(walkableSlopeAngle/180.0f*(float)M_PI); - - for (int i = 0; i < nt; ++i) - { - // Check if the face is walkable. - if (norms[i*3+1] > walkableThr) - flags[i] |= RC_WALKABLE; - } -}*/ - static void calcTriNormal(const float* v0, const float* v1, const float* v2, float* norm) { float e0[3], e1[3]; @@ -284,4 +270,3 @@ static int getCompactHeightFieldMemoryusage(const rcCompactHeightfield& chf) size += sizeof(rcCompactCell) * chf.width * chf.height; return size; } - diff --git a/Recast/Source/RecastContour.cpp b/Recast/Source/RecastContour.cpp index ff0fa87a..e954137a 100644 --- a/Recast/Source/RecastContour.cpp +++ b/Recast/Source/RecastContour.cpp @@ -26,11 +26,17 @@ static int getCornerHeight(int x, int y, int i, int dir, - const rcCompactHeightfield& chf) + const rcCompactHeightfield& chf, + bool& isBorderVertex) { const rcCompactSpan& s = chf.spans[i]; int ch = (int)s.y; int dirp = (dir+1) & 0x3; + + unsigned short regs[4] = {0,0,0,0}; + + regs[0] = s.reg; + if (rcGetCon(s, dir) != 0xf) { const int ax = x + rcGetDirOffsetX(dir); @@ -38,6 +44,7 @@ static int getCornerHeight(int x, int y, int i, int dir, const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dir); const rcCompactSpan& as = chf.spans[ai]; ch = rcMax(ch, (int)as.y); + regs[1] = as.reg; if (rcGetCon(as, dirp) != 0xf) { const int ax2 = ax + rcGetDirOffsetX(dirp); @@ -45,6 +52,7 @@ static int getCornerHeight(int x, int y, int i, int dir, const int ai2 = (int)chf.cells[ax2+ay2*chf.width].index + rcGetCon(as, dirp); const rcCompactSpan& as2 = chf.spans[ai2]; ch = rcMax(ch, (int)as2.y); + regs[2] = as2.reg; } } if (rcGetCon(s, dirp) != 0xf) @@ -54,6 +62,7 @@ static int getCornerHeight(int x, int y, int i, int dir, const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(s, dirp); const rcCompactSpan& as = chf.spans[ai]; ch = rcMax(ch, (int)as.y); + regs[3] = as.reg; if (rcGetCon(as, dir) != 0xf) { const int ax2 = ax + rcGetDirOffsetX(dir); @@ -61,6 +70,27 @@ static int getCornerHeight(int x, int y, int i, int dir, const int ai2 = (int)chf.cells[ax2+ay2*chf.width].index + rcGetCon(as, dir); const rcCompactSpan& as2 = chf.spans[ai2]; ch = rcMax(ch, (int)as2.y); + regs[2] = as2.reg; + } + } + + // Check if the vertex is special edge vertex, these vertices will be removed later. + for (int j = 0; j < 4; ++j) + { + const int a = j; + const int b = (j+1) & 0x3; + const int c = (j+2) & 0x3; + const int d = (j+3) & 0x3; + + // The vertex is a border vertex there are two same exterior cells in a row, + // followed by two interior cells and none of the regions are out of bounds. + const bool twoSameExts = (regs[a] & regs[b] & 0x8000) != 0 && regs[a] == regs[b]; + const bool twoInts = ((regs[c] | regs[d]) & 0x8000) == 0; + const bool noZeros = regs[a] != 0 && regs[b] != 0 && regs[c] != 0 && regs[d] != 0; + if (twoSameExts && twoInts && noZeros) + { + isBorderVertex = true; + break; } } @@ -85,8 +115,9 @@ static void walkContour(int x, int y, int i, if (flags[i] & (1 << dir)) { // Choose the edge corner + bool isBorderVertex = false; int px = x; - int py = getCornerHeight(x, y, i, dir, chf); + int py = getCornerHeight(x, y, i, dir, chf, isBorderVertex); int pz = y; switch(dir) { @@ -105,6 +136,12 @@ static void walkContour(int x, int y, int i, r = (int)as.reg; } +/* if (r & 0x8000) + printf("0x8000\n");*/ + + if (isBorderVertex) + r |= 0x10000; + points.push(px); points.push(py); points.push(pz); @@ -192,7 +229,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma bool noConnections = true; for (int i = 0; i < points.size(); i += 4) { - if (points[i+3] != 0) + if ((points[i+3] & 0xffff) != 0) { noConnections = false; break; @@ -249,7 +286,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma for (int i = 0, ni = points.size()/4; i < ni; ++i) { int ii = (i+1) % ni; - if (points[i*4+3] != points[ii*4+3]) + if ((points[i*4+3] & 0xffff) != (points[ii*4+3] & 0xffff)) { simplified.push(points[i*4+0]); simplified.push(points[i*4+1]); @@ -282,7 +319,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma int ci = (ai+1) % pn; // Tesselate only outer edges. - if (points[ci*4+3] == 0) + if ((points[ci*4+3] & 0xffff) == 0) { while (ci != bi) { @@ -344,7 +381,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma int ci = (ai+1) % pn; // Tesselate only outer edges. - if (points[ci*4+3] == 0) + if ((points[ci*4+3] & 0xffff) == 0) { int dx = bx - ax; int dz = bz - az; @@ -384,8 +421,11 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma for (int i = 0; i < simplified.size()/4; ++i) { - int ai = (simplified[i*4+3]+1) % pn; - simplified[i*4+3] = points[ai*4+3]; + // The edge vertex flag is take from the current raw point, + // and the neighbour region is take from the next raw point. + const int ai = (simplified[i*4+3]+1) % pn; + const int bi = simplified[i*4+3]; + simplified[i*4+3] = (points[ai*4+3] & 0xffff) | (points[bi*4+3] & 0x10000); } } @@ -497,7 +537,7 @@ static bool mergeContours(rcContour& ca, rcContour& cb, int ia, int ib) } bool rcBuildContours(rcCompactHeightfield& chf, - float maxError, int maxEdgeLen, + const float maxError, const int maxEdgeLen, rcContourSet& cset) { const int w = chf.width; @@ -505,6 +545,11 @@ bool rcBuildContours(rcCompactHeightfield& chf, rcTimeVal startTime = rcGetPerformanceTimer(); + vcopy(cset.bmin, chf.bmin); + vcopy(cset.bmax, chf.bmax); + cset.cs = chf.cs; + cset.ch = chf.ch; + const int maxContours = chf.maxRegions*2; cset.conts = new rcContour[maxContours]; if (!cset.conts) @@ -520,6 +565,7 @@ bool rcBuildContours(rcCompactHeightfield& chf, } rcTimeVal traceStartTime = rcGetPerformanceTimer(); + // Mark boundaries. for (int y = 0; y < h; ++y) @@ -689,167 +735,3 @@ bool rcBuildContours(rcCompactHeightfield& chf, return true; } - -static bool insertPoint(rcContour* c, int idx, const int* v) -{ - int* newVerts = new int[(c->nverts+1)*4]; - if (!newVerts) - { - if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "insertPoint: Out of memory 'newVerts'."); - return false; - } - - if (idx > 0) - memcpy(newVerts, c->verts, sizeof(int)*4*idx); - - newVerts[idx*4+0] = v[0]; - newVerts[idx*4+1] = v[1]; - newVerts[idx*4+2] = v[2]; - newVerts[idx*4+3] = 0; - - if (c->nverts - idx > 0) - memcpy(&newVerts[(idx+1)*4], &c->verts[idx*4], sizeof(int)*4*(c->nverts - idx)); - - delete [] c->verts; - - c->verts = newVerts; - c->nverts++; - - return true; -} - -static bool conformVertex(rcContourSet* cset, const int* v, - const int pminy, const int pmaxy, - const int nminy, const int nmaxy, - const int walkableClimb) -{ - for (int i = 0; i < cset->nconts; ++i) - { - rcContour* c = &cset->conts[i]; - for (int j = 0; j < c->nverts; ++j) - { - const int k = (j+1) % c->nverts; - const int* vj = &c->verts[j*4]; - const int* vk = &c->verts[k*4]; - - const int miny = rcMin(vj[1], vk[1]); - const int maxy = rcMax(vj[1], vk[1]); - - // Is edge within y-range. - if ((miny > pmaxy || maxy < pminy) && - (miny > nmaxy || maxy < nminy)) - continue; - - if (vj[0] == vk[0] && vj[0] == v[0]) - { - // The segment is x edge. - const int minz = rcMin(vj[2], vk[2]); - const int maxz = rcMax(vj[2], vk[2]); - if (v[2] > minz && v[2] < maxz) - { - return insertPoint(c, j+1, v); - } - } - else if (vj[2] == vk[2] && vj[2] == v[2]) - { - // The segment is z edge. - const int minx = rcMin(vj[0], vk[0]); - const int maxx = rcMax(vj[0], vk[0]); - if (v[0] > minx && v[0] < maxx) - { - return insertPoint(c, j+1, v); - } - } - } - } - return true; -} - -bool rcFixupAdjacentContours(rcContourSet* cseta, rcContourSet* csetb, - const int walkableClimb, const int edgex, const int edgez) -{ - if (!cseta || !csetb) - return true; - - rcTimeVal startTime = rcGetPerformanceTimer(); - - for (int i = 0; i < cseta->nconts; ++i) - { - const rcContour& c = cseta->conts[i]; - for (int j = 0; j < c.nverts; ++j) - { - const int* v = &c.verts[j*4]; - const int* pv = &c.verts[((j+c.nverts-1)%c.nverts)*4]; - const int* nv = &c.verts[((j+1)%c.nverts)*4]; - - // If the vertex is at the tile edge, make sure it also exists in - // the neighbour contour set. - if (v[0] == edgex || v[2] == edgez) - { - const int pminy = rcMin(v[1], pv[1]); - const int pmaxy = rcMax(v[1], pv[1]); - const int nminy = rcMin(v[1], nv[1]); - const int nmaxy = rcMax(v[1], nv[1]); - - if (!conformVertex(csetb, v, pminy, pmaxy, nminy, nmaxy, walkableClimb)) - return false; - } - } - } - - for (int i = 0; i < csetb->nconts; ++i) - { - const rcContour& c = csetb->conts[i]; - for (int j = 0; j < c.nverts; ++j) - { - const int* v = &c.verts[j*4]; - const int* pv = &c.verts[((j+c.nverts-1)%c.nverts)*4]; - const int* nv = &c.verts[((j+1)%c.nverts)*4]; - - // If the vertex is at the tile edge, make sure it also exists in - // the neighbour contour set. - if (v[0] == edgex || v[2] == edgez) - { - const int pminy = rcMin(v[1], pv[1]); - const int pmaxy = rcMax(v[1], pv[1]); - const int nminy = rcMin(v[1], nv[1]); - const int nmaxy = rcMax(v[1], nv[1]); - - if (!conformVertex(cseta, v, pminy, pmaxy, nminy, nmaxy, walkableClimb)) - return false; - } - } - } - - rcTimeVal endTime = rcGetPerformanceTimer(); - if (rcGetBuildTimes()) - rcGetBuildTimes()->fixupContours += rcGetDeltaTimeUsec(startTime, endTime); - - return true; -} - -void rcTranslateContours(rcContourSet* cset, int dx, int dy, int dz) -{ - if (!cset) return; - - for (int i = 0; i < cset->nconts; ++i) - { - rcContour& cont = cset->conts[i]; - for (int i = 0; i < cont.nverts; ++i) - { - int* v = &cont.verts[i*4]; - v[0] += dx; - v[1] += dy; - v[2] += dz; - } - for (int i = 0; i < cont.nrverts; ++i) - { - int* v = &cont.rverts[i*4]; - v[0] += dx; - v[1] += dy; - v[2] += dz; - } - } -} - diff --git a/Recast/Source/RecastDebugDraw.cpp b/Recast/Source/RecastDebugDraw.cpp index 024b3c84..fd10beb9 100644 --- a/Recast/Source/RecastDebugDraw.cpp +++ b/Recast/Source/RecastDebugDraw.cpp @@ -31,7 +31,7 @@ void rcDebugDrawMesh(const float* verts, int nverts, glBegin(GL_TRIANGLES); for (int i = 0; i < ntris*3; i += 3) { - float a = (2+normals[i+0]+normals[i+1])/4; + float a = (2+normals[i+0]+normals[i+1])/4 * 0.5f; if (flags && !flags[i/3]) glColor3f(a,a*0.3f,a*0.1f); else @@ -420,8 +420,12 @@ void rcDrawArc(const float* p0, const float* p1) glEnd(); } -void rcDebugDrawRegionConnections(const rcContourSet& cset, const float* orig, float cs, float ch, const float alpha) +void rcDebugDrawRegionConnections(const rcContourSet& cset, const float alpha) { + const float* orig = cset.bmin; + const float cs = cset.cs; + const float ch = cset.ch; + // Draw centers float pos[3], pos2[3]; @@ -469,8 +473,11 @@ void rcDebugDrawRegionConnections(const rcContourSet& cset, const float* orig, f glPointSize(1.0f); } -void rcDebugDrawRawContours(const rcContourSet& cset, const float* orig, float cs, float ch, const float alpha) +void rcDebugDrawRawContours(const rcContourSet& cset, const float alpha) { + const float* orig = cset.bmin; + const float cs = cset.cs; + const float ch = cset.ch; float col[4] = { 1,1,1,alpha }; glLineWidth(2.0f); glPointSize(2.0f); @@ -499,8 +506,20 @@ void rcDebugDrawRawContours(const rcContourSet& cset, const float* orig, float c for (int j = 0; j < c.nrverts; ++j) { const int* v = &c.rverts[j*4]; + + float off = 0; + if (v[3] & 0x10000) + { + glColor4ub(255,255,255,255); + off = ch*2; + } + else + { + glColor4fv(col); + } + float fx = orig[0] + v[0]*cs; - float fy = orig[1] + (v[1]+1+(i&1))*ch; + float fy = orig[1] + (v[1]+1+(i&1))*ch + off; float fz = orig[2] + v[2]*cs; glVertex3f(fx,fy,fz); } @@ -510,8 +529,11 @@ void rcDebugDrawRawContours(const rcContourSet& cset, const float* orig, float c glPointSize(1.0f); } -void rcDebugDrawContours(const rcContourSet& cset, const float* orig, float cs, float ch) +void rcDebugDrawContours(const rcContourSet& cset, const float alpha) { + const float* orig = cset.bmin; + const float cs = cset.cs; + const float ch = cset.ch; float col[4] = { 1,1,1,1 }; glLineWidth(2.5f); glPointSize(3.0f); @@ -540,8 +562,19 @@ void rcDebugDrawContours(const rcContourSet& cset, const float* orig, float cs, for (int j = 0; j < c.nverts; ++j) { const int* v = &c.verts[j*4]; + float off = 0; + if (v[3] & 0x10000) + { + glColor4ub(255,255,255,255); + off = ch*2; + } + else + { + glColor4fv(col); + } + float fx = orig[0] + v[0]*cs; - float fy = orig[1] + (v[1]+1+(i&1))*ch; + float fy = orig[1] + (v[1]+1+(i&1))*ch + off; float fz = orig[2] + v[2]*cs; glVertex3f(fx,fy,fz); } @@ -557,11 +590,13 @@ void rcDebugDrawPolyMesh(const struct rcPolyMesh& mesh) const float cs = mesh.cs; const float ch = mesh.ch; const float* orig = mesh.bmin; - glColor4ub(0,196,255,64); + float col[4] = {1,1,1,0.5f}; glBegin(GL_TRIANGLES); for (int i = 0; i < mesh.npolys; ++i) { const unsigned short* p = &mesh.polys[i*nvp*2]; + intToCol(i, col); + glColor4fv(col); unsigned short vi[3]; for (int j = 2; j < nvp; ++j) { @@ -652,5 +687,73 @@ void rcDebugDrawPolyMesh(const struct rcPolyMesh& mesh) glVertex3f(x, y, z); } glEnd(); - glPointSize(1.0f); + glPointSize(1.0f); +} + +void rcDebugDrawPolyMeshDetail(const struct rcPolyMeshDetail& dmesh) +{ + float col[4] = {1,1,1,0.75f}; + + for (int i = 0; i < dmesh.nmeshes; ++i) + { + const unsigned short* m = &dmesh.meshes[i*4]; + const unsigned short bverts = m[0]; + const unsigned short nverts = m[1]; + const unsigned short btris = m[2]; + const unsigned short ntris = m[3]; + + intToCol(i, col); + + const float* verts = &dmesh.verts[bverts*3]; + const unsigned char* tris = &dmesh.tris[btris*4]; + + glPointSize(3.0f); + glBegin(GL_POINTS); + for (int j = 0; j < nverts; ++j) + { + glColor4ub(0,0,0,64); + glVertex3fv(&verts[j*3]); + } + glEnd(); + glPointSize(1.0f); + + glBegin(GL_TRIANGLES); + glColor4fv(col); + for (int j = 0; j < ntris; ++j) + { + glVertex3fv(&verts[tris[j*4+0]*3]); + glVertex3fv(&verts[tris[j*4+1]*3]); + glVertex3fv(&verts[tris[j*4+2]*3]); + } + glEnd(); + + for (int j = 0; j < ntris; ++j) + { + glBegin(GL_LINES); + const unsigned char* t = &tris[j*4]; + for (int k = 0, kp = 2; k < 3; kp=k++) + { + unsigned char ef = (t[3] >> (kp*2)) & 0x3; + if (ef == 0) + { + // Internal edge + if (t[kp] < t[k]) + { + glColor4ub(255,255,255,32); + glVertex3fv(&verts[t[kp]*3]); + glVertex3fv(&verts[t[k]*3]); + } + } + else + { + // Ext edge + glColor4ub(0,0,0,128); + glVertex3fv(&verts[t[kp]*3]); + glVertex3fv(&verts[t[k]*3]); + } + } + glEnd(); + } + } + } diff --git a/Recast/Source/RecastMesh.cpp b/Recast/Source/RecastMesh.cpp index 7b6740d5..376c1597 100644 --- a/Recast/Source/RecastMesh.cpp +++ b/Recast/Source/RecastMesh.cpp @@ -136,13 +136,12 @@ inline int computeVertexHash(int x, int y, int z) static int addVertex(unsigned short x, unsigned short y, unsigned short z, unsigned short* verts, int* firstVert, int* nextVert, int& nv) { - int bucket = computeVertexHash(x, 0/*y*/, z); + int bucket = computeVertexHash(x, 0, z); int i = firstVert[bucket]; while (i != -1) { const unsigned short* v = &verts[i*3]; -// if (v[0] == x && v[1] == y && v[2] == z) if (v[0] == x && (rcAbs(v[1] - y) <= 2) && v[2] == z) return i; i = nextVert[i]; // next @@ -475,17 +474,331 @@ static void mergePolys(unsigned short* pa, unsigned short* pb, memcpy(pa, tmp, sizeof(unsigned short)*nvp); } -bool rcBuildPolyMesh(rcContourSet& cset, - const float* bmin, const float* bmax, - const float cs, const float ch, int nvp, - rcPolyMesh& mesh) +static void pushFront(int v, int* arr, int& an) +{ + an++; + for (int i = an-1; i > 0; --i) arr[i] = arr[i-1]; + arr[0] = v; +} + +static void pushBack(int v, int* arr, int& an) +{ + arr[an] = v; + an++; +} + +static bool removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int maxTris) +{ + static const int nvp = mesh.nvp; + + int* edges = 0; + int nedges = 0; + int* hole = 0; + int nhole = 0; + int* hreg = 0; + int nhreg = 0; + int* tris = 0; + int* tverts = 0; + int* thole = 0; + unsigned short* polys = 0; + unsigned short* pregs = 0; + int npolys = 0; + + // Count number of polygons to remove. + int nrem = 0; + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*nvp*2]; + for (int j = 0; j < nvp; ++j) + if (p[j] == rem) { nrem++; break; } + } + + edges = new int[nrem*nvp*3]; + if (!edges) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'edges' (%d).", nrem*nvp*3); + goto failure; + } + + hole = new int[nrem*nvp]; + if (!hole) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'hole' (%d).", nrem*nvp); + goto failure; + } + hreg = new int[nrem*nvp]; + if (!hreg) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'hreg' (%d).", nrem*nvp); + goto failure; + } + + + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*nvp*2]; + const int nv = countPolyVerts(p, nvp); + bool hasRem = false; + for (int j = 0; j < nv; ++j) + if (p[j] == rem) hasRem = true; + if (hasRem) + { + // Collect edges which does not touch the removed vertex. + for (int j = 0, k = nv-1; j < nv; k = j++) + { + if (p[j] != rem && p[k] != rem) + { + int* e = &edges[nedges*3]; + e[0] = p[k]; + e[1] = p[j]; + e[2] = mesh.regs[i]; + nedges++; + } + } + // Remove the polygon. + unsigned short* p2 = &mesh.polys[(mesh.npolys-1)*nvp*2]; + memcpy(p,p2,sizeof(unsigned short)*nvp); + mesh.regs[i] = mesh.regs[mesh.npolys-1]; + mesh.npolys--; + --i; + } + } + + // Remove vertex. + for (int i = (int)rem; i < mesh.nverts; ++i) + { + mesh.verts[i*3+0] = mesh.verts[(i+1)*3+0]; + mesh.verts[i*3+1] = mesh.verts[(i+1)*3+1]; + mesh.verts[i*3+2] = mesh.verts[(i+1)*3+2]; + } + mesh.nverts--; + + // Adjust indices to match the removed vertex layout. + for (int i = 0; i < mesh.npolys; ++i) + { + unsigned short* p = &mesh.polys[i*nvp*2]; + const int nv = countPolyVerts(p, nvp); + for (int j = 0; j < nv; ++j) + if (p[j] > rem) p[j]--; + } + for (int i = 0; i < nedges; ++i) + { + if (edges[i*3+0] > rem) edges[i*3+0]--; + if (edges[i*3+1] > rem) edges[i*3+1]--; + } + + if (nedges == 0) + return true; + + hole[nhole] = edges[0]; + hreg[nhole] = edges[2]; + nhole++; + + while (nedges) + { + bool match = false; + + for (int i = 0; i < nedges; ++i) + { + const int ea = edges[i*3+0]; + const int eb = edges[i*3+1]; + const int r = edges[i*3+2]; + bool add = false; + if (hole[0] == eb) + { + pushFront(ea, hole, nhole); + pushFront(r, hreg, nhreg); + add = true; + } + else if (hole[nhole-1] == ea) + { + pushBack(eb, hole, nhole); + pushBack(r, hreg, nhreg); + add = true; + } + if (add) + { + // Remove edge. + edges[i*3+0] = edges[(nedges-1)*3+0]; + edges[i*3+1] = edges[(nedges-1)*3+1]; + edges[i*3+2] = edges[(nedges-1)*3+2]; + --nedges; + match = true; + --i; + } + } + + if (!match) + break; + } + + tris = new int[nhole*3]; + if (!tris) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'tris' (%d).", nhole*3); + goto failure; + } + + tverts = new int[nhole*4]; + if (!tverts) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'tverts' (%d).", nhole*4); + goto failure; + } + + thole = new int[nhole]; + if (!tverts) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'thole' (%d).", nhole); + goto failure; + } + + // Generate temp vertex array for triangulation. + for (int i = 0; i < nhole; ++i) + { + const int pi = hole[i]; + tverts[i*4+0] = mesh.verts[pi*3+0]; + tverts[i*4+1] = mesh.verts[pi*3+1]; + tverts[i*4+2] = mesh.verts[pi*3+2]; + tverts[i*4+3] = 0; + thole[i] = i; + } + + // Triangulate the hole. + int ntris = triangulate(nhole, &tverts[0], &thole[0], tris); + + // Merge the hole triangles back to polygons. + polys = new unsigned short[(ntris+1)*nvp]; + if (!polys) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'polys' (%d).", (ntris+1)*nvp); + goto failure; + } + pregs = new unsigned short[ntris]; + if (!pregs) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_WARNING, "removeVertex: Out of memory 'pregs' (%d).", ntris); + goto failure; + } + + unsigned short* tmpPoly = &polys[ntris*nvp]; + + // Build initial polygons. + memset(polys, 0xff, ntris*nvp*sizeof(unsigned short)); + for (int j = 0; j < ntris; ++j) + { + int* t = &tris[j*3]; + if (t[0] != t[1] && t[0] != t[2] && t[1] != t[2]) + { + polys[npolys*nvp+0] = (unsigned short)hole[t[0]]; + polys[npolys*nvp+1] = (unsigned short)hole[t[1]]; + polys[npolys*nvp+2] = (unsigned short)hole[t[2]]; + pregs[npolys] = hreg[t[0]]; + npolys++; + } + } + if (!npolys) + return true; + + // Merge polygons. + if (nvp > 3) + { + while (true) + { + // Find best polygons to merge. + int bestMergeVal = 0; + int bestPa, bestPb, bestEa, bestEb; + + for (int j = 0; j < npolys-1; ++j) + { + unsigned short* pj = &polys[j*nvp]; + for (int k = j+1; k < npolys; ++k) + { + unsigned short* pk = &polys[k*nvp]; + int ea, eb; + int v = getPolyMergeValue(pj, pk, mesh.verts, ea, eb, nvp); + if (v > bestMergeVal) + { + bestMergeVal = v; + bestPa = j; + bestPb = k; + bestEa = ea; + bestEb = eb; + } + } + } + + if (bestMergeVal > 0) + { + // Found best, merge. + unsigned short* pa = &polys[bestPa*nvp]; + unsigned short* pb = &polys[bestPb*nvp]; + mergePolys(pa, pb, mesh.verts, bestEa, bestEb, tmpPoly, nvp); + memcpy(pb, &polys[(npolys-1)*nvp], sizeof(unsigned short)*nvp); + pregs[bestPb] = pregs[npolys-1]; + npolys--; + } + else + { + // Could not merge any polygons, stop. + break; + } + } + } + + // Store polygons. + for (int i = 0; i < npolys; ++i) + { + if (mesh.npolys >= maxTris) break; + unsigned short* p = &mesh.polys[mesh.npolys*nvp*2]; + memset(p,0xff,sizeof(unsigned short)*nvp*2); + for (int j = 0; j < nvp; ++j) + p[j] = polys[i*nvp+j]; + mesh.regs[mesh.npolys] = pregs[i]; + mesh.npolys++; + } + + delete [] edges; + delete [] hole; + delete [] hreg; + delete [] tris; + delete [] thole; + delete [] tverts; + delete [] polys; + delete [] pregs; + + return true; + +failure: + delete [] edges; + delete [] hole; + delete [] hreg; + delete [] tris; + delete [] thole; + delete [] tverts; + delete [] polys; + delete [] pregs; + + return false; +} + + +bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh) { rcTimeVal startTime = rcGetPerformanceTimer(); - vcopy(mesh.bmin, bmin); - vcopy(mesh.bmax, bmax); - mesh.cs = cs; - mesh.ch = ch; + vcopy(mesh.bmin, cset.bmin); + vcopy(mesh.bmax, cset.bmax); + mesh.cs = cset.cs; + mesh.ch = cset.ch; int maxVertices = 0; int maxTris = 0; @@ -504,19 +817,42 @@ bool rcBuildPolyMesh(rcContourSet& cset, return false; } + unsigned char* vflags = 0; + int* nextVert = 0; + int* firstVert = 0; + int* indices = 0; + int* tris = 0; + unsigned short* polys = 0; + + vflags = new unsigned char[maxVertices]; + if (!vflags) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices); + goto failure; + } + memset(vflags, 0, maxVertices); + mesh.verts = new unsigned short[maxVertices*3]; if (!mesh.verts) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxVertices); - return false; + goto failure; } mesh.polys = new unsigned short[maxTris*nvp*2]; if (!mesh.polys) { if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.verts' (%d).", maxTris*nvp); - return false; + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.polys' (%d).", maxTris*nvp*2); + goto failure; + } + mesh.regs = new unsigned short[maxTris]; + if (!mesh.regs) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'mesh.regs' (%d).", maxTris); + goto failure; } mesh.nverts = 0; mesh.npolys = 0; @@ -524,54 +860,49 @@ bool rcBuildPolyMesh(rcContourSet& cset, memset(mesh.verts, 0, sizeof(unsigned short)*maxVertices*3); memset(mesh.polys, 0xff, sizeof(unsigned short)*maxTris*nvp*2); + memset(mesh.regs, 0, sizeof(unsigned short)*maxTris); - int* nextVert = new int[maxVertices]; + nextVert = new int[maxVertices]; if (!nextVert) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'nextVert' (%d).", maxVertices); - return false; + goto failure; } memset(nextVert, 0, sizeof(int)*maxVertices); - int* firstVert = new int[VERTEX_BUCKET_COUNT]; + firstVert = new int[VERTEX_BUCKET_COUNT]; if (!firstVert) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT); - return false; + goto failure; } for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i) firstVert[i] = -1; - int* indices = new int[maxVertsPerCont]; + indices = new int[maxVertsPerCont]; if (!indices) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'indices' (%d).", maxVertsPerCont); - return false; + goto failure; } - int* tris = new int[maxVertsPerCont*3]; + tris = new int[maxVertsPerCont*3]; if (!tris) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'tris' (%d).", maxVertsPerCont*3); - return false; + goto failure; } - unsigned short* polys = new unsigned short[maxVertsPerCont*nvp]; + polys = new unsigned short[(maxVertsPerCont+1)*nvp]; if (!polys) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'polys' (%d).", maxVertsPerCont*nvp); - return false; - } - unsigned short* tmpPoly = new unsigned short[nvp]; - if (!tmpPoly) - { - if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMesh: Out of memory 'tmpPoly' (%d).", nvp); - return false; + goto failure; } + unsigned short* tmpPoly = &polys[maxVertsPerCont*nvp]; for (int i = 0; i < cset.nconts; ++i) { @@ -609,6 +940,11 @@ bool rcBuildPolyMesh(rcContourSet& cset, const int* v = &cont.verts[j*4]; indices[j] = addVertex((unsigned short)v[0], (unsigned short)v[1], (unsigned short)v[2], mesh.verts, firstVert, nextVert, mesh.nverts); + if (v[3] & 0x10000) + { + // This vertex should be removed. + vflags[indices[j]] = 1; + } } // Build initial polygons. @@ -681,11 +1017,26 @@ bool rcBuildPolyMesh(rcContourSet& cset, unsigned short* q = &polys[j*nvp]; for (int k = 0; k < nvp; ++k) p[k] = q[k]; + mesh.regs[mesh.npolys] = cont.reg; mesh.npolys++; } } - delete [] tmpPoly; + + // Remove edge vertices. + for (int i = 0; i < mesh.nverts; ++i) + { + if (vflags[i]) + { + if (!removeVertex(mesh, i, maxTris)) + goto failure; + for (int j = i; j < mesh.nverts-1; ++j) + vflags[j] = vflags[j+1]; + --i; + } + } + + delete [] vflags; delete [] firstVert; delete [] nextVert; delete [] indices; @@ -707,4 +1058,155 @@ bool rcBuildPolyMesh(rcContourSet& cset, rcGetBuildTimes()->buildPolymesh += rcGetDeltaTimeUsec(startTime, endTime); return true; + +failure: + delete [] vflags; + delete [] tmpPoly; + delete [] firstVert; + delete [] nextVert; + delete [] indices; + delete [] tris; + + return false; +} + +bool rcMergePolyMeshes(rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh) +{ + if (!nmeshes || !meshes) + return true; + + rcTimeVal startTime = rcGetPerformanceTimer(); + + int* nextVert = 0; + int* firstVert = 0; + unsigned short* vremap = 0; + + mesh.nvp = meshes[0]->nvp; + mesh.cs = meshes[0]->cs; + mesh.ch = meshes[0]->ch; + vcopy(mesh.bmin, meshes[0]->bmin); + vcopy(mesh.bmax, meshes[0]->bmax); + + int maxVerts = 0; + int maxPolys = 0; + int maxVertsPerMesh = 0; + for (int i = 0; i < nmeshes; ++i) + { + vmin(mesh.bmin, meshes[i]->bmin); + vmax(mesh.bmax, meshes[i]->bmax); + maxVertsPerMesh = rcMax(maxVertsPerMesh, meshes[i]->nverts); + maxVerts += meshes[i]->nverts; + maxPolys += meshes[i]->npolys; + } + + mesh.nverts = 0; + mesh.verts = new unsigned short[maxVerts*3]; + if (!mesh.verts) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.verts' (%d).", maxVerts*3); + return false; + } + + mesh.npolys = 0; + mesh.polys = new unsigned short[maxPolys*2*mesh.nvp]; + if (!mesh.polys) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.polys' (%d).", maxPolys*2*mesh.nvp); + return false; + } + memset(mesh.polys, 0xff, sizeof(unsigned short)*maxPolys*2*mesh.nvp); + + mesh.regs = new unsigned short[maxPolys]; + if (!mesh.regs) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'mesh.regs' (%d).", maxPolys); + return false; + } + memset(mesh.regs, 0, sizeof(unsigned short)*maxPolys); + + nextVert = new int[maxVerts]; + if (!nextVert) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'nextVert' (%d).", maxVerts); + goto failure; + } + memset(nextVert, 0, sizeof(int)*maxVerts); + + firstVert = new int[VERTEX_BUCKET_COUNT]; + if (!firstVert) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'firstVert' (%d).", VERTEX_BUCKET_COUNT); + goto failure; + } + for (int i = 0; i < VERTEX_BUCKET_COUNT; ++i) + firstVert[i] = -1; + + vremap = new unsigned short[maxVertsPerMesh]; + if (!vremap) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcMergePolyMeshes: Out of memory 'vremap' (%d).", maxVertsPerMesh); + goto failure; + } + memset(nextVert, 0, sizeof(int)*maxVerts); + + for (int i = 0; i < nmeshes; ++i) + { + const rcPolyMesh* pmesh = meshes[i]; + + const unsigned short ox = (unsigned short)floorf((pmesh->bmin[0]-mesh.bmin[0])/mesh.cs+0.5f); + const unsigned short oz = (unsigned short)floorf((pmesh->bmin[2]-mesh.bmin[2])/mesh.cs+0.5f); + + for (int j = 0; j < pmesh->nverts; ++j) + { + unsigned short* v = &pmesh->verts[j*3]; + vremap[j] = addVertex(v[0]+ox, v[1], v[2]+oz, + mesh.verts, firstVert, nextVert, mesh.nverts); + } + + for (int j = 0; j < pmesh->npolys; ++j) + { + unsigned short* tgt = &mesh.polys[mesh.npolys*2*mesh.nvp]; + unsigned short* src = &pmesh->polys[j*2*mesh.nvp]; + mesh.regs[mesh.npolys] = pmesh->regs[j]; + mesh.npolys++; + for (int k = 0; k < mesh.nvp; ++k) + { + if (src[k] == 0xffff) break; + tgt[k] = vremap[src[k]]; + } + } + } + + // Calculate adjacency. + if (!buildMeshAdjacency(mesh.polys, mesh.npolys, mesh.nverts, mesh.nvp)) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcMergePolyMeshes: Adjacency failed."); + return false; + } + + + delete [] firstVert; + delete [] nextVert; + delete [] vremap; + + rcTimeVal endTime = rcGetPerformanceTimer(); + + if (rcGetBuildTimes()) + rcGetBuildTimes()->mergePolyMesh += rcGetDeltaTimeUsec(startTime, endTime); + + return true; + +failure: + delete [] firstVert; + delete [] nextVert; + delete [] vremap; + + return false; } diff --git a/Recast/Source/RecastMeshDetail.cpp b/Recast/Source/RecastMeshDetail.cpp new file mode 100644 index 00000000..5b2ede9f --- /dev/null +++ b/Recast/Source/RecastMeshDetail.cpp @@ -0,0 +1,969 @@ +// +// Copyright (c) 2009 Mikko Mononen memon@inside.org +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source distribution. +// + +#include +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include "Recast.h" +#include "RecastLog.h" +#include "RecastTimer.h" + + +struct rcHeightPatch +{ + inline rcHeightPatch() : data(0) {} + inline ~rcHeightPatch() { delete [] data; } + unsigned short* data; + int xmin, ymin, width, height; +}; + + +static int circumCircle(const float xp, const float yp, + const float x1, const float y1, + const float x2, const float y2, + const float x3, const float y3, + float& xc, float& yc, float& rsqr) +{ + static const float EPSILON = 1e-6f; + + const float fabsy1y2 = rcAbs(y1-y2); + const float fabsy2y3 = rcAbs(y2-y3); + + /* Check for coincident points */ + if (fabsy1y2 < EPSILON && fabsy2y3 < EPSILON) + return 0; + + if (fabsy1y2 < EPSILON) + { + const float m2 = - (x3-x2) / (y3-y2); + const float mx2 = (x2 + x3) / 2.0f; + const float my2 = (y2 + y3) / 2.0f; + xc = (x2 + x1) / 2.0f; + yc = m2 * (xc - mx2) + my2; + } + else if (fabsy2y3 < EPSILON) + { + const float m1 = - (x2-x1) / (y2-y1); + const float mx1 = (x1 + x2) / 2.0f; + const float my1 = (y1 + y2) / 2.0f; + xc = (x3 + x2) / 2.0f; + yc = m1 * (xc - mx1) + my1; + } + else + { + const float m1 = - (x2-x1) / (y2-y1); + const float m2 = - (x3-x2) / (y3-y2); + const float mx1 = (x1 + x2) / 2.0f; + const float mx2 = (x2 + x3) / 2.0f; + const float my1 = (y1 + y2) / 2.0f; + const float my2 = (y2 + y3) / 2.0f; + xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2); + if (fabsy1y2 > fabsy2y3) + yc = m1 * (xc - mx1) + my1; + else + yc = m2 * (xc - mx2) + my2; + } + + float dx,dy; + + dx = x2 - xc; + dy = y2 - yc; + rsqr = dx*dx + dy*dy; + + dx = xp - xc; + dy = yp - yc; + const float drsqr = dx*dx + dy*dy; + + return (drsqr <= rsqr) ? 1 : 0; +} + +static int ptcmp(void* up, const void *v1, const void *v2) +{ + const float* verts = (const float*)up; + const float* p1 = &verts[(*(const int*)v1)*3]; + const float* p2 = &verts[(*(const int*)v2)*3]; + if (p1[0] < p2[0]) + return -1; + else if (p1[0] > p2[0]) + return 1; + else + return 0; +} + +// Based on Paul Bourke's triangulate.c +// http://astronomy.swin.edu.au/~pbourke/terrain/triangulate/triangulate.c +static void delaunay(const int nv, float *verts, rcIntArray& idx, rcIntArray& tris, rcIntArray& edges) +{ + // Sort vertices + idx.resize(nv); + for (int i = 0; i < nv; ++i) + idx[i] = i; + qsort_r(&idx[0], idx.size(), sizeof(int), verts, ptcmp); + + // Find the maximum and minimum vertex bounds. + // This is to allow calculation of the bounding triangle + float xmin = verts[0]; + float ymin = verts[2]; + float xmax = xmin; + float ymax = ymin; + for (int i = 1; i < nv; ++i) + { + xmin = rcMin(xmin, verts[i*3+0]); + xmax = rcMax(xmax, verts[i*3+0]); + ymin = rcMin(ymin, verts[i*3+2]); + ymax = rcMax(ymax, verts[i*3+2]); + } + float dx = xmax - xmin; + float dy = ymax - ymin; + float dmax = (dx > dy) ? dx : dy; + float xmid = (xmax + xmin) / 2.0; + float ymid = (ymax + ymin) / 2.0; + + // Set up the supertriangle + // This is a triangle which encompasses all the sample points. + // The supertriangle coordinates are added to the end of the + // vertex list. The supertriangle is the first triangle in + // the triangle list. + float sv[3*3]; + + sv[0] = xmid - 20 * dmax; + sv[1] = 0; + sv[2] = ymid - dmax; + + sv[3] = xmid; + sv[4] = 0; + sv[5] = ymid + 20 * dmax; + + sv[6] = xmid + 20 * dmax; + sv[7] = 0; + sv[8] = ymid - dmax; + + tris.push(-3); + tris.push(-2); + tris.push(-1); + tris.push(0); // not completed + + for (int i = 0; i < nv; ++i) + { + const float xp = verts[idx[i]*3+0]; + const float yp = verts[idx[i]*3+2]; + + edges.resize(0); + + // Set up the edge buffer. + // If the point (xp,yp) lies inside the circumcircle then the + // three edges of that triangle are added to the edge buffer + // and that triangle is removed. + for (int j = 0; j < tris.size()/4; ++j) + { + int* t = &tris[j*4]; + if (t[3]) // completed? + continue; + const float* v1 = t[0] < 0 ? &sv[(t[0]+3)*3] : &verts[idx[t[0]]*3]; + const float* v2 = t[1] < 0 ? &sv[(t[1]+3)*3] : &verts[idx[t[1]]*3]; + const float* v3 = t[2] < 0 ? &sv[(t[2]+3)*3] : &verts[idx[t[2]]*3]; + float xc,yc,rsqr; + int inside = circumCircle(xp,yp, v1[0],v1[2], v2[0],v2[2], v3[0],v3[2], xc,yc,rsqr); + if (xc < xp && rcSqr(xp-xc) > rsqr) + t[3] = 1; + if (inside) + { + // Collect triangle edges. + edges.push(t[0]); + edges.push(t[1]); + edges.push(t[1]); + edges.push(t[2]); + edges.push(t[2]); + edges.push(t[0]); + // Remove triangle j. + t[0] = tris[tris.size()-4]; + t[1] = tris[tris.size()-3]; + t[2] = tris[tris.size()-2]; + t[3] = tris[tris.size()-1]; + tris.resize(tris.size()-4); + j--; + } + } + + // Remove duplicate edges. + const int ne = edges.size()/2; + for (int j = 0; j < ne-1; ++j) + { + for (int k = j+1; k < ne; ++k) + { + // Dupe?, make null. + if ((edges[j*2+0] == edges[k*2+1]) && (edges[j*2+1] == edges[k*2+0])) + { + edges[j*2+0] = 0; + edges[j*2+1] = 0; + edges[k*2+0] = 0; + edges[k*2+1] = 0; + } + } + } + + // Form new triangles for the current point + // Skipping over any null. + // All edges are arranged in clockwise order. + for (int j = 0; j < ne; ++j) + { + if (edges[j*2+0] == edges[j*2+1]) continue; + tris.push(edges[j*2+0]); + tris.push(edges[j*2+1]); + tris.push(i); + tris.push(0); // not completed + } + } + + // Remove triangles with supertriangle vertices + // These are triangles which have a vertex number greater than nv + for (int i = 0; i < tris.size()/4; ++i) + { + int* t = &tris[i*4]; + if (t[0] < 0 || t[1] < 0 || t[2] < 0) + { + t[0] = tris[tris.size()-4]; + t[1] = tris[tris.size()-3]; + t[2] = tris[tris.size()-2]; + t[3] = tris[tris.size()-1]; + tris.resize(tris.size()-4); + i--; + } + } + // Triangle vertices are pointing to sorted vertices, remap indices. + for (int i = 0; i < tris.size(); ++i) + tris[i] = idx[tris[i]]; +} + +inline float vdot2(const float* a, const float* b) +{ + return a[0]*b[0] + a[2]*b[2]; +} + +static float distPtTri(const float* p, const float* a, const float* b, const float* c) +{ + float v0[3], v1[3], v2[3]; + vsub(v0, c,a); + vsub(v1, b,a); + vsub(v2, p,a); + + const float dot00 = vdot2(v0, v0); + const float dot01 = vdot2(v0, v1); + const float dot02 = vdot2(v0, v2); + const float dot11 = vdot2(v1, v1); + const float dot12 = vdot2(v1, v2); + + // Compute barycentric coordinates + float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01); + float u = (dot11 * dot02 - dot01 * dot12) * invDenom; + float v = (dot00 * dot12 - dot01 * dot02) * invDenom; + + // If point lies inside the triangle, return interpolated y-coord. + static const float EPS = 1e-4f; + if (u >= -EPS && v >= -EPS && (u+v) <= 1+EPS) + { + float y = a[1] + v0[1]*u + v1[1]*v; + return fabsf(y-p[1]); + } + return FLT_MAX; +} + +static float distancePtSeg(const float* pt, const float* p, const float* q) +{ + float pqx = q[0] - p[0]; + float pqy = q[1] - p[1]; + float pqz = q[2] - p[2]; + float dx = pt[0] - p[0]; + float dy = pt[1] - p[1]; + float dz = pt[2] - p[2]; + float d = pqx*pqx + pqy*pqy + pqz*pqz; + float t = pqx*dx + pqy*dy + pqz*dz; + if (d > 0) + t /= d; + if (t < 0) + t = 0; + else if (t > 1) + t = 1; + + dx = p[0] + t*pqx - pt[0]; + dy = p[1] + t*pqy - pt[1]; + dz = p[2] + t*pqz - pt[2]; + + return dx*dx + dy*dy + dz*dz; +} + +static float distancePtSeg2d(const float* pt, const float* p, const float* q) +{ + float pqx = q[0] - p[0]; + float pqz = q[2] - p[2]; + float dx = pt[0] - p[0]; + float dz = pt[2] - p[2]; + float d = pqx*pqx + pqz*pqz; + float t = pqx*dx + pqz*dz; + if (d > 0) + t /= d; + if (t < 0) + t = 0; + else if (t > 1) + t = 1; + + dx = p[0] + t*pqx - pt[0]; + dz = p[2] + t*pqz - pt[2]; + + return dx*dx + dz*dz; +} + +static float distToTriMesh(const float* p, const float* verts, int nverts, const int* tris, int ntris) +{ + float dmin = FLT_MAX; + for (int i = 0; i < ntris; ++i) + { + const float* va = &verts[tris[i*4+0]*3]; + const float* vb = &verts[tris[i*4+1]*3]; + const float* vc = &verts[tris[i*4+2]*3]; + float d = distPtTri(p, va,vb,vc); + if (d < dmin) + dmin = d; + } + if (dmin == FLT_MAX) return -1; + return dmin; +} + +static float distToPoly(int nvert, const float* verts, const float* p) +{ + + float dmin = FLT_MAX; + int i, j, c = 0; + for (i = 0, j = nvert-1; i < nvert; j = i++) + { + const float* vi = &verts[i*3]; + const float* vj = &verts[j*3]; + if (((vi[2] > p[2]) != (vj[2] > p[2])) && + (p[0] < (vj[0]-vi[0]) * (p[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) ) + c = !c; + dmin = rcMin(dmin, distancePtSeg2d(p, vj, vi)); + } + return c ? -dmin : dmin; +} + + +static unsigned short getHeight(const float* pos, const float* bmin, const float ics, const rcHeightPatch& hp) +{ + int ix = (int)floorf((pos[0]-bmin[0])*ics + 0.01f); + int iz = (int)floorf((pos[2]-bmin[2])*ics + 0.01f); + ix = rcClamp(ix-hp.xmin, 0, hp.width); + iz = rcClamp(iz-hp.ymin, 0, hp.height); + unsigned short h = hp.data[ix+iz*hp.width]; + return h; +} + +static bool buildPolyDetail(const float* in, const int nin, unsigned short reg, + const float sampleDist, const float sampleMaxError, + const rcCompactHeightfield& chf, const rcHeightPatch& hp, + float* verts, int& nverts, rcIntArray& tris, + rcIntArray& edges, rcIntArray& idx, rcIntArray& samples) +{ + static const int MAX_VERTS = 256; + static const int MAX_EDGE = 64; + float edge[(MAX_EDGE+1)*3]; + + nverts = 0; + + for (int i = 0; i < nin; ++i) + vcopy(&verts[i*3], &in[i*3]); + nverts = nin; + + const float ics = 1.0f/chf.cs; + + // Tesselate outlines. + // This is done in separate pass in order to ensure + // seamless height values across the ply boundaries. + if (sampleDist > 0) + { + for (int i = 0, j = nin-1; i < nin; j=i++) + { + const float* vj = &in[j*3]; + const float* vi = &in[i*3]; + // Make sure the segments are always handled in same order + // using lexological sort or else there will be seams. + if (fabsf(vj[0]-vi[0]) < 1e-6f) + { + if (vj[2] > vi[2]) + rcSwap(vj,vi); + } + else + { + if (vj[0] > vi[0]) + rcSwap(vj,vi); + } + // Create samples along the edge. + float dx = vi[0] - vj[0]; + float dy = vi[1] - vj[1]; + float dz = vi[2] - vj[2]; + float d = sqrtf(dx*dx + dz*dz); + int nn = 1 + (int)floorf(d/sampleDist); + if (nn > MAX_EDGE) nn = MAX_EDGE; + if (nverts+nn >= MAX_VERTS) + nn = MAX_VERTS-1-nverts; + for (int k = 0; k <= nn; ++k) + { + float u = (float)k/(float)nn; + float* pos = &edge[k*3]; + pos[0] = vj[0] + dx*u; + pos[1] = vj[1] + dy*u; + pos[2] = vj[2] + dz*u; + pos[1] = chf.bmin[1] + getHeight(pos, chf.bmin, ics, hp)*chf.ch; + } + // Simplify samples. + int idx[MAX_EDGE] = {0,nn}; + int nidx = 2; + for (int k = 0; k < nidx-1; ) + { + const int a = idx[k]; + const int b = idx[k+1]; + const float* va = &edge[a*3]; + const float* vb = &edge[b*3]; + // Find maximum deviation along the segment. + float maxd = 0; + int maxi = -1; + for (int m = a+1; m < b; ++m) + { + float d = distancePtSeg(&edge[m*3],va,vb); + if (d > maxd) + { + maxd = d; + maxi = m; + } + } + // If the max deviation is larger than accepted error, + // add new point, else continue to next segment. + if (maxi != -1 && maxd > rcSqr(sampleMaxError)) + { + for (int m = nidx; m > k; --m) + idx[m] = idx[m-1]; + idx[k+1] = maxi; + nidx++; + } + else + { + ++k; + } + } + // Add new vertices. + for (int k = 1; k < nidx-1; ++k) + { + vcopy(&verts[nverts*3], &edge[idx[k]*3]); + nverts++; + } + } + } + + // Tesselate the base mesh. + edges.resize(0); + tris.resize(0); + idx.resize(0); + delaunay(nverts, verts, idx, tris, edges); + + if (sampleDist > 0) + { + // Create sample locations in a grid. + float bmin[3], bmax[3]; + vcopy(bmin, in); + vcopy(bmax, in); + for (int i = 1; i < nin; ++i) + { + vmin(bmin, &in[i*3]); + vmax(bmax, &in[i*3]); + } + int x0 = (int)floorf(bmin[0]/sampleDist); + int x1 = (int)ceilf(bmax[0]/sampleDist); + int z0 = (int)floorf(bmin[2]/sampleDist); + int z1 = (int)ceilf(bmax[2]/sampleDist); + samples.resize(0); + for (int z = z0; z < z1; ++z) + { + for (int x = x0; x < x1; ++x) + { + float pt[3]; + pt[0] = x*sampleDist; + pt[2] = z*sampleDist; + // Make sure the samples are not too close to the edges. + if (distToPoly(nin,in,pt) > -sampleDist/2) continue; + samples.push(x); + samples.push(getHeight(pt, chf.bmin, ics, hp)); + samples.push(z); + } + } + + // Add the samples starting from the one that has the most + // error. The procedure stops when all samples are added + // or when the max error is within treshold. + const int nsamples = samples.size()/3; + for (int iter = 0; iter < nsamples; ++iter) + { + // Find sample with most error. + float bestpt[3]; + float bestd = 0; + for (int i = 0; i < nsamples; ++i) + { + float pt[3]; + pt[0] = samples[i*3+0]*sampleDist; + pt[1] = chf.bmin[1] + samples[i*3+1]*chf.ch; + pt[2] = samples[i*3+2]*sampleDist; + float d = distToTriMesh(pt, verts, nverts, &tris[0], tris.size()/4); + if (d < 0) continue; // did not hit the mesh. + if (d > bestd) + { + bestd = d; + vcopy(bestpt,pt); + } + } + // If the max error is within accepted threshold, stop tesselating. + if (bestd <= sampleMaxError) + break; + + // Add the new sample point. + vcopy(&verts[nverts*3],bestpt); + nverts++; + + // Create new triangulation. + // TODO: Incremental add instead of full rebuild. + edges.resize(0); + tris.resize(0); + idx.resize(0); + delaunay(nverts, verts, idx, tris, edges); + + if (nverts >= MAX_VERTS) + break; + } + } + + return true; +} + +static void getHeightData(const rcCompactHeightfield& chf, + const unsigned short* poly, const int npoly, + const unsigned short* verts, + rcHeightPatch& hp, rcIntArray& stack) +{ + // Floodfill the heightfield to get 2D height data, + // starting at vertex locations as seeds. + + memset(hp.data, 0xff, sizeof(unsigned short)*hp.width*hp.height); + + stack.resize(0); + + // Use poly vertices as seed points for the flood fill. + for (int j = 0; j < npoly; ++j) + { + const int ax = (int)verts[poly[j]*3+0]; + const int ay = (int)verts[poly[j]*3+1]; + const int az = (int)verts[poly[j]*3+2]; + if (ax < hp.xmin || ax >= hp.xmin+hp.width || + az < hp.ymin || az >= hp.ymin+hp.height) + continue; + + const rcCompactCell& c = chf.cells[ax+az*chf.width]; + int dmin = 0xffff; + int ai = -1; + for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i) + { + const rcCompactSpan& s = chf.spans[i]; + int d = rcAbs(ay - (int)s.y); + if (d < dmin) + { + ai = i; + dmin = d; + } + } + if (ai != -1) + { + stack.push(ax); + stack.push(az); + stack.push(ai); + } + } + + while (stack.size() > 0) + { + int ci = stack.pop(); + int cy = stack.pop(); + int cx = stack.pop(); + + // Skip already visited locations. + int idx = cx-hp.xmin+(cy-hp.ymin)*hp.width; + if (hp.data[idx] != 0xffff) + continue; + + const rcCompactSpan& cs = chf.spans[ci]; + hp.data[idx] = cs.y; + + for (int dir = 0; dir < 4; ++dir) + { + if (rcGetCon(cs, dir) == 0xf) continue; + + const int ax = cx + rcGetDirOffsetX(dir); + const int ay = cy + rcGetDirOffsetY(dir); + + if (ax < hp.xmin || ax >= (hp.xmin+hp.width) || + ay < hp.ymin || ay >= (hp.ymin+hp.height)) + continue; + + if (hp.data[ax-hp.xmin+(ay-hp.ymin)*hp.width] != 0xffff) + continue; + + const int ai = (int)chf.cells[ax+ay*chf.width].index + rcGetCon(cs, dir); + + stack.push(ax); + stack.push(ay); + stack.push(ai); + } + } +} + +static unsigned char getEdgeFlags(const float* va, const float* vb, + const float* vpoly, const int npoly) +{ + // Return true if edge (va,vb) is part of the polygon. + static const float thrSqr = rcSqr(0.001f); + for (int i = 0, j = npoly-1; i < npoly; j=i++) + { + if (distancePtSeg2d(va, &vpoly[j*3], &vpoly[i*3]) < thrSqr && + distancePtSeg2d(vb, &vpoly[j*3], &vpoly[i*3]) < thrSqr) + return 1; + } + return 0; +} + +static unsigned char getTriFlags(const float* va, const float* vb, const float* vc, + const float* vpoly, const int npoly) +{ + unsigned char flags = 0; + flags |= getEdgeFlags(va,vb,vpoly,npoly) << 0; + flags |= getEdgeFlags(vb,vc,vpoly,npoly) << 2; + flags |= getEdgeFlags(vc,va,vpoly,npoly) << 4; + return flags; +} + + + +bool rcBuildPolyMeshDetail(const rcPolyMesh& mesh, const rcCompactHeightfield& chf, + const float sampleDist, const float sampleMaxError, + rcPolyMeshDetail& dmesh) +{ + rcTimeVal startTime = rcGetPerformanceTimer(); + + if (mesh.nverts == 0 || mesh.npolys == 0) + return true; + + const int nvp = mesh.nvp; + const float cs = mesh.cs; + const float ch = mesh.ch; + const float* orig = mesh.bmin; + + rcIntArray edges(64); + rcIntArray tris(512); + rcIntArray idx(512); + rcIntArray stack(512); + rcIntArray samples(512); + float verts[256*3]; + float poly[nvp*3]; + int* bounds = 0; + rcHeightPatch hp; + int nPolyVerts = 0; + int maxhw = 0, maxhh = 0; + + bounds = new int[mesh.npolys*4]; + + if (!bounds) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'bounds' (%d).", mesh.npolys*4); + goto failure; + } + + // Find max size for a polygon area. + for (int i = 0; i < mesh.npolys; ++i) + { + const unsigned short* p = &mesh.polys[i*nvp*2]; + int& xmin = bounds[i*4+0]; + int& xmax = bounds[i*4+1]; + int& ymin = bounds[i*4+2]; + int& ymax = bounds[i*4+3]; + xmin = chf.width; + xmax = 0; + ymin = chf.height; + ymax = 0; + for (int j = 0; j < nvp; ++j) + { + if(p[j] == 0xffff) break; + const unsigned short* v = &mesh.verts[p[j]*3]; + xmin = rcMin(xmin, (int)v[0]); + xmax = rcMax(xmax, (int)v[0]); + ymin = rcMin(ymin, (int)v[2]); + ymax = rcMax(ymax, (int)v[2]); + nPolyVerts++; + } + xmin = rcMax(0,xmin-1); + xmax = rcMin(chf.width,xmax+1); + ymin = rcMax(0,ymin-1); + ymax = rcMin(chf.height,ymax+1); + if (xmin >= xmax || ymin >= ymax) continue; + maxhw = rcMax(maxhw, xmax-xmin); + maxhh = rcMax(maxhh, ymax-ymin); + } + + hp.data = new unsigned short[maxhw*maxhh]; + if (!hp.data) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'hp.data' (%d).", maxhw*maxhh); + goto failure; + } + + dmesh.nmeshes = mesh.npolys; + dmesh.nverts = 0; + dmesh.ntris = 0; + dmesh.meshes = new unsigned short[dmesh.nmeshes*4]; + if (!dmesh.meshes) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.meshes' (%d).", dmesh.nmeshes*4); + goto failure; + } + + int vcap = nPolyVerts+nPolyVerts/2; + int tcap = vcap*2; + + dmesh.nverts = 0; + dmesh.verts = new float[vcap*3]; + if (!dmesh.verts) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", vcap*3); + goto failure; + } + dmesh.ntris = 0; + dmesh.tris = new unsigned char[tcap*4]; + if (!dmesh.tris) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", tcap*4); + goto failure; + } + + for (int i = 0; i < mesh.npolys; ++i) + { + const unsigned short* p = &mesh.polys[i*nvp*2]; + + // Find polygon bounding box. + int npoly = 0; + for (int j = 0; j < nvp; ++j) + { + if(p[j] == 0xffff) break; + const unsigned short* v = &mesh.verts[p[j]*3]; + poly[j*3+0] = orig[0] + v[0]*cs; + poly[j*3+1] = orig[1] + v[1]*ch; + poly[j*3+2] = orig[2] + v[2]*cs; + npoly++; + } + + // Get the height data from the area of the polygon. + hp.xmin = bounds[i*4+0]; + hp.ymin = bounds[i*4+2]; + hp.width = bounds[i*4+1]-bounds[i*4+0]; + hp.height = bounds[i*4+3]-bounds[i*4+2]; + getHeightData(chf, p, npoly, mesh.verts, hp, stack); + + // Build detail mesh. + int nverts = 0; + if (!buildPolyDetail(poly, npoly, mesh.regs[i], + sampleDist, sampleMaxError, + chf, hp, verts, nverts, tris, + edges, idx, samples)) + { + goto failure; + } + + // Offset detail vertices, unnecassary? + for (int j = 0; j < nverts; ++j) + verts[j*3+1] += chf.ch; + + // Store detail submesh. + const int ntris = tris.size()/4; + + dmesh.meshes[i*4+0] = dmesh.nverts; + dmesh.meshes[i*4+1] = (unsigned short)nverts; + dmesh.meshes[i*4+2] = dmesh.ntris; + dmesh.meshes[i*4+3] = (unsigned short)ntris; + + // Store vertices, allocate more memory if necessary. + if (dmesh.nverts+nverts > vcap) + { + while (dmesh.nverts+nverts > vcap) + vcap += 256; + + float* newv = new float[vcap*3]; + if (!newv) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newv' (%d).", vcap*3); + goto failure; + } + if (dmesh.nverts) + memcpy(newv, dmesh.verts, sizeof(float)*3*dmesh.nverts); + delete [] dmesh.verts; + dmesh.verts = newv; + } + for (int j = 0; j < nverts; ++j) + { + dmesh.verts[dmesh.nverts*3+0] = verts[j*3+0]; + dmesh.verts[dmesh.nverts*3+1] = verts[j*3+1]; + dmesh.verts[dmesh.nverts*3+2] = verts[j*3+2]; + dmesh.nverts++; + } + + // Store triangles, allocate more memory if necessary. + if (dmesh.ntris+ntris > tcap) + { + while (dmesh.ntris+ntris > tcap) + tcap += 256; + unsigned char* newt = new unsigned char[tcap*4]; + if (!newt) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'newt' (%d).", tcap*4); + goto failure; + } + if (dmesh.ntris) + memcpy(newt, dmesh.tris, sizeof(unsigned char)*4*dmesh.ntris); + delete [] dmesh.tris; + dmesh.tris = newt; + } + for (int j = 0; j < ntris; ++j) + { + const int* t = &tris[j*4]; + dmesh.tris[dmesh.ntris*4+0] = (unsigned char)t[0]; + dmesh.tris[dmesh.ntris*4+1] = (unsigned char)t[1]; + dmesh.tris[dmesh.ntris*4+2] = (unsigned char)t[2]; + dmesh.tris[dmesh.ntris*4+3] = getTriFlags(&verts[t[0]*3], &verts[t[1]*3], &verts[t[2]*3], poly, npoly); + dmesh.ntris++; + } + } + + delete [] bounds; + + rcTimeVal endTime = rcGetPerformanceTimer(); + + if (rcGetBuildTimes()) + rcGetBuildTimes()->buildDetailMesh += rcGetDeltaTimeUsec(startTime, endTime); + + return true; + +failure: + + delete [] bounds; + + return false; +} + +bool rcMergePolyMeshDetails(rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh) +{ + rcTimeVal startTime = rcGetPerformanceTimer(); + + int maxVerts = 0; + int maxTris = 0; + int maxMeshes = 0; + + for (int i = 0; i < nmeshes; ++i) + { + if (!meshes[i]) continue; + maxVerts += meshes[i]->nverts; + maxTris += meshes[i]->ntris; + maxMeshes += meshes[i]->nmeshes; + } + + mesh.nmeshes = 0; + mesh.meshes = new unsigned short[maxMeshes*4]; + if (!mesh.meshes) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'pmdtl.meshes' (%d).", maxMeshes*4); + return false; + } + + mesh.ntris = 0; + mesh.tris = new unsigned char[maxTris*4]; + if (!mesh.tris) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.tris' (%d).", maxTris*4); + return false; + } + + mesh.nverts = 0; + mesh.verts = new float[maxVerts*3]; + if (!mesh.verts) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "rcBuildPolyMeshDetail: Out of memory 'dmesh.verts' (%d).", maxVerts*3); + return false; + } + + // Merge datas. + for (int i = 0; i < nmeshes; ++i) + { + rcPolyMeshDetail* dm = meshes[i]; + if (!dm) continue; + for (int j = 0; j < dm->nmeshes; ++j) + { + unsigned short* dst = &mesh.meshes[mesh.nmeshes*4]; + unsigned short* src = &dm->meshes[j*4]; + dst[0] = mesh.nverts+src[0]; + dst[1] = src[1]; + dst[2] = mesh.ntris+src[2]; + dst[3] = src[3]; + mesh.nmeshes++; + } + + for (int k = 0; k < dm->nverts; ++k) + { + vcopy(&mesh.verts[mesh.nverts*3], &dm->verts[k*3]); + mesh.nverts++; + } + for (int k = 0; k < dm->ntris; ++k) + { + mesh.tris[mesh.ntris*4+0] = dm->tris[k*4+0]; + mesh.tris[mesh.ntris*4+1] = dm->tris[k*4+1]; + mesh.tris[mesh.ntris*4+2] = dm->tris[k*4+2]; + mesh.tris[mesh.ntris*4+3] = dm->tris[k*4+3]; + mesh.ntris++; + } + } + + rcTimeVal endTime = rcGetPerformanceTimer(); + + if (rcGetBuildTimes()) + rcGetBuildTimes()->mergePolyMeshDetail += rcGetDeltaTimeUsec(startTime, endTime); + + return true; +} + diff --git a/Recast/Source/RecastRegion.cpp b/Recast/Source/RecastRegion.cpp index faaf3506..12ac1f0b 100644 --- a/Recast/Source/RecastRegion.cpp +++ b/Recast/Source/RecastRegion.cpp @@ -447,7 +447,7 @@ static void removeAdjacentNeighbours(rcRegion& reg) } } -void replaceNeighbour(rcRegion& reg, unsigned short oldId, unsigned short newId) +static void replaceNeighbour(rcRegion& reg, unsigned short oldId, unsigned short newId) { bool neiChanged = false; for (int i = 0; i < reg.connections.size(); ++i) @@ -467,7 +467,7 @@ void replaceNeighbour(rcRegion& reg, unsigned short oldId, unsigned short newId) removeAdjacentNeighbours(reg); } -bool canMergeWithRegion(rcRegion& reg, unsigned short id) +static bool canMergeWithRegion(rcRegion& reg, unsigned short id) { int n = 0; for (int i = 0; i < reg.connections.size(); ++i) diff --git a/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.pbxuser b/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.pbxuser index 2ad6467b..4783e15f 100644 --- a/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.pbxuser +++ b/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.pbxuser @@ -16,10 +16,14 @@ 8D1107260486CEB800E47090 /* Recast */, ); breakpoints = ( - 6B0249B11003783F00CF7107 /* Sample_TileMesh.cpp:786 */, + 6B0249B11003783F00CF7107 /* Sample_TileMesh.cpp:48 */, 6B0249ED10037C0A00CF7107 /* DetourTileNavMesh.cpp:1 */, 6B0249EF10037C0C00CF7107 /* DetourTileNavMesh.cpp:1 */, 6B024AC01004AB3900CF7107 /* DetourTileNavMesh.cpp:1 */, + 6B9D0932102722F0009B1A6C /* RecastTexture.cpp:301 */, + 6B9D09921028542A009B1A6C /* RecastDebugDraw.cpp:693 */, + 6B93FEFF1030443300F0C0DA /* Recast.cpp:273 */, + 6B9301521032F08300F0C0DA /* Recast.cpp:273 */, ); codeSenseManager = 6B8632AA0F78115100E2684A /* Code sense */; executables = ( @@ -110,143 +114,273 @@ PBXFileDataSource_Target_ColumnID, ); }; - PBXPerProjectTemplateStateSaveDate = 270109465; - PBXWorkspaceStateSaveDate = 270109465; + PBXPerProjectTemplateStateSaveDate = 272806358; + PBXWorkspaceStateSaveDate = 272806358; }; perUserProjectItems = { - 6B0249051001EABD00CF7107 = 6B0249051001EABD00CF7107 /* PBXTextBookmark */; 6B02498D1003751300CF7107 = 6B02498D1003751300CF7107 /* PBXTextBookmark */; 6B0249BE1003793900CF7107 = 6B0249BE1003793900CF7107 /* PBXTextBookmark */; 6B024A721004A2FE00CF7107 = 6B024A721004A2FE00CF7107 /* PBXTextBookmark */; 6B024BCF1005DFAB00CF7107 = 6B024BCF1005DFAB00CF7107 /* PBXTextBookmark */; - 6B024BD31006059C00CF7107 = 6B024BD31006059C00CF7107 /* PBXTextBookmark */; 6B024C011006098300CF7107 = 6B024C011006098300CF7107 /* PBXTextBookmark */; 6B024C041006098300CF7107 = 6B024C041006098300CF7107 /* PBXTextBookmark */; 6B024C1110060C7600CF7107 = 6B024C1110060C7600CF7107 /* PlistBookmark */; 6B024C1310060C7600CF7107 = 6B024C1310060C7600CF7107 /* PlistBookmark */; - 6B092B1A0FFC98FF0088D3A5 = 6B092B1A0FFC98FF0088D3A5 /* PBXTextBookmark */; - 6B092B4F0FFCA0A20088D3A5 = 6B092B4F0FFCA0A20088D3A5 /* PBXTextBookmark */; + 6B05AF59104042D5004A71D1 = 6B05AF59104042D5004A71D1 /* PBXTextBookmark */; + 6B05AFA810404FAB004A71D1 = 6B05AFA810404FAB004A71D1 /* PBXTextBookmark */; + 6B05AFA910404FAB004A71D1 = 6B05AFA910404FAB004A71D1 /* PBXTextBookmark */; + 6B05AFF010405B90004A71D1 = 6B05AFF010405B90004A71D1 /* PBXTextBookmark */; + 6B05B00C10405F0A004A71D1 = 6B05B00C10405F0A004A71D1 /* PBXTextBookmark */; + 6B05B00D10405F0A004A71D1 = 6B05B00D10405F0A004A71D1 /* PBXTextBookmark */; + 6B05B00F10405F0A004A71D1 = 6B05B00F10405F0A004A71D1 /* PBXTextBookmark */; + 6B05B01010405F0A004A71D1 = 6B05B01010405F0A004A71D1 /* PBXTextBookmark */; 6B092B500FFCA0A20088D3A5 = 6B092B500FFCA0A20088D3A5 /* PBXTextBookmark */; - 6B092B530FFCA0A20088D3A5 = 6B092B530FFCA0A20088D3A5 /* PBXTextBookmark */; 6B092BBC0FFCEC1A0088D3A5 = 6B092BBC0FFCEC1A0088D3A5 /* PBXTextBookmark */; - 6B092CC10FFE40160088D3A5 = 6B092CC10FFE40160088D3A5 /* PBXTextBookmark */; 6B1186211006945C0018F96F = 6B1186211006945C0018F96F /* PBXBookmark */; 6B11862D1006945C0018F96F = 6B11862D1006945C0018F96F /* PBXBookmark */; 6B1186301006945C0018F96F = 6B1186301006945C0018F96F /* PBXTextBookmark */; 6B1186311006945C0018F96F = 6B1186311006945C0018F96F /* PBXTextBookmark */; 6B1186411006945C0018F96F = 6B1186411006945C0018F96F /* PBXTextBookmark */; - 6B1186D1100699A00018F96F = 6B1186D1100699A00018F96F /* PBXTextBookmark */; - 6B1E02680F924A8500CC0038 = 6B1E02680F924A8500CC0038 /* PBXTextBookmark */; - 6B1E02FC0F92563500CC0038 = 6B1E02FC0F92563500CC0038 /* PBXTextBookmark */; 6B1E032E0F925D9100CC0038 = 6B1E032E0F925D9100CC0038 /* PBXTextBookmark */; 6B25B4080FFA13E9004F1BC4 = 6B25B4080FFA13E9004F1BC4 /* PBXTextBookmark */; 6B25B4120FFA1545004F1BC4 = 6B25B4120FFA1545004F1BC4 /* PBXTextBookmark */; 6B25B43E0FFA1786004F1BC4 = 6B25B43E0FFA1786004F1BC4 /* PBXTextBookmark */; 6B25B44B0FFA1968004F1BC4 = 6B25B44B0FFA1968004F1BC4 /* PBXTextBookmark */; 6B25B6250FFA63C8004F1BC4 = 6B25B6250FFA63C8004F1BC4 /* PBXTextBookmark */; - 6B2AEC620FFB8AB0005BE9CC = 6B2AEC620FFB8AB0005BE9CC /* PBXTextBookmark */; 6B2AEC670FFB8AB0005BE9CC = 6B2AEC670FFB8AB0005BE9CC /* PBXTextBookmark */; 6B2AEC740FFB8AB0005BE9CC = 6B2AEC740FFB8AB0005BE9CC /* PBXTextBookmark */; 6B2AEC750FFB8AB0005BE9CC = 6B2AEC750FFB8AB0005BE9CC /* PBXTextBookmark */; - 6B2AEC970FFB8AB0005BE9CC = 6B2AEC970FFB8AB0005BE9CC /* PBXTextBookmark */; - 6B2AECED0FFB8B41005BE9CC = 6B2AECED0FFB8B41005BE9CC /* PBXTextBookmark */; - 6B2AED930FFBA45B005BE9CC = 6B2AED930FFBA45B005BE9CC /* PBXTextBookmark */; + 6B3314EA1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314EA1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314EB1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314EB1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314EC1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314EC1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314ED1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314ED1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314EE1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314EE1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314EF1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314EF1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F01042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F01042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F11042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F11042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F21042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F21042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F31042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F31042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F41042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F41042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F51042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F51042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F61042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F61042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F71042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F71042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F81042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F81042BC8200E98B50 /* PBXTextBookmark */; + 6B3314F91042BC8200E98B50 /* PBXTextBookmark */ = 6B3314F91042BC8200E98B50 /* PBXTextBookmark */; + 6B3314FA1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314FA1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314FB1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314FB1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314FC1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314FC1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314FD1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314FD1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314FE1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314FE1042BC8200E98B50 /* PBXTextBookmark */; + 6B3314FF1042BC8200E98B50 /* PBXTextBookmark */ = 6B3314FF1042BC8200E98B50 /* PBXTextBookmark */; + 6B3315001042BC8200E98B50 /* PBXTextBookmark */ = 6B3315001042BC8200E98B50 /* PBXTextBookmark */; + 6B3315011042BC8200E98B50 /* PBXTextBookmark */ = 6B3315011042BC8200E98B50 /* PBXTextBookmark */; + 6B3315021042BC8200E98B50 /* PBXTextBookmark */ = 6B3315021042BC8200E98B50 /* PBXTextBookmark */; + 6B3315031042BC8200E98B50 /* PBXTextBookmark */ = 6B3315031042BC8200E98B50 /* PBXTextBookmark */; + 6B3315041042BC8200E98B50 /* PBXTextBookmark */ = 6B3315041042BC8200E98B50 /* PBXTextBookmark */; + 6B3315051042BC8200E98B50 /* PBXTextBookmark */ = 6B3315051042BC8200E98B50 /* PBXTextBookmark */; + 6B3315061042BC8200E98B50 /* PBXTextBookmark */ = 6B3315061042BC8200E98B50 /* PBXTextBookmark */; + 6B3315071042BC8200E98B50 /* PBXTextBookmark */ = 6B3315071042BC8200E98B50 /* PBXTextBookmark */; + 6B3315081042BC8200E98B50 /* PBXTextBookmark */ = 6B3315081042BC8200E98B50 /* PBXTextBookmark */; + 6B3315091042BC8200E98B50 /* PBXTextBookmark */ = 6B3315091042BC8200E98B50 /* PBXTextBookmark */; + 6B33150A1042BC8200E98B50 /* PBXTextBookmark */ = 6B33150A1042BC8200E98B50 /* PBXTextBookmark */; + 6B33150B1042BC8200E98B50 /* PBXTextBookmark */ = 6B33150B1042BC8200E98B50 /* PBXTextBookmark */; + 6B33150C1042BC8200E98B50 /* PBXTextBookmark */ = 6B33150C1042BC8200E98B50 /* PBXTextBookmark */; + 6B33150D1042BC8200E98B50 /* PBXTextBookmark */ = 6B33150D1042BC8200E98B50 /* PBXTextBookmark */; + 6B33150E1042BC8200E98B50 /* PBXTextBookmark */ = 6B33150E1042BC8200E98B50 /* PBXTextBookmark */; + 6B33150F1042BC8200E98B50 /* PBXTextBookmark */ = 6B33150F1042BC8200E98B50 /* PBXTextBookmark */; + 6B3315101042BC8200E98B50 /* PBXTextBookmark */ = 6B3315101042BC8200E98B50 /* PBXTextBookmark */; + 6B3315111042BC8200E98B50 /* PBXTextBookmark */ = 6B3315111042BC8200E98B50 /* PBXTextBookmark */; + 6B3315121042BC8200E98B50 /* PBXTextBookmark */ = 6B3315121042BC8200E98B50 /* PBXTextBookmark */; + 6B3315131042BC8200E98B50 /* PBXTextBookmark */ = 6B3315131042BC8200E98B50 /* PBXTextBookmark */; + 6B3315141042BC8200E98B50 /* PBXTextBookmark */ = 6B3315141042BC8200E98B50 /* PBXTextBookmark */; + 6B3315151042BC8200E98B50 /* PBXTextBookmark */ = 6B3315151042BC8200E98B50 /* PBXTextBookmark */; + 6B3315161042BC8200E98B50 /* PBXTextBookmark */ = 6B3315161042BC8200E98B50 /* PBXTextBookmark */; + 6B3315171042BC8200E98B50 /* PBXTextBookmark */ = 6B3315171042BC8200E98B50 /* PBXTextBookmark */; + 6B3315181042BC8200E98B50 /* PBXTextBookmark */ = 6B3315181042BC8200E98B50 /* PBXTextBookmark */; + 6B3315191042BC8200E98B50 /* PBXTextBookmark */ = 6B3315191042BC8200E98B50 /* PBXTextBookmark */; + 6B33151A1042BC8200E98B50 /* PBXTextBookmark */ = 6B33151A1042BC8200E98B50 /* PBXTextBookmark */; + 6B33151B1042BC8200E98B50 /* PBXTextBookmark */ = 6B33151B1042BC8200E98B50 /* PBXTextBookmark */; + 6B33151C1042BC8200E98B50 /* PBXTextBookmark */ = 6B33151C1042BC8200E98B50 /* PBXTextBookmark */; + 6B33151D1042BC8200E98B50 /* PBXTextBookmark */ = 6B33151D1042BC8200E98B50 /* PBXTextBookmark */; + 6B3315291042BCC100E98B50 /* PBXTextBookmark */ = 6B3315291042BCC100E98B50 /* PBXTextBookmark */; + 6B33152B1042BCEF00E98B50 /* PBXTextBookmark */ = 6B33152B1042BCEF00E98B50 /* PBXTextBookmark */; + 6B33152E1042BD3500E98B50 /* PBXTextBookmark */ = 6B33152E1042BD3500E98B50 /* PBXTextBookmark */; + 6B33152F1042BD3500E98B50 /* PBXTextBookmark */ = 6B33152F1042BD3500E98B50 /* PBXTextBookmark */; + 6B3315301042BD3500E98B50 /* PBXTextBookmark */ = 6B3315301042BD3500E98B50 /* PBXTextBookmark */; + 6B3315311042BD3500E98B50 /* PBXTextBookmark */ = 6B3315311042BD3500E98B50 /* PBXTextBookmark */; + 6B3315321042BE1600E98B50 /* PBXTextBookmark */ = 6B3315321042BE1600E98B50 /* PBXTextBookmark */; + 6B3315331042BE1600E98B50 /* PBXTextBookmark */ = 6B3315331042BE1600E98B50 /* PBXTextBookmark */; + 6B3315341042BE1600E98B50 /* PBXTextBookmark */ = 6B3315341042BE1600E98B50 /* PBXTextBookmark */; + 6B3315351042BE1600E98B50 /* PBXTextBookmark */ = 6B3315351042BE1600E98B50 /* PBXTextBookmark */; + 6B3315361042BE1600E98B50 /* PBXTextBookmark */ = 6B3315361042BE1600E98B50 /* PBXTextBookmark */; + 6B3315371042BE1600E98B50 /* PBXTextBookmark */ = 6B3315371042BE1600E98B50 /* PBXTextBookmark */; + 6B3315381042BE1600E98B50 /* PBXTextBookmark */ = 6B3315381042BE1600E98B50 /* PBXTextBookmark */; + 6B3315391042BE1600E98B50 /* PBXTextBookmark */ = 6B3315391042BE1600E98B50 /* PBXTextBookmark */; + 6B33153A1042BE1600E98B50 /* PBXTextBookmark */ = 6B33153A1042BE1600E98B50 /* PBXTextBookmark */; + 6B33153B1042BE1600E98B50 /* PBXTextBookmark */ = 6B33153B1042BE1600E98B50 /* PBXTextBookmark */; + 6B33153C1042BE1600E98B50 /* PBXTextBookmark */ = 6B33153C1042BE1600E98B50 /* PBXTextBookmark */; + 6B33153D1042BE1600E98B50 /* PBXTextBookmark */ = 6B33153D1042BE1600E98B50 /* PBXTextBookmark */; + 6B33153E1042BE1600E98B50 /* PBXTextBookmark */ = 6B33153E1042BE1600E98B50 /* PBXTextBookmark */; + 6B33153F1042BE1600E98B50 /* PBXTextBookmark */ = 6B33153F1042BE1600E98B50 /* PBXTextBookmark */; + 6B3315401042BE1600E98B50 /* PBXTextBookmark */ = 6B3315401042BE1600E98B50 /* PBXTextBookmark */; + 6B3315411042BE1600E98B50 /* PBXTextBookmark */ = 6B3315411042BE1600E98B50 /* PBXTextBookmark */; + 6B3315421042BE1600E98B50 /* PBXTextBookmark */ = 6B3315421042BE1600E98B50 /* PBXTextBookmark */; + 6B3315431042BE1600E98B50 /* PBXTextBookmark */ = 6B3315431042BE1600E98B50 /* PBXTextBookmark */; + 6B3315441042BE4600E98B50 /* PBXTextBookmark */ = 6B3315441042BE4600E98B50 /* PBXTextBookmark */; + 6B3315451042BED800E98B50 /* PBXTextBookmark */ = 6B3315451042BED800E98B50 /* PBXTextBookmark */; + 6B3315481042C02C00E98B50 /* PBXTextBookmark */ = 6B3315481042C02C00E98B50 /* PBXTextBookmark */; + 6B3315491042C02C00E98B50 /* PBXTextBookmark */ = 6B3315491042C02C00E98B50 /* PBXTextBookmark */; + 6B33154A1042C0A500E98B50 /* PBXTextBookmark */ = 6B33154A1042C0A500E98B50 /* PBXTextBookmark */; + 6B41875F10397C9F00FBF4A5 = 6B41875F10397C9F00FBF4A5 /* PBXTextBookmark */; + 6B41876A1039827000FBF4A5 = 6B41876A1039827000FBF4A5 /* PBXTextBookmark */; + 6B41878E1039854600FBF4A5 = 6B41878E1039854600FBF4A5 /* PBXTextBookmark */; + 6B4187B11039909100FBF4A5 = 6B4187B11039909100FBF4A5 /* PBXTextBookmark */; + 6B4187C41039909100FBF4A5 = 6B4187C41039909100FBF4A5 /* PBXTextBookmark */; + 6B418869103ACAC700FBF4A5 = 6B418869103ACAC700FBF4A5 /* PBXTextBookmark */; 6B458EA80FB4540500044EA9 = 6B458EA80FB4540500044EA9 /* PBXTextBookmark */; - 6B555D24100B136A00247EA3 = 6B555D24100B136A00247EA3 /* PBXTextBookmark */; 6B555D26100B136A00247EA3 = 6B555D26100B136A00247EA3 /* PBXTextBookmark */; 6B555D30100B143200247EA3 = 6B555D30100B143200247EA3 /* PBXTextBookmark */; 6B555DC9100B236A00247EA3 = 6B555DC9100B236A00247EA3 /* PBXTextBookmark */; 6B555E01100B285300247EA3 = 6B555E01100B285300247EA3 /* PBXTextBookmark */; 6B555E13100B285300247EA3 = 6B555E13100B285300247EA3 /* PBXTextBookmark */; - 6B555E5F100B334900247EA3 = 6B555E5F100B334900247EA3 /* PBXTextBookmark */; - 6B555E60100B334900247EA3 = 6B555E60100B334900247EA3 /* PBXTextBookmark */; - 6B555EA1100B37AB00247EA3 = 6B555EA1100B37AB00247EA3 /* PBXTextBookmark */; 6B555EE0100B39A600247EA3 = 6B555EE0100B39A600247EA3 /* PBXTextBookmark */; 6B555EF9100B42E600247EA3 = 6B555EF9100B42E600247EA3 /* PBXTextBookmark */; - 6B555F0C100B473F00247EA3 = 6B555F0C100B473F00247EA3 /* PBXTextBookmark */; 6B555F0D100B473F00247EA3 = 6B555F0D100B473F00247EA3 /* PBXTextBookmark */; 6B555F0E100B473F00247EA3 = 6B555F0E100B473F00247EA3 /* PBXTextBookmark */; - 6B555F0F100B473F00247EA3 = 6B555F0F100B473F00247EA3 /* PBXTextBookmark */; - 6B555FB4100B595C00247EA3 = 6B555FB4100B595C00247EA3 /* PBXTextBookmark */; - 6B58CAE510198B2400956BA2 /* PBXTextBookmark */ = 6B58CAE510198B2400956BA2 /* PBXTextBookmark */; + 6B6241E91034B2FA0002E346 = 6B6241E91034B2FA0002E346 /* PBXTextBookmark */; + 6B6241EB1034B2FA0002E346 = 6B6241EB1034B2FA0002E346 /* PBXTextBookmark */; + 6B74D043103DD3B600623975 = 6B74D043103DD3B600623975 /* PBXTextBookmark */; + 6B74D052103DD64C00623975 = 6B74D052103DD64C00623975 /* PBXTextBookmark */; + 6B74D091103DDCC300623975 = 6B74D091103DDCC300623975 /* PBXTextBookmark */; 6B7707B90FBD66CF00D21BAE = 6B7707B90FBD66CF00D21BAE /* PBXTextBookmark */; 6B7707F00FBD90F100D21BAE = 6B7707F00FBD90F100D21BAE /* PBXTextBookmark */; 6B7707F90FBD90F100D21BAE = 6B7707F90FBD90F100D21BAE /* PBXTextBookmark */; 6B7708F70FBDA96300D21BAE = 6B7708F70FBDA96300D21BAE /* PBXTextBookmark */; 6B7EBB69100721310066EF8C = 6B7EBB69100721310066EF8C /* PBXTextBookmark */; 6B86333B0F7813A600E2684A = 6B86333B0F7813A600E2684A /* PBXTextBookmark */; - 6B8AE8DA10121C6000FF1D07 = 6B8AE8DA10121C6000FF1D07 /* PBXTextBookmark */; 6B8AE8DF10121C6000FF1D07 = 6B8AE8DF10121C6000FF1D07 /* PBXTextBookmark */; 6B8AE8FA10123B5700FF1D07 = 6B8AE8FA10123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE8FB10123B5700FF1D07 = 6B8AE8FB10123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE8FC10123B5700FF1D07 = 6B8AE8FC10123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE8FE10123B5700FF1D07 = 6B8AE8FE10123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90010123B5700FF1D07 = 6B8AE90010123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90210123B5700FF1D07 = 6B8AE90210123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90310123B5700FF1D07 = 6B8AE90310123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90410123B5700FF1D07 = 6B8AE90410123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90510123B5700FF1D07 = 6B8AE90510123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90610123B5700FF1D07 = 6B8AE90610123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90710123B5700FF1D07 = 6B8AE90710123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90D10123B5700FF1D07 = 6B8AE90D10123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90E10123B5700FF1D07 = 6B8AE90E10123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE90F10123B5700FF1D07 = 6B8AE90F10123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE91010123B5700FF1D07 = 6B8AE91010123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE91810123B5700FF1D07 = 6B8AE91810123B5700FF1D07 /* PBXTextBookmark */; - 6B8AE91910123B5700FF1D07 = 6B8AE91910123B5700FF1D07 /* PBXTextBookmark */; 6B8DB3900F9798DE007FA9E1 = 6B8DB3900F9798DE007FA9E1 /* PBXTextBookmark */; - 6B92CE68100E0577003DA304 = 6B92CE68100E0577003DA304 /* PBXTextBookmark */; 6B92CE69100E0577003DA304 = 6B92CE69100E0577003DA304 /* PBXTextBookmark */; 6B92CE6A100E0577003DA304 = 6B92CE6A100E0577003DA304 /* PBXTextBookmark */; - 6B92CE6F100E0577003DA304 = 6B92CE6F100E0577003DA304 /* PBXTextBookmark */; - 6B92CE70100E0577003DA304 = 6B92CE70100E0577003DA304 /* PBXTextBookmark */; - 6B92CE72100E0577003DA304 = 6B92CE72100E0577003DA304 /* PBXTextBookmark */; 6B92CE8A100E0739003DA304 = 6B92CE8A100E0739003DA304 /* PBXTextBookmark */; - 6B995BDF0FE0D9B300D5C493 = 6B995BDF0FE0D9B300D5C493 /* PBXTextBookmark */; + 6B93FDBB102FFCFE00F0C0DA = 6B93FDBB102FFCFE00F0C0DA /* PBXTextBookmark */; + 6B93FDEB10300CBE00F0C0DA = 6B93FDEB10300CBE00F0C0DA /* PBXTextBookmark */; + 6B93FDF010300CBE00F0C0DA = 6B93FDF010300CBE00F0C0DA /* PBXTextBookmark */; + 6B93FE7C1030279700F0C0DA = 6B93FE7C1030279700F0C0DA /* PBXTextBookmark */; + 6B95064210383C6900213080 = 6B95064210383C6900213080 /* PBXTextBookmark */; + 6B95064C10383C6900213080 = 6B95064C10383C6900213080 /* PBXTextBookmark */; + 6B95065010383C6900213080 = 6B95065010383C6900213080 /* PBXTextBookmark */; + 6B9506851038680900213080 = 6B9506851038680900213080 /* PBXTextBookmark */; + 6B9506891038680900213080 = 6B9506891038680900213080 /* PBXTextBookmark */; + 6B95069A103869D900213080 = 6B95069A103869D900213080 /* PBXTextBookmark */; + 6B95069B103869D900213080 = 6B95069B103869D900213080 /* PBXTextBookmark */; + 6B9506F810388A4200213080 = 6B9506F810388A4200213080 /* PBXTextBookmark */; + 6B95070510388A4200213080 = 6B95070510388A4200213080 /* PBXTextBookmark */; + 6B9507401038910D00213080 = 6B9507401038910D00213080 /* PBXTextBookmark */; + 6B950746103891A700213080 = 6B950746103891A700213080 /* PBXTextBookmark */; + 6B955A0610359EBB00FE9FE3 = 6B955A0610359EBB00FE9FE3 /* PBXTextBookmark */; + 6B955A0810359EBB00FE9FE3 = 6B955A0810359EBB00FE9FE3 /* PBXTextBookmark */; + 6B955A0A10359EBB00FE9FE3 = 6B955A0A10359EBB00FE9FE3 /* PBXTextBookmark */; + 6B955A0C10359EBB00FE9FE3 = 6B955A0C10359EBB00FE9FE3 /* PBXTextBookmark */; 6B995F9F100F336B00D7BF5A = 6B995F9F100F336B00D7BF5A /* PBXTextBookmark */; 6B995FA2100F336B00D7BF5A = 6B995FA2100F336B00D7BF5A /* PBXTextBookmark */; 6B995FDF100F387200D7BF5A = 6B995FDF100F387200D7BF5A /* PBXTextBookmark */; - 6B996059100F42AF00D7BF5A = 6B996059100F42AF00D7BF5A /* PBXTextBookmark */; 6B9B7D9D0FF91AC600A9090F = 6B9B7D9D0FF91AC600A9090F /* PBXTextBookmark */; - 6B9B7DA30FF91AC600A9090F = 6B9B7DA30FF91AC600A9090F /* PBXTextBookmark */; - 6B9B7DA40FF91AC600A9090F = 6B9B7DA40FF91AC600A9090F /* PBXTextBookmark */; - 6BB787C30FC03EAD003C24DB = 6BB787C30FC03EAD003C24DB /* PBXTextBookmark */; + 6B9D09E210285EFE009B1A6C = 6B9D09E210285EFE009B1A6C /* PBXTextBookmark */; + 6B9D0AD010298E12009B1A6C = 6B9D0AD010298E12009B1A6C /* PBXTextBookmark */; + 6B9D0AF4102991F0009B1A6C = 6B9D0AF4102991F0009B1A6C /* PBXTextBookmark */; 6BB788290FC0593E003C24DB = 6BB788290FC0593E003C24DB /* PBXTextBookmark */; 6BB7882A0FC0593E003C24DB = 6BB7882A0FC0593E003C24DB /* PBXTextBookmark */; 6BB7882B0FC0593E003C24DB = 6BB7882B0FC0593E003C24DB /* PBXTextBookmark */; 6BB85D3E0FCEAA6300758966 = 6BB85D3E0FCEAA6300758966 /* PBXTextBookmark */; - 6BC620920FD7C2380022CACF = 6BC620920FD7C2380022CACF /* PBXTextBookmark */; - 6BC745A70FF527E50083A694 = 6BC745A70FF527E50083A694 /* PBXTextBookmark */; - 6BC745A80FF527E50083A694 = 6BC745A80FF527E50083A694 /* PBXTextBookmark */; - 6BC745AD0FF527E50083A694 = 6BC745AD0FF527E50083A694 /* PBXTextBookmark */; - 6BC745AE0FF527E50083A694 = 6BC745AE0FF527E50083A694 /* PBXTextBookmark */; 6BC745AF0FF527E50083A694 = 6BC745AF0FF527E50083A694 /* PBXTextBookmark */; - 6BD4DBB910145A50003FF199 = 6BD4DBB910145A50003FF199 /* PBXTextBookmark */; - 6BD4DBBA10145A50003FF199 = 6BD4DBBA10145A50003FF199 /* PBXTextBookmark */; - 6BD4DBBD10145A50003FF199 = 6BD4DBBD10145A50003FF199 /* PBXTextBookmark */; - 6BD4DBBE10145A50003FF199 = 6BD4DBBE10145A50003FF199 /* PBXTextBookmark */; - 6BD4DBBF10145A50003FF199 = 6BD4DBBF10145A50003FF199 /* PBXTextBookmark */; - 6BD4DBC710145C42003FF199 = 6BD4DBC710145C42003FF199 /* PBXTextBookmark */; - 6BD4DBC810145C42003FF199 = 6BD4DBC810145C42003FF199 /* PBXTextBookmark */; - 6BD4DBC910145C42003FF199 = 6BD4DBC910145C42003FF199 /* PBXTextBookmark */; - 6BD4DBCA10145C42003FF199 = 6BD4DBCA10145C42003FF199 /* PBXTextBookmark */; - 6BD4DBCB10145C42003FF199 = 6BD4DBCB10145C42003FF199 /* PBXTextBookmark */; - 6BD4DBCC10145C42003FF199 = 6BD4DBCC10145C42003FF199 /* PBXTextBookmark */; - 6BD4DBCD10145C42003FF199 = 6BD4DBCD10145C42003FF199 /* PBXTextBookmark */; - 6BD4DBCE10145C42003FF199 = 6BD4DBCE10145C42003FF199 /* PBXTextBookmark */; - 6BD4DBCF10145C42003FF199 = 6BD4DBCF10145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD010145C42003FF199 = 6BD4DBD010145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD110145C42003FF199 = 6BD4DBD110145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD210145C42003FF199 = 6BD4DBD210145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD310145C42003FF199 = 6BD4DBD310145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD410145C42003FF199 = 6BD4DBD410145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD510145C42003FF199 = 6BD4DBD510145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD610145C42003FF199 = 6BD4DBD610145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD710145C42003FF199 = 6BD4DBD710145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD810145C42003FF199 = 6BD4DBD810145C42003FF199 /* PBXTextBookmark */; - 6BD4DBD910145C42003FF199 = 6BD4DBD910145C42003FF199 /* PBXTextBookmark */; - 6BD4DBDA10145C42003FF199 = 6BD4DBDA10145C42003FF199 /* PBXTextBookmark */; - 6BD4DBDC101485D3003FF199 = 6BD4DBDC101485D3003FF199 /* PBXTextBookmark */; + 6BF26B4310413CC80099C14A = 6BF26B4310413CC80099C14A /* PBXTextBookmark */; + 6BF26B4410413CC80099C14A = 6BF26B4410413CC80099C14A /* PBXTextBookmark */; + 6BF26B4510413CC80099C14A = 6BF26B4510413CC80099C14A /* PBXTextBookmark */; + 6BF26B4610413CC80099C14A = 6BF26B4610413CC80099C14A /* PBXTextBookmark */; + 6BF26B5110413CF00099C14A = 6BF26B5110413CF00099C14A /* PBXTextBookmark */; + 6BF26B641041423B0099C14A = 6BF26B641041423B0099C14A /* PBXTextBookmark */; + 6BF26B651041423B0099C14A = 6BF26B651041423B0099C14A /* PBXTextBookmark */; + 6BF26B661041423B0099C14A = 6BF26B661041423B0099C14A /* PBXTextBookmark */; + 6BF26B671041423B0099C14A = 6BF26B671041423B0099C14A /* PBXTextBookmark */; + 6BF26B681041423B0099C14A = 6BF26B681041423B0099C14A /* PBXTextBookmark */; + 6BF26B691041423B0099C14A = 6BF26B691041423B0099C14A /* PBXTextBookmark */; + 6BF26B6A1041423B0099C14A = 6BF26B6A1041423B0099C14A /* PBXTextBookmark */; + 6BF26B6B1041423B0099C14A = 6BF26B6B1041423B0099C14A /* PBXTextBookmark */; + 6BF26B781041437C0099C14A = 6BF26B781041437C0099C14A /* PBXTextBookmark */; + 6BF26B7B1041437C0099C14A = 6BF26B7B1041437C0099C14A /* PBXTextBookmark */; + 6BF26B7D1041437C0099C14A = 6BF26B7D1041437C0099C14A /* PBXTextBookmark */; + 6BF26B85104143E10099C14A = 6BF26B85104143E10099C14A /* PBXTextBookmark */; + 6BF26B86104143E10099C14A = 6BF26B86104143E10099C14A /* PBXTextBookmark */; + 6BF26B8C104144910099C14A = 6BF26B8C104144910099C14A /* PBXTextBookmark */; + 6BF26B92104144F90099C14A = 6BF26B92104144F90099C14A /* PBXTextBookmark */; + 6BF26B93104144F90099C14A = 6BF26B93104144F90099C14A /* PBXTextBookmark */; + 6BF26B94104144F90099C14A = 6BF26B94104144F90099C14A /* PBXTextBookmark */; + 6BF26B9E104145630099C14A = 6BF26B9E104145630099C14A /* PBXTextBookmark */; + 6BF26B9F104145630099C14A = 6BF26B9F104145630099C14A /* PBXTextBookmark */; + 6BF26BA5104145A20099C14A = 6BF26BA5104145A20099C14A /* PBXTextBookmark */; + 6BF26BA7104151460099C14A = 6BF26BA7104151460099C14A /* PBXTextBookmark */; + 6BF26BAA104151460099C14A = 6BF26BAA104151460099C14A /* PBXTextBookmark */; + 6BF26BAE104151A50099C14A = 6BF26BAE104151A50099C14A /* PBXTextBookmark */; + 6BF26BB51041520F0099C14A = 6BF26BB51041520F0099C14A /* PBXTextBookmark */; + 6BF26BC4104158E90099C14A = 6BF26BC4104158E90099C14A /* PBXTextBookmark */; + 6BF26BC5104158E90099C14A = 6BF26BC5104158E90099C14A /* PBXTextBookmark */; + 6BF26BC6104158E90099C14A = 6BF26BC6104158E90099C14A /* PBXTextBookmark */; + 6BF26BC7104158E90099C14A = 6BF26BC7104158E90099C14A /* PBXTextBookmark */; + 6BF26BC9104158E90099C14A = 6BF26BC9104158E90099C14A /* PBXTextBookmark */; + 6BF26BCA104158E90099C14A = 6BF26BCA104158E90099C14A /* PBXTextBookmark */; + 6BF26BCE104158E90099C14A = 6BF26BCE104158E90099C14A /* PBXTextBookmark */; + 6BF26BD1104158E90099C14A = 6BF26BD1104158E90099C14A /* PBXTextBookmark */; + 6BF26BD2104158E90099C14A = 6BF26BD2104158E90099C14A /* PBXTextBookmark */; + 6BF26BD3104158E90099C14A = 6BF26BD3104158E90099C14A /* PBXTextBookmark */; + 6BF26BD4104158E90099C14A = 6BF26BD4104158E90099C14A /* PBXTextBookmark */; + 6BF26BD5104158E90099C14A = 6BF26BD5104158E90099C14A /* PBXTextBookmark */; + 6BF26BD6104158E90099C14A = 6BF26BD6104158E90099C14A /* PBXTextBookmark */; + 6BF26BD7104158E90099C14A = 6BF26BD7104158E90099C14A /* PBXTextBookmark */; + 6BF26BD8104158E90099C14A = 6BF26BD8104158E90099C14A /* PBXTextBookmark */; + 6BF26BDA104158E90099C14A = 6BF26BDA104158E90099C14A /* PBXTextBookmark */; + 6BF26BDC104158E90099C14A = 6BF26BDC104158E90099C14A /* PBXTextBookmark */; + 6BF26BDE104158E90099C14A = 6BF26BDE104158E90099C14A /* PBXTextBookmark */; + 6BF26BE0104158E90099C14A = 6BF26BE0104158E90099C14A /* PBXTextBookmark */; + 6BF26BE2104158E90099C14A = 6BF26BE2104158E90099C14A /* PBXTextBookmark */; + 6BF26BE4104158E90099C14A = 6BF26BE4104158E90099C14A /* PBXTextBookmark */; + 6BF26BE5104158E90099C14A = 6BF26BE5104158E90099C14A /* PBXTextBookmark */; + 6BF26BE6104158E90099C14A = 6BF26BE6104158E90099C14A /* PBXTextBookmark */; + 6BF26BE7104158E90099C14A = 6BF26BE7104158E90099C14A /* PBXTextBookmark */; + 6BF26BE8104158E90099C14A = 6BF26BE8104158E90099C14A /* PBXTextBookmark */; + 6BF26BE9104158E90099C14A = 6BF26BE9104158E90099C14A /* PBXTextBookmark */; + 6BF26BEA104158E90099C14A = 6BF26BEA104158E90099C14A /* PBXTextBookmark */; + 6BF26BEC104158E90099C14A = 6BF26BEC104158E90099C14A /* PBXTextBookmark */; + 6BF26BED104158E90099C14A = 6BF26BED104158E90099C14A /* PBXTextBookmark */; + 6BF26BEE104158E90099C14A = 6BF26BEE104158E90099C14A /* PBXTextBookmark */; + 6BF26C0B10415C680099C14A = 6BF26C0B10415C680099C14A /* PBXTextBookmark */; + 6BF26C0C10415C680099C14A = 6BF26C0C10415C680099C14A /* PBXTextBookmark */; + 6BF26C1110415C680099C14A = 6BF26C1110415C680099C14A /* PBXTextBookmark */; + 6BF26C1210415C680099C14A = 6BF26C1210415C680099C14A /* PBXTextBookmark */; + 6BF26C1310415C680099C14A = 6BF26C1310415C680099C14A /* PBXTextBookmark */; + 6BF26C1410415C680099C14A = 6BF26C1410415C680099C14A /* PBXTextBookmark */; + 6BF26C1510415C680099C14A = 6BF26C1510415C680099C14A /* PBXTextBookmark */; + 6BF26C1610415C680099C14A = 6BF26C1610415C680099C14A /* PBXTextBookmark */; + 6BF26C1710415C680099C14A = 6BF26C1710415C680099C14A /* PBXTextBookmark */; + 6BF26C1810415C680099C14A = 6BF26C1810415C680099C14A /* PBXTextBookmark */; + 6BF26C1910415C680099C14A = 6BF26C1910415C680099C14A /* PBXTextBookmark */; + 6BF26C1A10415C680099C14A = 6BF26C1A10415C680099C14A /* PBXTextBookmark */; + 6BF26C1B10415C680099C14A = 6BF26C1B10415C680099C14A /* PBXTextBookmark */; + 6BF26C2410415CA60099C14A = 6BF26C2410415CA60099C14A /* PBXTextBookmark */; + 6BF26C2910415D040099C14A = 6BF26C2910415D040099C14A /* PBXTextBookmark */; + 6BF26C301041A5190099C14A = 6BF26C301041A5190099C14A /* PBXTextBookmark */; + 6BF26C311041A5190099C14A = 6BF26C311041A5190099C14A /* PBXTextBookmark */; + 6BF26C321041A5190099C14A = 6BF26C321041A5190099C14A /* PBXTextBookmark */; + 6BF26C341041A5190099C14A = 6BF26C341041A5190099C14A /* PBXTextBookmark */; + 6BF26C351041A5190099C14A = 6BF26C351041A5190099C14A /* PBXTextBookmark */; + 6BF26C361041A5190099C14A = 6BF26C361041A5190099C14A /* PBXTextBookmark */; + 6BF26C371041A5190099C14A = 6BF26C371041A5190099C14A /* PBXTextBookmark */; + 6BF26C381041A5190099C14A = 6BF26C381041A5190099C14A /* PBXTextBookmark */; + 6BF26C3C1041A5F00099C14A = 6BF26C3C1041A5F00099C14A /* PBXTextBookmark */; + 6BF26C3D1041A5F00099C14A = 6BF26C3D1041A5F00099C14A /* PBXTextBookmark */; + 6BF26C3E1041A5F00099C14A = 6BF26C3E1041A5F00099C14A /* PBXTextBookmark */; + 6BF26C451042A5530099C14A = 6BF26C451042A5530099C14A /* PBXTextBookmark */; }; sourceControlManager = 6B8632A90F78115100E2684A /* Source Control */; userBuildSettings = { @@ -260,16 +394,6 @@ sepNavWindowFrame = "{{38, 57}, {1011, 695}}"; }; }; - 6B0249051001EABD00CF7107 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; - name = "BuilderStatMeshTiled.cpp: 828"; - rLen = 0; - rLoc = 23956; - rType = 0; - vrLen = 2467; - vrLoc = 27512; - }; 6B02498D1003751300CF7107 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B25B6110FFA62AD004F1BC4 /* Sample_StatMesh.h */; @@ -280,7 +404,7 @@ vrLen = 558; vrLoc = 362; }; - 6B0249B11003783F00CF7107 /* Sample_TileMesh.cpp:786 */ = { + 6B0249B11003783F00CF7107 /* Sample_TileMesh.cpp:48 */ = { isa = PBXFileBreakpoint; actions = ( ); @@ -292,9 +416,9 @@ functionName = "BuilderTiledMesh::toolRecalc()"; hitCount = 0; ignoreCount = 0; - lineNumber = 786; + lineNumber = 48; location = Recast; - modificationTime = 269435439.5894469; + modificationTime = 272654272.9215111; state = 1; }; 6B0249BE1003793900CF7107 /* PBXTextBookmark */ = { @@ -321,7 +445,7 @@ ignoreCount = 0; lineNumber = 1; location = Recast; - modificationTime = 269435439.589783; + modificationTime = 272654272.921926; state = 1; }; 6B0249EF10037C0C00CF7107 /* DetourTileNavMesh.cpp:1 */ = { @@ -338,7 +462,7 @@ ignoreCount = 0; lineNumber = 1; location = Recast; - modificationTime = 269435439.589934; + modificationTime = 272654272.92219; state = 1; }; 6B024A721004A2FE00CF7107 /* PBXTextBookmark */ = { @@ -346,10 +470,10 @@ fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; name = "DetourTiledNavMeshBuilder.cpp: 192"; rLen = 0; - rLoc = 4099; + rLoc = 5231; rType = 0; vrLen = 0; - vrLoc = 4363; + vrLoc = 4345; }; 6B024AC01004AB3900CF7107 /* DetourTileNavMesh.cpp:1 */ = { isa = PBXFileBreakpoint; @@ -365,7 +489,7 @@ ignoreCount = 0; lineNumber = 1; location = Recast; - modificationTime = 269435439.590075; + modificationTime = 272654272.92241; state = 1; }; 6B024BCF1005DFAB00CF7107 /* PBXTextBookmark */ = { @@ -373,21 +497,11 @@ fRef = 6B2AEC510FFB8946005BE9CC /* Sample_TileMesh.h */; name = "BuilderTiledMesh.h: 61"; rLen = 16; - rLoc = 2114; + rLoc = 2139; rType = 0; vrLen = 588; vrLoc = 718; }; - 6B024BD31006059C00CF7107 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */; - name = "DetourStatNavMeshBuilder.h: 1"; - rLen = 918; - rLoc = 0; - rType = 0; - vrLen = 1284; - vrLoc = 0; - }; 6B024C011006098300CF7107 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 089C165DFE840E0CC02AAC07 /* English */; @@ -430,25 +544,85 @@ rLen = 0; rLoc = 2147483647; }; - 6B092B1A0FFC98FF0088D3A5 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC570FFB89F4005BE9CC /* Sample_StatMeshTiled.h */; - name = "BuilderStatMeshTiled.h: 44"; - rLen = 117; - rLoc = 950; - rType = 0; - vrLen = 580; - vrLoc = 440; - }; - 6B092B4F0FFCA0A20088D3A5 /* PBXTextBookmark */ = { + 6B05AF59104042D5004A71D1 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */; - name = "RecastMesh.cpp: 493"; + name = "RecastMesh.cpp: 1143"; rLen = 0; - rLoc = 12878; + rLoc = 28267; rType = 0; - vrLen = 749; - vrLoc = 12474; + vrLen = 813; + vrLoc = 27699; + }; + 6B05AFA810404FAB004A71D1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; + name = "Recast.h: 183"; + rLen = 16; + rLoc = 7053; + rType = 0; + vrLen = 758; + vrLoc = 7108; + }; + 6B05AFA910404FAB004A71D1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 923"; + rLen = 0; + rLoc = 24134; + rType = 0; + vrLen = 651; + vrLoc = 23170; + }; + 6B05AFF010405B90004A71D1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 278"; + rLen = 0; + rLoc = 5367; + rType = 0; + vrLen = 808; + vrLoc = 6250; + }; + 6B05B00C10405F0A004A71D1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7F0F7FCBFE00459200 /* RecastDebugDraw.h */; + name = "RecastDebugDraw.h: 45"; + rLen = 0; + rLoc = 1918; + rType = 0; + vrLen = 1760; + vrLoc = 1037; + }; + 6B05B00D10405F0A004A71D1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C830F7FCC1100459200 /* RecastContour.cpp */; + name = "RecastContour.cpp: 719"; + rLen = 0; + rLoc = 17870; + rType = 0; + vrLen = 1041; + vrLoc = 17592; + }; + 6B05B00F10405F0A004A71D1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */; + name = "RecastMesh.cpp: 1197"; + rLen = 150; + rLoc = 29372; + rType = 0; + vrLen = 581; + vrLoc = 28976; + }; + 6B05B01010405F0A004A71D1 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C800F7FCBFE00459200 /* RecastLog.h */; + name = "RecastLog.h: 71"; + rLen = 0; + rLoc = 2113; + rType = 0; + vrLen = 683; + vrLoc = 1527; }; 6B092B500FFCA0A20088D3A5 /* PBXTextBookmark */ = { isa = PBXTextBookmark; @@ -467,28 +641,18 @@ path = /Users/memon/Downloads/GraphicsGems/gems/Label.c; sourceTree = ""; }; - 6B092B530FFCA0A20088D3A5 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */; - name = "RecastMesh.cpp: 493"; - rLen = 0; - rLoc = 12878; - rType = 0; - vrLen = 749; - vrLoc = 12474; - }; 6B092B920FFCC2AC0088D3A5 /* DetourTileNavMeshBuilder.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 448}}"; - sepNavSelRange = "{919, 0}"; - sepNavVisRange = "{0, 1327}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 464}}"; + sepNavSelRange = "{1272, 0}"; + sepNavVisRange = "{0, 1461}"; }; }; 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 2448}}"; - sepNavSelRange = "{2965, 0}"; - sepNavVisRange = "{2558, 766}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 3344}}"; + sepNavSelRange = "{1641, 0}"; + sepNavVisRange = "{1200, 838}"; }; }; 6B092BBC0FFCEC1A0088D3A5 /* PBXTextBookmark */ = { @@ -496,21 +660,11 @@ fRef = 6B092B920FFCC2AC0088D3A5 /* DetourTileNavMeshBuilder.h */; name = "DetourTiledNavMeshBuilder.h: 1"; rLen = 0; - rLoc = 1327; + rLoc = 1461; rType = 0; vrLen = 0; vrLoc = 0; }; - 6B092CC10FFE40160088D3A5 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C830F7FCC1100459200 /* RecastContour.cpp */; - name = "RecastContour.cpp: 795"; - rLen = 13; - rLoc = 19849; - rType = 0; - vrLen = 972; - vrLoc = 18966; - }; 6B1185F41006895B0018F96F /* DetourNode.cpp */ = { uiCtxt = { sepNavIntBoundsRect = "{{0, 0}, {915, 2208}}"; @@ -527,16 +681,16 @@ }; 6B1185FC10068B040018F96F /* DetourCommon.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 2480}}"; - sepNavSelRange = "{2070, 0}"; - sepNavVisRange = "{1266, 895}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 2512}}"; + sepNavSelRange = "{4235, 5}"; + sepNavVisRange = "{3484, 1210}"; }; }; 6B1185FD10068B150018F96F /* DetourCommon.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 3296}}"; - sepNavSelRange = "{918, 0}"; - sepNavVisRange = "{0, 1254}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 3904}}"; + sepNavSelRange = "{5987, 0}"; + sepNavVisRange = "{5062, 943}"; }; }; 6B1186211006945C0018F96F /* PBXBookmark */ = { @@ -572,26 +726,16 @@ fRef = 6B1185FD10068B150018F96F /* DetourCommon.cpp */; name = "DetourCommon.cpp: 1"; rLen = 0; - rLoc = 4974; + rLoc = 6005; rType = 0; vrLen = 0; vrLoc = 0; }; - 6B1186D1100699A00018F96F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B092B920FFCC2AC0088D3A5 /* DetourTileNavMeshBuilder.h */; - name = "DetourTileNavMeshBuilder.h: 19"; - rLen = 0; - rLoc = 919; - rType = 0; - vrLen = 1327; - vrLoc = 0; - }; 6B137C6C0F7FCBBB00459200 /* imgui.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 9968}}"; - sepNavSelRange = "{3820, 0}"; - sepNavVisRange = "{3805, 589}"; + sepNavIntBoundsRect = "{{0, 0}, {1167, 9600}}"; + sepNavSelRange = "{8066, 0}"; + sepNavVisRange = "{7444, 984}"; }; }; 6B137C6D0F7FCBBB00459200 /* MeshLoaderObj.cpp */ = { @@ -611,8 +755,8 @@ 6B137C7A0F7FCBE400459200 /* imgui.h */ = { uiCtxt = { sepNavIntBoundsRect = "{{0, 0}, {915, 1568}}"; - sepNavSelRange = "{2268, 0}"; - sepNavVisRange = "{2242, 299}"; + sepNavSelRange = "{2368, 0}"; + sepNavVisRange = "{2175, 366}"; }; }; 6B137C7B0F7FCBE400459200 /* MeshLoaderObj.h */ = { @@ -624,23 +768,23 @@ }; 6B137C7E0F7FCBFE00459200 /* Recast.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 7424}}"; - sepNavSelRange = "{6708, 0}"; - sepNavVisRange = "{14949, 1369}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 7392}}"; + sepNavSelRange = "{17518, 21}"; + sepNavVisRange = "{16453, 1361}"; }; }; 6B137C7F0F7FCBFE00459200 /* RecastDebugDraw.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {992, 944}}"; - sepNavSelRange = "{2787, 0}"; - sepNavVisRange = "{1079, 1739}"; + sepNavIntBoundsRect = "{{0, 0}, {992, 960}}"; + sepNavSelRange = "{1918, 0}"; + sepNavVisRange = "{1037, 1760}"; }; }; 6B137C800F7FCBFE00459200 /* RecastLog.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 1264}}"; - sepNavSelRange = "{1953, 0}"; - sepNavVisRange = "{1626, 593}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 1296}}"; + sepNavSelRange = "{2113, 0}"; + sepNavVisRange = "{1527, 683}"; }; }; 6B137C810F7FCBFE00459200 /* RecastTimer.h */ = { @@ -653,58 +797,58 @@ }; 6B137C820F7FCC1100459200 /* Recast.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 4528}}"; - sepNavSelRange = "{1144, 0}"; - sepNavVisRange = "{516, 1042}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 4368}}"; + sepNavSelRange = "{1301, 0}"; + sepNavVisRange = "{2964, 734}"; }; }; 6B137C830F7FCC1100459200 /* RecastContour.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 13328}}"; - sepNavSelRange = "{19849, 13}"; - sepNavVisRange = "{18966, 972}"; + sepNavIntBoundsRect = "{{0, 0}, {950, 11728}}"; + sepNavSelRange = "{18633, 0}"; + sepNavVisRange = "{7955, 828}"; }; }; 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 10304}}"; - sepNavSelRange = "{13249, 19}"; - sepNavVisRange = "{13082, 875}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 12080}}"; + sepNavSelRange = "{14041, 0}"; + sepNavVisRange = "{13338, 790}"; }; }; 6B137C850F7FCC1100459200 /* RecastFilter.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {969, 4000}}"; - sepNavSelRange = "{7174, 0}"; - sepNavVisRange = "{5903, 1272}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 4000}}"; + sepNavSelRange = "{1325, 0}"; + sepNavVisRange = "{6305, 972}"; }; }; 6B137C860F7FCC1100459200 /* RecastLog.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {969, 1248}}"; - sepNavSelRange = "{1703, 0}"; - sepNavVisRange = "{1158, 668}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 1248}}"; + sepNavSelRange = "{1420, 0}"; + sepNavVisRange = "{1157, 612}"; }; }; 6B137C870F7FCC1100459200 /* RecastMesh.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 11376}}"; - sepNavSelRange = "{12878, 0}"; - sepNavVisRange = "{12474, 749}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 19408}}"; + sepNavSelRange = "{16698, 0}"; + sepNavVisRange = "{0, 1171}"; }; }; 6B137C880F7FCC1100459200 /* RecastRasterization.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 4448}}"; - sepNavSelRange = "{7129, 0}"; - sepNavVisRange = "{6948, 872}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 4400}}"; + sepNavSelRange = "{6402, 0}"; + sepNavVisRange = "{7178, 1037}"; }; }; 6B137C890F7FCC1100459200 /* RecastRegion.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {969, 17184}}"; - sepNavSelRange = "{2344, 0}"; - sepNavVisRange = "{2462, 905}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 16416}}"; + sepNavSelRange = "{25274, 0}"; + sepNavVisRange = "{22208, 920}"; }; }; 6B137C8A0F7FCC1100459200 /* RecastTimer.cpp */ = { @@ -714,32 +858,12 @@ sepNavVisRange = "{549, 468}"; }; }; - 6B1E02680F924A8500CC0038 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C820F7FCC1100459200 /* Recast.cpp */; - name = "Recast.cpp: 253"; - rLen = 0; - rLoc = 7583; - rType = 0; - vrLen = 929; - vrLoc = 6318; - }; - 6B1E02FC0F92563500CC0038 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */; - name = "DetourStatNavMeshBuilder.h: 22"; - rLen = 19; - rLoc = 995; - rType = 0; - vrLen = 1284; - vrLoc = 0; - }; 6B1E032E0F925D9100CC0038 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B137C890F7FCC1100459200 /* RecastRegion.cpp */; name = "RecastRegion.cpp: 921"; rLen = 0; - rLoc = 22732; + rLoc = 22746; rType = 0; vrLen = 918; vrLoc = 20892; @@ -756,7 +880,7 @@ fRef = 6B137C6C0F7FCBBB00459200 /* imgui.cpp */; name = "imgui.cpp: 537"; rLen = 0; - rLoc = 5690; + rLoc = 5820; rType = 0; vrLen = 508; vrLoc = 11934; @@ -793,51 +917,51 @@ }; 6B25B6100FFA62AD004F1BC4 /* Sample.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 816}}"; - sepNavSelRange = "{713, 0}"; - sepNavVisRange = "{428, 655}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 928}}"; + sepNavSelRange = "{485, 22}"; + sepNavVisRange = "{132, 607}"; }; }; 6B25B6110FFA62AD004F1BC4 /* Sample_StatMesh.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 1136}}"; - sepNavSelRange = "{211, 575}"; - sepNavVisRange = "{83, 480}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 1184}}"; + sepNavSelRange = "{599, 0}"; + sepNavVisRange = "{358, 504}"; }; }; 6B25B6120FFA62AD004F1BC4 /* Sample_StatMeshSimple.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 1088}}"; - sepNavSelRange = "{331, 14}"; - sepNavVisRange = "{0, 835}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 1152}}"; + sepNavSelRange = "{467, 7}"; + sepNavVisRange = "{301, 649}"; }; }; 6B25B6140FFA62BE004F1BC4 /* Sample.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 2144}}"; - sepNavSelRange = "{773, 0}"; - sepNavVisRange = "{436, 670}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 2096}}"; + sepNavSelRange = "{1481, 0}"; + sepNavVisRange = "{1130, 710}"; }; }; 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 5632}}"; - sepNavSelRange = "{4562, 0}"; - sepNavVisRange = "{4123, 930}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 5200}}"; + sepNavSelRange = "{4624, 0}"; + sepNavVisRange = "{4210, 893}"; }; }; 6B25B6160FFA62BE004F1BC4 /* Sample_StatMeshSimple.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1160, 8784}}"; - sepNavSelRange = "{14031, 19}"; - sepNavVisRange = "{13482, 1136}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 9584}}"; + sepNavSelRange = "{8815, 32}"; + sepNavVisRange = "{7997, 1256}"; }; }; 6B25B6180FFA62BE004F1BC4 /* main.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 11776}}"; - sepNavSelRange = "{11140, 0}"; - sepNavVisRange = "{10891, 688}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 12224}}"; + sepNavSelRange = "{989, 0}"; + sepNavVisRange = "{2242, 1061}"; }; }; 6B25B6250FFA63C8004F1BC4 /* PBXTextBookmark */ = { @@ -852,57 +976,47 @@ }; 6B2AEC510FFB8946005BE9CC /* Sample_TileMesh.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 1888}}"; - sepNavSelRange = "{2083, 0}"; - sepNavVisRange = "{1857, 557}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 1904}}"; + sepNavSelRange = "{1402, 0}"; + sepNavVisRange = "{1106, 573}"; sepNavWindowFrame = "{{15, 78}, {1011, 695}}"; }; }; 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 14096}}"; - sepNavSelRange = "{2973, 0}"; - sepNavVisRange = "{2680, 626}"; + sepNavIntBoundsRect = "{{0, 0}, {1223, 14208}}"; + sepNavSelRange = "{9597, 0}"; + sepNavVisRange = "{10515, 929}"; }; }; 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 16080}}"; - sepNavSelRange = "{26007, 0}"; - sepNavVisRange = "{25298, 1096}"; + sepNavIntBoundsRect = "{{0, 0}, {922, 15904}}"; + sepNavSelRange = "{16302, 0}"; + sepNavVisRange = "{15408, 1210}"; }; }; 6B2AEC570FFB89F4005BE9CC /* Sample_StatMeshTiled.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 1472}}"; - sepNavSelRange = "{703, 824}"; - sepNavVisRange = "{1442, 595}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 1552}}"; + sepNavSelRange = "{342, 0}"; + sepNavVisRange = "{72, 721}"; }; }; 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 4768}}"; - sepNavSelRange = "{12059, 0}"; - sepNavVisRange = "{11155, 1173}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 5232}}"; + sepNavSelRange = "{4314, 14}"; + sepNavVisRange = "{3262, 1417}"; }; }; 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 22624}}"; - sepNavSelRange = "{10230, 0}"; - sepNavVisRange = "{9496, 736}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 22704}}"; + sepNavSelRange = "{12502, 0}"; + sepNavVisRange = "{12269, 792}"; }; }; - 6B2AEC620FFB8AB0005BE9CC /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C7F0F7FCBFE00459200 /* RecastDebugDraw.h */; - name = "RecastDebugDraw.h: 56"; - rLen = 0; - rLoc = 2787; - rType = 0; - vrLen = 1739; - vrLoc = 1079; - }; 6B2AEC670FFB8AB0005BE9CC /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B137C6E0F7FCBBB00459200 /* SDLMain.m */; @@ -918,7 +1032,7 @@ fRef = 6B25B6100FFA62AD004F1BC4 /* Sample.h */; name = "Builder.h: 39"; rLen = 75; - rLoc = 713; + rLoc = 771; rType = 0; vrLen = 732; vrLoc = 337; @@ -933,35 +1047,873 @@ vrLen = 625; vrLoc = 372; }; - 6B2AEC970FFB8AB0005BE9CC /* PBXTextBookmark */ = { + 6B3314EA1042BC8200E98B50 /* PBXTextBookmark */ = { isa = PBXTextBookmark; - fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; - name = "DetourDebugDraw.cpp: 114"; - rLen = 0; - rLoc = 3372; + fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; + name = "Recast.h: 485"; + rLen = 21; + rLoc = 17518; rType = 0; - vrLen = 572; - vrLoc = 3083; + vrLen = 1361; + vrLoc = 16453; }; - 6B2AECED0FFB8B41005BE9CC /* PBXTextBookmark */ = { + 6B3314EB1042BC8200E98B50 /* PBXTextBookmark */ = { isa = PBXTextBookmark; - fRef = 6B137C800F7FCBFE00459200 /* RecastLog.h */; - name = "RecastLog.h: 64"; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 558"; rLen = 0; - rLoc = 1953; + rLoc = 14394; rType = 0; - vrLen = 593; - vrLoc = 1626; + vrLen = 758; + vrLoc = 14176; }; - 6B2AED930FFBA45B005BE9CC /* PBXTextBookmark */ = { + 6B3314EC1042BC8200E98B50 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B25B6120FFA62AD004F1BC4 /* Sample_StatMeshSimple.h */; - name = "BuilderStatMeshSimple.h: 22"; - rLen = 0; - rLoc = 451; + name = "Sample_StatMeshSimple.h: 22"; + rLen = 7; + rLoc = 467; rType = 0; - vrLen = 603; - vrLoc = 234; + vrLen = 649; + vrLoc = 301; + }; + 6B3314ED1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6160FFA62BE004F1BC4 /* Sample_StatMeshSimple.cpp */; + name = "Sample_StatMeshSimple.cpp: 297"; + rLen = 32; + rLoc = 8815; + rType = 0; + vrLen = 1256; + vrLoc = 7997; + }; + 6B3314EE1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */; + name = "DetourStatNavMeshBuilder.h: 12"; + rLen = 0; + rLoc = 639; + rType = 0; + vrLen = 1416; + vrLoc = 0; + }; + 6B3314EF1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; + name = "DetourStatNavMeshBuilder.cpp: 225"; + rLen = 0; + rLoc = 5801; + rType = 0; + vrLen = 736; + vrLoc = 5389; + }; + 6B3314F01042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 41"; + rLen = 0; + rLoc = 1641; + rType = 0; + vrLen = 838; + vrLoc = 1200; + }; + 6B3314F11042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; + name = "Sample_StatMeshTiled.cpp: 588"; + rLen = 0; + rLoc = 16302; + rType = 0; + vrLen = 1210; + vrLoc = 15408; + }; + 6B3314F21042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6140FFA62BE004F1BC4 /* Sample.cpp */; + name = "Sample.cpp: 78"; + rLen = 0; + rLoc = 1481; + rType = 0; + vrLen = 710; + vrLoc = 1130; + }; + 6B3314F31042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 598"; + rLen = 0; + rLoc = 14041; + rType = 0; + vrLen = 790; + vrLoc = 13338; + }; + 6B3314F41042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E040F91112200904EEF /* DetourDebugDraw.h */; + name = "DetourDebugDraw.h: 27"; + rLen = 0; + rLoc = 1194; + rType = 0; + vrLen = 1465; + vrLoc = 0; + }; + 6B3314F51042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; + name = "DetourTileNavMesh.h: 109"; + rLen = 14; + rLoc = 4314; + rType = 0; + vrLen = 1417; + vrLoc = 3262; + }; + 6B3314F61042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 131"; + rLen = 0; + rLoc = 4694; + rType = 0; + vrLen = 1912; + vrLoc = 3168; + }; + 6B3314F71042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; + name = "DetourStatNavMesh.cpp: 441"; + rLen = 0; + rLoc = 10567; + rType = 0; + vrLen = 453; + vrLoc = 10265; + }; + 6B3314F81042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 480"; + rLen = 0; + rLoc = 12618; + rType = 0; + vrLen = 699; + vrLoc = 11988; + }; + 6B3314F91042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6110FFA62AD004F1BC4 /* Sample_StatMesh.h */; + name = "Sample_StatMesh.h: 33"; + rLen = 0; + rLoc = 599; + rType = 0; + vrLen = 504; + vrLoc = 358; + }; + 6B3314FA1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 221"; + rLen = 0; + rLoc = 5018; + rType = 0; + vrLen = 1123; + vrLoc = 7697; + }; + 6B3314FB1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 494"; + rLen = 0; + rLoc = 12502; + rType = 0; + vrLen = 792; + vrLoc = 12269; + }; + 6B3314FC1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 613"; + rLen = 0; + rLoc = 16260; + rType = 0; + vrLen = 1424; + vrLoc = 15136; + }; + 6B3314FD1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; + name = "Recast.h: 485"; + rLen = 21; + rLoc = 17518; + rType = 0; + vrLen = 1361; + vrLoc = 16453; + }; + 6B3314FE1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 558"; + rLen = 0; + rLoc = 14394; + rType = 0; + vrLen = 758; + vrLoc = 14176; + }; + 6B3314FF1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6120FFA62AD004F1BC4 /* Sample_StatMeshSimple.h */; + name = "Sample_StatMeshSimple.h: 22"; + rLen = 7; + rLoc = 467; + rType = 0; + vrLen = 649; + vrLoc = 301; + }; + 6B3315001042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6160FFA62BE004F1BC4 /* Sample_StatMeshSimple.cpp */; + name = "Sample_StatMeshSimple.cpp: 297"; + rLen = 32; + rLoc = 8815; + rType = 0; + vrLen = 1256; + vrLoc = 7997; + }; + 6B3315011042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; + name = "Sample_StatMeshTiled.cpp: 582"; + rLen = 0; + rLoc = 15999; + rType = 0; + vrLen = 915; + vrLoc = 25772; + }; + 6B3315021042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */; + name = "DetourStatNavMeshBuilder.h: 12"; + rLen = 0; + rLoc = 639; + rType = 0; + vrLen = 1416; + vrLoc = 0; + }; + 6B3315031042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; + name = "DetourStatNavMeshBuilder.cpp: 225"; + rLen = 53; + rLoc = 5794; + rType = 0; + vrLen = 892; + vrLoc = 5248; + }; + 6B3315041042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 370"; + rLen = 0; + rLoc = 10145; + rType = 0; + vrLen = 1102; + vrLoc = 9226; + }; + 6B3315051042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 132"; + rLen = 8; + rLoc = 4182; + rType = 0; + vrLen = 1070; + vrLoc = 3417; + }; + 6B3315061042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 204"; + rLen = 0; + rLoc = 8285; + rType = 0; + vrLen = 1624; + vrLoc = 7011; + }; + 6B3315071042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; + name = "DetourStatNavMesh.cpp: 59"; + rLen = 8; + rLoc = 1946; + rType = 0; + vrLen = 1158; + vrLoc = 1367; + }; + 6B3315081042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 360"; + rLen = 0; + rLoc = 9691; + rType = 0; + vrLen = 1115; + vrLoc = 9473; + }; + 6B3315091042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; + name = "DetourStatNavMeshBuilder.cpp: 225"; + rLen = 0; + rLoc = 5801; + rType = 0; + vrLen = 736; + vrLoc = 5389; + }; + 6B33150A1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; + name = "Sample_StatMeshTiled.cpp: 800"; + rLen = 0; + rLoc = 23217; + rType = 0; + vrLen = 765; + vrLoc = 22602; + }; + 6B33150B1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 41"; + rLen = 0; + rLoc = 1641; + rType = 0; + vrLen = 838; + vrLoc = 1200; + }; + 6B33150C1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 366"; + rLen = 0; + rLoc = 9926; + rType = 0; + vrLen = 1043; + vrLoc = 9473; + }; + 6B33150D1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 613"; + rLen = 0; + rLoc = 16260; + rType = 0; + vrLen = 1266; + vrLoc = 15211; + }; + 6B33150E1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; + name = "Sample_StatMeshTiled.cpp: 588"; + rLen = 0; + rLoc = 16302; + rType = 0; + vrLen = 1210; + vrLoc = 15408; + }; + 6B33150F1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6140FFA62BE004F1BC4 /* Sample.cpp */; + name = "Sample.cpp: 78"; + rLen = 0; + rLoc = 1481; + rType = 0; + vrLen = 710; + vrLoc = 1130; + }; + 6B3315101042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 697"; + rLen = 0; + rLoc = 16295; + rType = 0; + vrLen = 1465; + vrLoc = 0; + }; + 6B3315111042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 598"; + rLen = 0; + rLoc = 14041; + rType = 0; + vrLen = 790; + vrLoc = 13338; + }; + 6B3315121042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E040F91112200904EEF /* DetourDebugDraw.h */; + name = "DetourDebugDraw.h: 27"; + rLen = 0; + rLoc = 1194; + rType = 0; + vrLen = 1465; + vrLoc = 0; + }; + 6B3315131042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 481"; + rLen = 0; + rLoc = 12646; + rType = 0; + vrLen = 964; + vrLoc = 11948; + }; + 6B3315141042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 131"; + rLen = 0; + rLoc = 4694; + rType = 0; + vrLen = 1912; + vrLoc = 3168; + }; + 6B3315151042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; + name = "DetourStatNavMesh.cpp: 441"; + rLen = 0; + rLoc = 10567; + rType = 0; + vrLen = 453; + vrLoc = 10265; + }; + 6B3315161042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 480"; + rLen = 0; + rLoc = 12618; + rType = 0; + vrLen = 699; + vrLoc = 11988; + }; + 6B3315171042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 122"; + rLen = 0; + rLoc = 2330; + rType = 0; + vrLen = 777; + vrLoc = 2031; + }; + 6B3315181042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6110FFA62AD004F1BC4 /* Sample_StatMesh.h */; + name = "Sample_StatMesh.h: 36"; + rLen = 0; + rLoc = 645; + rType = 0; + vrLen = 553; + vrLoc = 358; + }; + 6B3315191042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 162"; + rLen = 0; + rLoc = 2330; + rType = 0; + vrLen = 669; + vrLoc = 3189; + }; + 6B33151A1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6110FFA62AD004F1BC4 /* Sample_StatMesh.h */; + name = "Sample_StatMesh.h: 33"; + rLen = 0; + rLoc = 599; + rType = 0; + vrLen = 504; + vrLoc = 358; + }; + 6B33151B1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 221"; + rLen = 0; + rLoc = 5018; + rType = 0; + vrLen = 1123; + vrLoc = 7697; + }; + 6B33151C1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 494"; + rLen = 0; + rLoc = 12502; + rType = 0; + vrLen = 792; + vrLoc = 12269; + }; + 6B33151D1042BC8200E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 421"; + rLen = 0; + rLoc = 11145; + rType = 0; + vrLen = 1031; + vrLoc = 10646; + }; + 6B3315291042BCC100E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 328"; + rLen = 0; + rLoc = 8322; + rType = 0; + vrLen = 1188; + vrLoc = 7358; + }; + 6B33152B1042BCEF00E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 320"; + rLen = 0; + rLoc = 7923; + rType = 0; + vrLen = 1188; + vrLoc = 7358; + }; + 6B33152E1042BD3500E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 373"; + rLen = 0; + rLoc = 9597; + rType = 0; + vrLen = 929; + vrLoc = 10515; + }; + 6B33152F1042BD3500E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 221"; + rLen = 0; + rLoc = 5018; + rType = 0; + vrLen = 1123; + vrLoc = 7697; + }; + 6B3315301042BD3500E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 373"; + rLen = 0; + rLoc = 9597; + rType = 0; + vrLen = 929; + vrLoc = 10515; + }; + 6B3315311042BD3500E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 222"; + rLen = 0; + rLoc = 5040; + rType = 0; + vrLen = 842; + vrLoc = 4210; + }; + 6B3315321042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 206"; + rLen = 0; + rLoc = 4624; + rType = 0; + vrLen = 893; + vrLoc = 4210; + }; + 6B3315331042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C820F7FCC1100459200 /* Recast.cpp */; + name = "Recast.cpp: 37"; + rLen = 0; + rLoc = 1301; + rType = 0; + vrLen = 734; + vrLoc = 2964; + }; + 6B3315341042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C830F7FCC1100459200 /* RecastContour.cpp */; + name = "RecastContour.cpp: 738"; + rLen = 0; + rLoc = 18633; + rType = 0; + vrLen = 828; + vrLoc = 7955; + }; + 6B3315351042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C850F7FCC1100459200 /* RecastFilter.cpp */; + name = "RecastFilter.cpp: 37"; + rLen = 0; + rLoc = 1325; + rType = 0; + vrLen = 972; + vrLoc = 6305; + }; + 6B3315361042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C860F7FCC1100459200 /* RecastLog.cpp */; + name = "RecastLog.cpp: 47"; + rLen = 0; + rLoc = 1420; + rType = 0; + vrLen = 612; + vrLoc = 1157; + }; + 6B3315371042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */; + name = "RecastMesh.cpp: 676"; + rLen = 0; + rLoc = 16698; + rType = 0; + vrLen = 1171; + vrLoc = 0; + }; + 6B3315381042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C880F7FCC1100459200 /* RecastRasterization.cpp */; + name = "RecastRasterization.cpp: 250"; + rLen = 0; + rLoc = 6402; + rType = 0; + vrLen = 1037; + vrLoc = 7178; + }; + 6B3315391042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C890F7FCC1100459200 /* RecastRegion.cpp */; + name = "RecastRegion.cpp: 1058"; + rLen = 0; + rLoc = 25274; + rType = 0; + vrLen = 920; + vrLoc = 22208; + }; + 6B33153A1042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 558"; + rLen = 0; + rLoc = 14394; + rType = 0; + vrLen = 758; + vrLoc = 14176; + }; + 6B33153B1042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 206"; + rLen = 0; + rLoc = 4624; + rType = 0; + vrLen = 893; + vrLoc = 4210; + }; + 6B33153C1042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C820F7FCC1100459200 /* Recast.cpp */; + name = "Recast.cpp: 37"; + rLen = 0; + rLoc = 1301; + rType = 0; + vrLen = 734; + vrLoc = 2964; + }; + 6B33153D1042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C830F7FCC1100459200 /* RecastContour.cpp */; + name = "RecastContour.cpp: 738"; + rLen = 0; + rLoc = 18633; + rType = 0; + vrLen = 828; + vrLoc = 7955; + }; + 6B33153E1042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C850F7FCC1100459200 /* RecastFilter.cpp */; + name = "RecastFilter.cpp: 37"; + rLen = 0; + rLoc = 1325; + rType = 0; + vrLen = 972; + vrLoc = 6305; + }; + 6B33153F1042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C860F7FCC1100459200 /* RecastLog.cpp */; + name = "RecastLog.cpp: 47"; + rLen = 0; + rLoc = 1420; + rType = 0; + vrLen = 612; + vrLoc = 1157; + }; + 6B3315401042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C870F7FCC1100459200 /* RecastMesh.cpp */; + name = "RecastMesh.cpp: 676"; + rLen = 0; + rLoc = 16698; + rType = 0; + vrLen = 1171; + vrLoc = 0; + }; + 6B3315411042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C880F7FCC1100459200 /* RecastRasterization.cpp */; + name = "RecastRasterization.cpp: 250"; + rLen = 0; + rLoc = 6402; + rType = 0; + vrLen = 1037; + vrLoc = 7178; + }; + 6B3315421042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C890F7FCC1100459200 /* RecastRegion.cpp */; + name = "RecastRegion.cpp: 1058"; + rLen = 0; + rLoc = 25274; + rType = 0; + vrLen = 920; + vrLoc = 22208; + }; + 6B3315431042BE1600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 39"; + rLen = 12; + rLoc = 1287; + rType = 0; + vrLen = 907; + vrLoc = 1171; + }; + 6B3315441042BE4600E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 138"; + rLen = 24; + rLoc = 3865; + rType = 0; + vrLen = 837; + vrLoc = 3344; + }; + 6B3315451042BED800E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 111"; + rLen = 0; + rLoc = 3009; + rType = 0; + vrLen = 948; + vrLoc = 2681; + }; + 6B3315481042C02C00E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + comments = "error: crosses initialization of 'int maxhh'"; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + rLen = 0; + rLoc = 703; + rType = 1; + }; + 6B3315491042C02C00E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 691"; + rLen = 0; + rLoc = 17717; + rType = 0; + vrLen = 697; + vrLoc = 17444; + }; + 6B33154A1042C0A500E98B50 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 548"; + rLen = 0; + rLoc = 14244; + rType = 0; + vrLen = 842; + vrLoc = 13234; + }; + 6B41875F10397C9F00FBF4A5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 131"; + rLen = 0; + rLoc = 4694; + rType = 0; + vrLen = 1598; + vrLoc = 3224; + }; + 6B41876A1039827000FBF4A5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6180FFA62BE004F1BC4 /* main.cpp */; + name = "main.cpp: 54"; + rLen = 0; + rLoc = 989; + rType = 0; + vrLen = 1061; + vrLoc = 2242; + }; + 6B41878E1039854600FBF4A5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B1185FD10068B150018F96F /* DetourCommon.cpp */; + name = "DetourCommon.cpp: 242"; + rLen = 0; + rLoc = 5987; + rType = 0; + vrLen = 943; + vrLoc = 5062; + }; + 6B4187B11039909100FBF4A5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6120FFA62AD004F1BC4 /* Sample_StatMeshSimple.h */; + name = "Sample_StatMeshSimple.h: 41"; + rLen = 24; + rLoc = 862; + rType = 0; + vrLen = 649; + vrLoc = 301; + }; + 6B4187C41039909100FBF4A5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 660"; + rLen = 69; + rLoc = 16191; + rType = 0; + vrLen = 789; + vrLoc = 15711; + }; + 6B418869103ACAC700FBF4A5 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC570FFB89F4005BE9CC /* Sample_StatMeshTiled.h */; + name = "Sample_StatMeshTiled.h: 17"; + rLen = 0; + rLoc = 367; + rType = 0; + vrLen = 792; + vrLoc = 0; }; 6B458EA80FB4540500044EA9 /* PBXTextBookmark */ = { isa = PBXTextBookmark; @@ -973,16 +1925,6 @@ vrLen = 1182; vrLoc = 0; }; - 6B555D24100B136A00247EA3 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C880F7FCC1100459200 /* RecastRasterization.cpp */; - name = "RecastRasterization.cpp: 274"; - rLen = 0; - rLoc = 7129; - rType = 0; - vrLen = 872; - vrLoc = 6948; - }; 6B555D26100B136A00247EA3 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B137C880F7FCC1100459200 /* RecastRasterization.cpp */; @@ -1061,36 +2003,6 @@ vrLen = 681; vrLoc = 915; }; - 6B555E5F100B334900247EA3 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6100FFA62AD004F1BC4 /* Sample.h */; - name = "Sample.h: 39"; - rLen = 0; - rLoc = 713; - rType = 0; - vrLen = 655; - vrLoc = 428; - }; - 6B555E60100B334900247EA3 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6140FFA62BE004F1BC4 /* Sample.cpp */; - name = "Sample.cpp: 47"; - rLen = 0; - rLoc = 773; - rType = 0; - vrLen = 670; - vrLoc = 436; - }; - 6B555EA1100B37AB00247EA3 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C7A0F7FCBE400459200 /* imgui.h */; - name = "imgui.h: 76"; - rLen = 0; - rLoc = 2268; - rType = 0; - vrLen = 299; - vrLoc = 2242; - }; 6B555EE0100B39A600247EA3 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B25B6180FFA62BE004F1BC4 /* main.cpp */; @@ -1111,16 +2023,6 @@ vrLen = 572; vrLoc = 5401; }; - 6B555F0C100B473F00247EA3 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6180FFA62BE004F1BC4 /* main.cpp */; - name = "main.cpp: 493"; - rLen = 0; - rLoc = 11140; - rType = 0; - vrLen = 688; - vrLoc = 10891; - }; 6B555F0D100B473F00247EA3 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B555DAE100B211D00247EA3 /* imguiRenderGL.h */; @@ -1141,35 +2043,76 @@ vrLen = 1274; vrLoc = 0; }; - 6B555F0F100B473F00247EA3 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B1185FD10068B150018F96F /* DetourCommon.cpp */; - name = "DetourCommon.cpp: 18"; - rLen = 0; - rLoc = 918; - rType = 0; - vrLen = 1254; - vrLoc = 0; + 6B624169103434880002E346 /* RecastMeshDetail.cpp */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {915, 15520}}"; + sepNavSelRange = "{14244, 0}"; + sepNavVisRange = "{13234, 842}"; + }; }; - 6B555FB4100B595C00247EA3 /* PBXTextBookmark */ = { + 6B6241E91034B2FA0002E346 /* PBXTextBookmark */ = { isa = PBXTextBookmark; - fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; - name = "Sample_TileMesh.cpp: 207"; + fRef = 6B6241EA1034B2FA0002E346 /* macros.h */; + name = "macros.h: 21"; rLen = 0; - rLoc = 5467; + rLoc = 542; rType = 0; - vrLen = 621; - vrLoc = 4992; + vrLen = 721; + vrLoc = 226; }; - 6B58CAE510198B2400956BA2 /* PBXTextBookmark */ = { + 6B6241EA1034B2FA0002E346 /* macros.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = macros.h; + path = /Users/memon/Downloads/Ccode2/dt/macros.h; + sourceTree = ""; + }; + 6B6241EB1034B2FA0002E346 /* PBXTextBookmark */ = { isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 277"; + fRef = 6B6241EC1034B2FA0002E346 /* dt4.c */; + name = "dt4.c: 22"; rLen = 0; - rLoc = 12059; + rLoc = 621; rType = 0; - vrLen = 1173; - vrLoc = 11155; + vrLen = 838; + vrLoc = 457; + }; + 6B6241EC1034B2FA0002E346 /* dt4.c */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.c; + name = dt4.c; + path = /Users/memon/Downloads/Ccode2/dt/dt4.c; + sourceTree = ""; + }; + 6B74D043103DD3B600623975 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C890F7FCC1100459200 /* RecastRegion.cpp */; + name = "RecastRegion.cpp: 1063"; + rLen = 0; + rLoc = 25569; + rType = 0; + vrLen = 1252; + vrLoc = 25037; + }; + 6B74D052103DD64C00623975 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C830F7FCC1100459200 /* RecastContour.cpp */; + name = "RecastContour.cpp: 87"; + rLen = 0; + rLoc = 3216; + rType = 0; + vrLen = 926; + vrLoc = 2328; + }; + 6B74D091103DDCC300623975 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC570FFB89F4005BE9CC /* Sample_StatMeshTiled.h */; + name = "Sample_StatMeshTiled.h: 16"; + rLen = 0; + rLoc = 342; + rType = 0; + vrLen = 721; + vrLoc = 72; }; 6B7707B90FBD66CF00D21BAE /* PBXTextBookmark */ = { isa = PBXTextBookmark; @@ -1298,16 +2241,6 @@ path = /Library/Frameworks/SDL.framework/Versions/A/Headers/SDL_events.h; sourceTree = ""; }; - 6B8AE8DA10121C6000FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B1185FC10068B040018F96F /* DetourCommon.h */; - name = "DetourCommon.h: 56"; - rLen = 0; - rLoc = 2070; - rType = 0; - vrLen = 895; - vrLoc = 1266; - }; 6B8AE8DF10121C6000FF1D07 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B1185FC10068B040018F96F /* DetourCommon.h */; @@ -1328,166 +2261,6 @@ vrLen = 482; vrLoc = 2496; }; - 6B8AE8FB10123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E040F91112200904EEF /* DetourDebugDraw.h */; - name = "DetourDebugDraw.h: 27"; - rLen = 0; - rLoc = 1194; - rType = 0; - vrLen = 1465; - vrLoc = 0; - }; - 6B8AE8FC10123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; - name = "DetourDebugDraw.cpp: 106"; - rLen = 22; - rLoc = 3107; - rType = 0; - vrLen = 619; - vrLoc = 2960; - }; - 6B8AE8FE10123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; - name = "Sample_StatMesh.cpp: 203"; - rLen = 0; - rLoc = 4562; - rType = 0; - vrLen = 930; - vrLoc = 4123; - }; - 6B8AE90010123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; - name = "DetourStatNavMesh.h: 180"; - rLen = 0; - rLoc = 7274; - rType = 0; - vrLen = 1576; - vrLoc = 6460; - }; - 6B8AE90210123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C820F7FCC1100459200 /* Recast.cpp */; - name = "Recast.cpp: 32"; - rLen = 0; - rLoc = 1144; - rType = 0; - vrLen = 1042; - vrLoc = 516; - }; - 6B8AE90310123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; - name = "Recast.h: 180"; - rLen = 0; - rLoc = 6708; - rType = 0; - vrLen = 1369; - vrLoc = 14949; - }; - 6B8AE90410123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6120FFA62AD004F1BC4 /* Sample_StatMeshSimple.h */; - name = "Sample_StatMeshSimple.h: 17"; - rLen = 14; - rLoc = 331; - rType = 0; - vrLen = 835; - vrLoc = 0; - }; - 6B8AE90510123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; - name = "Sample_StatMeshTiled.cpp: 901"; - rLen = 0; - rLoc = 26007; - rType = 0; - vrLen = 1096; - vrLoc = 25298; - }; - 6B8AE90610123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; - name = "RecastDebugDraw.cpp: 554"; - rLen = 19; - rLoc = 13249; - rType = 0; - vrLen = 875; - vrLoc = 13082; - }; - 6B8AE90710123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6160FFA62BE004F1BC4 /* Sample_StatMeshSimple.cpp */; - name = "Sample_StatMeshSimple.cpp: 464"; - rLen = 19; - rLoc = 14031; - rType = 0; - vrLen = 1136; - vrLoc = 13482; - }; - 6B8AE90D10123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; - name = "Sample_StatMesh.cpp: 203"; - rLen = 0; - rLoc = 4562; - rType = 0; - vrLen = 930; - vrLoc = 4123; - }; - 6B8AE90E10123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 1144"; - rLen = 276; - rLoc = 29135; - rType = 0; - vrLen = 1141; - vrLoc = 28145; - }; - 6B8AE90F10123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; - name = "DetourStatNavMesh.h: 180"; - rLen = 0; - rLoc = 7274; - rType = 0; - vrLen = 1576; - vrLoc = 6460; - }; - 6B8AE91010123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; - name = "DetourStatNavMesh.cpp: 659"; - rLen = 0; - rLoc = 15988; - rType = 0; - vrLen = 1140; - vrLoc = 15138; - }; - 6B8AE91810123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; - name = "DetourStatNavMeshBuilder.cpp: 212"; - rLen = 0; - rLoc = 5492; - rType = 0; - vrLen = 1263; - vrLoc = 5247; - }; - 6B8AE91910123B5700FF1D07 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6160FFA62BE004F1BC4 /* Sample_StatMeshSimple.cpp */; - name = "Sample_StatMeshSimple.cpp: 464"; - rLen = 19; - rLoc = 14031; - rType = 0; - vrLen = 1136; - vrLoc = 13482; - }; 6B8DB3900F9798DE007FA9E1 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6BDD9E040F91112200904EEF /* DetourDebugDraw.h */; @@ -1498,16 +2271,6 @@ vrLen = 1243; vrLoc = 0; }; - 6B92CE68100E0577003DA304 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C6C0F7FCBBB00459200 /* imgui.cpp */; - name = "imgui.cpp: 130"; - rLen = 0; - rLoc = 3820; - rType = 0; - vrLen = 589; - vrLoc = 3805; - }; 6B92CE69100E0577003DA304 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B137C7B0F7FCBE400459200 /* MeshLoaderObj.h */; @@ -1528,36 +2291,6 @@ vrLen = 424; vrLoc = 915; }; - 6B92CE6F100E0577003DA304 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC510FFB8946005BE9CC /* Sample_TileMesh.h */; - name = "Sample_TileMesh.h: 78"; - rLen = 0; - rLoc = 2083; - rType = 0; - vrLen = 557; - vrLoc = 1857; - }; - 6B92CE70100E0577003DA304 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC570FFB89F4005BE9CC /* Sample_StatMeshTiled.h */; - name = "Sample_StatMeshTiled.h: 34"; - rLen = 824; - rLoc = 703; - rType = 0; - vrLen = 595; - vrLoc = 1442; - }; - 6B92CE72100E0577003DA304 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B25B6110FFA62AD004F1BC4 /* Sample_StatMesh.h */; - name = "Sample_StatMesh.h: 13"; - rLen = 575; - rLoc = 211; - rType = 0; - vrLen = 480; - vrLoc = 83; - }; 6B92CE8A100E0739003DA304 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B137C810F7FCBFE00459200 /* RecastTimer.h */; @@ -1568,15 +2301,257 @@ vrLen = 984; vrLoc = 202; }; - 6B995BDF0FE0D9B300D5C493 /* PBXTextBookmark */ = { + 6B9301521032F08300F0C0DA /* Recast.cpp:273 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 6B137C820F7FCC1100459200 /* Recast.cpp */; + functionName = "buildPolySurface(const float* in, const int nin, const float tol, const rcCompactHeightfield& chf, rcPolySubdiv& psub)"; + hitCount = 0; + ignoreCount = 0; + lineNumber = 273; + location = Recast; + modificationTime = 272654272.923319; + state = 1; + }; + 6B93FDBB102FFCFE00F0C0DA /* PBXTextBookmark */ = { isa = PBXTextBookmark; - fRef = 6B137C890F7FCC1100459200 /* RecastRegion.cpp */; - name = "RecastRegion.cpp: 78"; + fRef = 6B137C6C0F7FCBBB00459200 /* imgui.cpp */; + name = "imgui.cpp: 332"; rLen = 0; + rLoc = 8066; + rType = 0; + vrLen = 984; + vrLoc = 7444; + }; + 6B93FDEB10300CBE00F0C0DA /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6120FFA62AD004F1BC4 /* Sample_StatMeshSimple.h */; + name = "Sample_StatMeshSimple.h: 24"; + rLen = 0; + rLoc = 465; + rType = 0; + vrLen = 670; + vrLoc = 155; + }; + 6B93FDF010300CBE00F0C0DA /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7F0F7FCBFE00459200 /* RecastDebugDraw.h */; + name = "RecastDebugDraw.h: 54"; + rLen = 1; rLoc = 2344; rType = 0; - vrLen = 905; - vrLoc = 2462; + vrLen = 1599; + vrLoc = 1289; + }; + 6B93FE7C1030279700F0C0DA /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E040F91112200904EEF /* DetourDebugDraw.h */; + name = "DetourDebugDraw.h: 27"; + rLen = 0; + rLoc = 1194; + rType = 0; + vrLen = 1438; + vrLoc = 0; + }; + 6B93FEFF1030443300F0C0DA /* Recast.cpp:273 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 6B137C820F7FCC1100459200 /* Recast.cpp */; + functionName = "removeVertex(unsigned short v, float* verts, int& nv, unsigned short* tris, int& nt)"; + hitCount = 0; + ignoreCount = 0; + lineNumber = 273; + location = Recast; + modificationTime = 272654272.923061; + state = 2; + }; + 6B95064210383C6900213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C860F7FCC1100459200 /* RecastLog.cpp */; + name = "RecastLog.cpp: 47"; + rLen = 0; + rLoc = 1420; + rType = 0; + vrLen = 591; + vrLoc = 1158; + }; + 6B95064C10383C6900213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6160FFA62BE004F1BC4 /* Sample_StatMeshSimple.cpp */; + name = "Sample_StatMeshSimple.cpp: 296"; + rLen = 0; + rLoc = 566; + rType = 0; + vrLen = 1375; + vrLoc = 8423; + }; + 6B95065010383C6900213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C800F7FCBFE00459200 /* RecastLog.h */; + name = "RecastLog.h: 70"; + rLen = 15; + rLoc = 2052; + rType = 0; + vrLen = 690; + vrLoc = 1527; + }; + 6B9506851038680900213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C820F7FCC1100459200 /* Recast.cpp */; + name = "Recast.cpp: 42"; + rLen = 0; + rLoc = 1380; + rType = 0; + vrLen = 631; + vrLoc = 1084; + }; + 6B9506891038680900213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C820F7FCC1100459200 /* Recast.cpp */; + name = "Recast.cpp: 42"; + rLen = 0; + rLoc = 1380; + rType = 0; + vrLen = 631; + vrLoc = 1084; + }; + 6B95069A103869D900213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6100FFA62AD004F1BC4 /* Sample.h */; + name = "Sample.h: 27"; + rLen = 22; + rLoc = 485; + rType = 0; + vrLen = 607; + vrLoc = 132; + }; + 6B95069B103869D900213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6140FFA62BE004F1BC4 /* Sample.cpp */; + name = "Sample.cpp: 114"; + rLen = 0; + rLoc = 2694; + rType = 0; + vrLen = 1001; + vrLoc = 1840; + }; + 6B9506F810388A4200213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B1185FC10068B040018F96F /* DetourCommon.h */; + name = "DetourCommon.h: 156"; + rLen = 5; + rLoc = 4235; + rType = 0; + vrLen = 1210; + vrLoc = 3484; + }; + 6B95070510388A4200213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 29"; + rLen = 0; + rLoc = 1185; + rType = 0; + vrLen = 644; + vrLoc = 915; + }; + 6B9507401038910D00213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6150FFA62BE004F1BC4 /* Sample_StatMesh.cpp */; + name = "Sample_StatMesh.cpp: 144"; + rLen = 0; + rLoc = 2330; + rType = 0; + vrLen = 994; + vrLoc = 2526; + }; + 6B950746103891A700213080 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6110FFA62AD004F1BC4 /* Sample_StatMesh.h */; + name = "Sample_StatMesh.h: 34"; + rLen = 0; + rLoc = 599; + rType = 0; + vrLen = 672; + vrLoc = 240; + }; + 6B955A0610359EBB00FE9FE3 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B955A0710359EBB00FE9FE3 /* DelaunayPoint.as */; + name = "DelaunayPoint.as: 5"; + rLen = 0; + rLoc = 60; + rType = 0; + vrLen = 425; + vrLoc = 0; + }; + 6B955A0710359EBB00FE9FE3 /* DelaunayPoint.as */ = { + isa = PBXFileReference; + lastKnownFileType = text; + name = DelaunayPoint.as; + path = /Users/memon/Downloads/net/nicoptere/delaunay/DelaunayPoint.as; + sourceTree = ""; + }; + 6B955A0810359EBB00FE9FE3 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B955A0910359EBB00FE9FE3 /* DelaunayEdge.as */; + name = "DelaunayEdge.as: 12"; + rLen = 0; + rLoc = 416; + rType = 0; + vrLen = 793; + vrLoc = 0; + }; + 6B955A0910359EBB00FE9FE3 /* DelaunayEdge.as */ = { + isa = PBXFileReference; + lastKnownFileType = text; + name = DelaunayEdge.as; + path = /Users/memon/Downloads/net/nicoptere/delaunay/DelaunayEdge.as; + sourceTree = ""; + }; + 6B955A0A10359EBB00FE9FE3 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B955A0B10359EBB00FE9FE3 /* DelaunayTriangle.as */; + name = "DelaunayTriangle.as: 72"; + rLen = 0; + rLoc = 1867; + rType = 0; + vrLen = 731; + vrLoc = 1307; + }; + 6B955A0B10359EBB00FE9FE3 /* DelaunayTriangle.as */ = { + isa = PBXFileReference; + lastKnownFileType = text; + name = DelaunayTriangle.as; + path = /Users/memon/Downloads/net/nicoptere/delaunay/DelaunayTriangle.as; + sourceTree = ""; + }; + 6B955A0C10359EBB00FE9FE3 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B955A0D10359EBB00FE9FE3 /* Delaunay.as */; + name = "Delaunay.as: 305"; + rLen = 0; + rLoc = 7416; + rType = 0; + vrLen = 368; + vrLoc = 7092; + }; + 6B955A0D10359EBB00FE9FE3 /* Delaunay.as */ = { + isa = PBXFileReference; + lastKnownFileType = text; + name = Delaunay.as; + path = /Users/memon/Downloads/net/nicoptere/delaunay/Delaunay.as; + sourceTree = ""; }; 6B995F9F100F336B00D7BF5A /* PBXTextBookmark */ = { isa = PBXTextBookmark; @@ -1615,16 +2590,6 @@ vrLen = 564; vrLoc = 2323; }; - 6B996059100F42AF00D7BF5A /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; - name = "Sample_TileMesh.cpp: 120"; - rLen = 0; - rLoc = 2973; - rType = 0; - vrLen = 626; - vrLoc = 2680; - }; 6B9B7D9D0FF91AC600A9090F /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6BB788180FC04753003C24DB /* ChunkyTriMesh.h */; @@ -1635,35 +2600,76 @@ vrLen = 835; vrLoc = 837; }; - 6B9B7DA30FF91AC600A9090F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C830F7FCC1100459200 /* RecastContour.cpp */; - name = "RecastContour.cpp: 830"; - rLen = 0; - rLoc = 20761; - rType = 0; - vrLen = 795; - vrLoc = 20354; + 6B9D0891102715D5009B1A6C /* RecastTexture.cpp */ = { + isa = PBXFileReference; + fileEncoding = 4; + lastKnownFileType = sourcecode.cpp.cpp; + name = RecastTexture.cpp; + path = /Users/memon/Code/recastnavigation/Recast/Source/RecastTexture.cpp; + sourceTree = ""; }; - 6B9B7DA40FF91AC600A9090F /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; - name = "Recast.h: 235"; - rLen = 0; - rLoc = 8967; - rType = 0; - vrLen = 639; - vrLoc = 5887; + 6B9D0932102722F0009B1A6C /* RecastTexture.cpp:301 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 6B9D0891102715D5009B1A6C /* RecastTexture.cpp */; + functionName = "floodfillTexture(int x, int y, int i, const int dstw, const int dsth, unsigned short* dst0, unsigned short* dst1, const rcTextureRegion& treg, const rcCompactHeightfield& chf, rcIntArray& stack)"; + hitCount = 0; + ignoreCount = 0; + lineNumber = 301; + modificationTime = 272654427.491914; + state = 1; }; - 6BB787C30FC03EAD003C24DB /* PBXTextBookmark */ = { + 6B9D09921028542A009B1A6C /* RecastDebugDraw.cpp:693 */ = { + isa = PBXFileBreakpoint; + actions = ( + ); + breakpointStyle = 0; + continueAfterActions = 0; + countType = 0; + delayBeforeContinue = 0; + fileReference = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + functionName = "rcDebugDrawTextureSet(const rcTextureSet& tset)"; + hitCount = 0; + ignoreCount = 0; + lineNumber = 693; + location = Recast; + modificationTime = 272654272.92286; + state = 2; + }; + 6B9D09E210285EFE009B1A6C /* PBXTextBookmark */ = { isa = PBXTextBookmark; - fRef = 6B137C800F7FCBFE00459200 /* RecastLog.h */; - name = "RecastLog.h: 68"; + fRef = 6B137C880F7FCC1100459200 /* RecastRasterization.cpp */; + name = "RecastRasterization.cpp: 257"; rLen = 0; - rLoc = 2066; + rLoc = 6598; rType = 0; - vrLen = 524; - vrLoc = 1649; + vrLen = 973; + vrLoc = 6154; + }; + 6B9D0AD010298E12009B1A6C /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C850F7FCC1100459200 /* RecastFilter.cpp */; + name = "RecastFilter.cpp: 45"; + rLen = 5; + rLoc = 1499; + rType = 0; + vrLen = 864; + vrLoc = 1133; + }; + 6B9D0AF4102991F0009B1A6C /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7A0F7FCBE400459200 /* imgui.h */; + name = "imgui.h: 84"; + rLen = 0; + rLoc = 2368; + rType = 0; + vrLen = 366; + vrLoc = 2175; }; 6BB788160FC0472B003C24DB /* ChunkyTriMesh.cpp */ = { uiCtxt = { @@ -1726,56 +2732,6 @@ path = /Library/Frameworks/SDL.framework/Versions/A/Headers/SDL_video.h; sourceTree = ""; }; - 6BC620920FD7C2380022CACF /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C7F0F7FCBFE00459200 /* RecastDebugDraw.h */; - name = "RecastDebugDraw.h: 51"; - rLen = 22; - rLoc = 2089; - rType = 0; - vrLen = 1638; - vrLoc = 1036; - }; - 6BC745A70FF527E50083A694 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C860F7FCC1100459200 /* RecastLog.cpp */; - name = "RecastLog.cpp: 68"; - rLen = 0; - rLoc = 1703; - rType = 0; - vrLen = 668; - vrLoc = 1158; - }; - 6BC745A80FF527E50083A694 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C850F7FCC1100459200 /* RecastFilter.cpp */; - name = "RecastFilter.cpp: 245"; - rLen = 0; - rLoc = 7174; - rType = 0; - vrLen = 1272; - vrLoc = 5903; - }; - 6BC745AD0FF527E50083A694 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; - name = "RecastDebugDraw.cpp: 406"; - rLen = 0; - rLoc = 9915; - rType = 0; - vrLen = 952; - vrLoc = 9881; - }; - 6BC745AE0FF527E50083A694 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B137C860F7FCC1100459200 /* RecastLog.cpp */; - name = "RecastLog.cpp: 68"; - rLen = 0; - rLoc = 1703; - rType = 0; - vrLen = 668; - vrLoc = 1158; - }; 6BC745AF0FF527E50083A694 /* PBXTextBookmark */ = { isa = PBXTextBookmark; fRef = 6B137C850F7FCC1100459200 /* RecastFilter.cpp */; @@ -1786,309 +2742,909 @@ vrLen = 1272; vrLoc = 5903; }; - 6BD4DBB910145A50003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; - name = "DetourStatNavMeshBuilder.cpp: 213"; - rLen = 0; - rLoc = 5505; - rType = 0; - vrLen = 1262; - vrLoc = 5247; - }; - 6BD4DBBA10145A50003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; - name = "DetourStatNavMesh.cpp: 798"; - rLen = 300; - rLoc = 19735; - rType = 0; - vrLen = 1013; - vrLoc = 19289; - }; - 6BD4DBBD10145A50003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; - name = "DetourStatNavMeshBuilder.cpp: 213"; - rLen = 0; - rLoc = 5505; - rType = 0; - vrLen = 1262; - vrLoc = 5247; - }; - 6BD4DBBE10145A50003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; - name = "DetourStatNavMesh.cpp: 798"; - rLen = 300; - rLoc = 19735; - rType = 0; - vrLen = 1013; - vrLoc = 19289; - }; - 6BD4DBBF10145A50003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 935"; - rLen = 0; - rLoc = 23148; - rType = 0; - vrLen = 1466; - vrLoc = 22303; - }; - 6BD4DBC710145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; - name = "DetourTileNavMeshBuilder.cpp: 89"; - rLen = 0; - rLoc = 2965; - rType = 0; - vrLen = 704; - vrLoc = 2558; - }; - 6BD4DBC810145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 378"; - rLen = 0; - rLoc = 10230; - rType = 0; - vrLen = 736; - vrLoc = 9496; - }; - 6BD4DBC910145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 85"; - rLen = 0; - rLoc = 3685; - rType = 0; - vrLen = 1146; - vrLoc = 2736; - }; - 6BD4DBCA10145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 1044"; - rLen = 0; - rLoc = 26065; - rType = 0; - vrLen = 1250; - vrLoc = 25644; - }; - 6BD4DBCB10145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 1044"; - rLen = 0; - rLoc = 26065; - rType = 0; - vrLen = 1250; - vrLoc = 25644; - }; - 6BD4DBCC10145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 1037"; - rLen = 0; - rLoc = 25785; - rType = 0; - vrLen = 1146; - vrLoc = 25347; - }; - 6BD4DBCD10145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 82"; - rLen = 0; - rLoc = 3498; - rType = 0; - vrLen = 1064; - vrLoc = 2736; - }; - 6BD4DBCE10145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 374"; - rLen = 6; - rLoc = 10137; - rType = 0; - vrLen = 759; - vrLoc = 9668; - }; - 6BD4DBCF10145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 83"; - rLen = 0; - rLoc = 3542; - rType = 0; - vrLen = 1073; - vrLoc = 2736; - }; - 6BD4DBD010145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 374"; - rLen = 6; - rLoc = 10137; - rType = 0; - vrLen = 759; - vrLoc = 9668; - }; - 6BD4DBD110145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 84"; - rLen = 0; - rLoc = 3619; - rType = 0; - vrLen = 1113; - vrLoc = 2736; - }; - 6BD4DBD210145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 374"; - rLen = 6; - rLoc = 10137; - rType = 0; - vrLen = 759; - vrLoc = 9668; - }; - 6BD4DBD310145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 84"; - rLen = 0; - rLoc = 3619; - rType = 0; - vrLen = 1064; - vrLoc = 2736; - }; - 6BD4DBD410145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 470"; - rLen = 0; - rLoc = 11835; - rType = 0; - vrLen = 410; - vrLoc = 11660; - }; - 6BD4DBD510145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 85"; - rLen = 0; - rLoc = 3685; - rType = 0; - vrLen = 1154; - vrLoc = 2736; - }; - 6BD4DBD610145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 470"; - rLen = 0; - rLoc = 11835; - rType = 0; - vrLen = 410; - vrLoc = 11660; - }; - 6BD4DBD710145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 85"; - rLen = 0; - rLoc = 3685; - rType = 0; - vrLen = 1154; - vrLoc = 2736; - }; - 6BD4DBD810145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 477"; - rLen = 0; - rLoc = 11966; - rType = 0; - vrLen = 410; - vrLoc = 11660; - }; - 6BD4DBD910145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 85"; - rLen = 0; - rLoc = 3685; - rType = 0; - vrLen = 1146; - vrLoc = 2736; - }; - 6BD4DBDA10145C42003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; - name = "DetourTileNavMesh.cpp: 378"; - rLen = 0; - rLoc = 10230; - rType = 0; - vrLen = 736; - vrLoc = 9496; - }; - 6BD4DBDC101485D3003FF199 /* PBXTextBookmark */ = { - isa = PBXTextBookmark; - fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; - name = "DetourTileNavMesh.h: 276"; - rLen = 0; - rLoc = 11997; - rType = 0; - vrLen = 880; - vrLoc = 11479; - }; 6BDD9E040F91112200904EEF /* DetourDebugDraw.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 516}}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 609}}"; sepNavSelRange = "{1194, 0}"; sepNavVisRange = "{0, 1465}"; }; }; 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 3088}}"; - sepNavSelRange = "{7274, 0}"; - sepNavVisRange = "{6460, 1576}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 3760}}"; + sepNavSelRange = "{4694, 0}"; + sepNavVisRange = "{3168, 1912}"; }; }; 6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 499}}"; - sepNavSelRange = "{0, 918}"; - sepNavVisRange = "{0, 1284}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 527}}"; + sepNavSelRange = "{639, 0}"; + sepNavVisRange = "{0, 1416}"; }; }; 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 6592}}"; - sepNavSelRange = "{3107, 22}"; - sepNavVisRange = "{2960, 619}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 7568}}"; + sepNavSelRange = "{12618, 0}"; + sepNavVisRange = "{11988, 699}"; }; }; 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 12960}}"; - sepNavSelRange = "{19735, 300}"; - sepNavVisRange = "{19289, 1013}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 14272}}"; + sepNavSelRange = "{10567, 0}"; + sepNavVisRange = "{10265, 453}"; }; }; 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {915, 4240}}"; - sepNavSelRange = "{5505, 0}"; - sepNavVisRange = "{5247, 1262}"; + sepNavIntBoundsRect = "{{0, 0}, {915, 5600}}"; + sepNavSelRange = "{5801, 0}"; + sepNavVisRange = "{5389, 736}"; sepNavWindowFrame = "{{15, 78}, {1011, 695}}"; }; }; + 6BF26B4310413CC80099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; + name = "Recast.h: 186"; + rLen = 0; + rLoc = 7361; + rType = 0; + vrLen = 946; + vrLoc = 6729; + }; + 6BF26B4410413CC80099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 397"; + rLen = 0; + rLoc = 10269; + rType = 0; + vrLen = 770; + vrLoc = 12557; + }; + 6BF26B4510413CC80099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 626"; + rLen = 0; + rLoc = 14683; + rType = 0; + vrLen = 657; + vrLoc = 16021; + }; + 6BF26B4610413CC80099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 501"; + rLen = 0; + rLoc = 12486; + rType = 0; + vrLen = 599; + vrLoc = 13984; + }; + 6BF26B5110413CF00099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 762"; + rLen = 0; + rLoc = 17088; + rType = 0; + vrLen = 641; + vrLoc = 17624; + }; + 6BF26B641041423B0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 929"; + rLen = 0; + rLoc = 24323; + rType = 0; + vrLen = 708; + vrLoc = 23319; + }; + 6BF26B651041423B0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 763"; + rLen = 0; + rLoc = 17092; + rType = 0; + vrLen = 666; + vrLoc = 17600; + }; + 6BF26B661041423B0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 927"; + rLen = 0; + rLoc = 24281; + rType = 0; + vrLen = 742; + vrLoc = 23284; + }; + 6BF26B671041423B0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; + name = "Recast.h: 184"; + rLen = 0; + rLoc = 7259; + rType = 0; + vrLen = 877; + vrLoc = 6729; + }; + 6BF26B681041423B0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 852"; + rLen = 0; + rLoc = 22355; + rType = 0; + vrLen = 851; + vrLoc = 21556; + }; + 6BF26B691041423B0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 782"; + rLen = 0; + rLoc = 17499; + rType = 0; + vrLen = 482; + vrLoc = 17791; + }; + 6BF26B6A1041423B0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 832"; + rLen = 0; + rLoc = 21605; + rType = 0; + vrLen = 779; + vrLoc = 20924; + }; + 6BF26B6B1041423B0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; + name = "Recast.h: 181"; + rLen = 0; + rLoc = 7236; + rType = 0; + vrLen = 876; + vrLoc = 6729; + }; + 6BF26B781041437C0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 746"; + rLen = 0; + rLoc = 16752; + rType = 0; + vrLen = 653; + vrLoc = 17353; + }; + 6BF26B7B1041437C0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 69"; + rLen = 7; + rLoc = 2147; + rType = 0; + vrLen = 463; + vrLoc = 1898; + }; + 6BF26B7D1041437C0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 205"; + rLen = 0; + rLoc = 8370; + rType = 0; + vrLen = 1502; + vrLoc = 7843; + }; + 6BF26B85104143E10099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 683"; + rLen = 0; + rLoc = 17719; + rType = 0; + vrLen = 671; + vrLoc = 17074; + }; + 6BF26B86104143E10099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 264"; + rLen = 0; + rLoc = 5399; + rType = 0; + vrLen = 543; + vrLoc = 6809; + }; + 6BF26B8C104144910099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 772"; + rLen = 0; + rLoc = 17316; + rType = 0; + vrLen = 633; + vrLoc = 16952; + }; + 6BF26B92104144F90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 847"; + rLen = 0; + rLoc = 22389; + rType = 0; + vrLen = 797; + vrLoc = 21287; + }; + 6BF26B93104144F90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 775"; + rLen = 0; + rLoc = 17393; + rType = 0; + vrLen = 651; + vrLoc = 17551; + }; + 6BF26B94104144F90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 846"; + rLen = 0; + rLoc = 22302; + rType = 0; + vrLen = 800; + vrLoc = 21283; + }; + 6BF26B9E104145630099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 772"; + rLen = 0; + rLoc = 17316; + rType = 0; + vrLen = 507; + vrLoc = 17762; + }; + 6BF26B9F104145630099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 846"; + rLen = 0; + rLoc = 22349; + rType = 0; + vrLen = 800; + vrLoc = 21283; + }; + 6BF26BA5104145A20099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 773"; + rLen = 0; + rLoc = 17323; + rType = 0; + vrLen = 515; + vrLoc = 17758; + }; + 6BF26BA7104151460099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 927"; + rLen = 0; + rLoc = 24327; + rType = 0; + vrLen = 769; + vrLoc = 23291; + }; + 6BF26BAA104151460099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; + name = "RecastMeshDetail.cpp: 927"; + rLen = 0; + rLoc = 24327; + rType = 0; + vrLen = 769; + vrLoc = 23291; + }; + 6BF26BAE104151A50099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C840F7FCC1100459200 /* RecastDebugDraw.cpp */; + name = "RecastDebugDraw.cpp: 774"; + rLen = 0; + rLoc = 17357; + rType = 0; + vrLen = 515; + vrLoc = 17758; + }; + 6BF26BB51041520F0099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; + name = "DetourStatNavMesh.cpp: 315"; + rLen = 0; + rLoc = 6991; + rType = 0; + vrLen = 613; + vrLoc = 7431; + }; + 6BF26BC4104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6160FFA62BE004F1BC4 /* Sample_StatMeshSimple.cpp */; + name = "Sample_StatMeshSimple.cpp: 469"; + rLen = 0; + rLoc = 14005; + rType = 0; + vrLen = 1054; + vrLoc = 11131; + }; + 6BF26BC5104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC510FFB8946005BE9CC /* Sample_TileMesh.h */; + name = "Sample_TileMesh.h: 41"; + rLen = 0; + rLoc = 1402; + rType = 0; + vrLen = 573; + vrLoc = 1106; + }; + 6BF26BC6104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B137C7E0F7FCBFE00459200 /* Recast.h */; + name = "Recast.h: 485"; + rLen = 150; + rLoc = 17540; + rType = 0; + vrLen = 1175; + vrLoc = 16639; + }; + 6BF26BC7104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; + name = "Sample_StatMeshTiled.cpp: 930"; + rLen = 0; + rLoc = 26311; + rType = 0; + vrLen = 862; + vrLoc = 25748; + }; + 6BF26BC9104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B920FFCC2AC0088D3A5 /* DetourTileNavMeshBuilder.h */; + name = "DetourTileNavMeshBuilder.h: 26"; + rLen = 0; + rLoc = 1272; + rType = 0; + vrLen = 1461; + vrLoc = 0; + }; + 6BF26BCA104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */; + name = "DetourStatNavMeshBuilder.h: 27"; + rLen = 0; + rLoc = 1328; + rType = 0; + vrLen = 1416; + vrLoc = 0; + }; + 6BF26BCE104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 201"; + rLen = 0; + rLoc = 8093; + rType = 0; + vrLen = 1518; + vrLoc = 7058; + }; + 6BF26BD1104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 248"; + rLen = 0; + rLoc = 5399; + rType = 0; + vrLen = 841; + vrLoc = 6306; + }; + 6BF26BD2104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B25B6160FFA62BE004F1BC4 /* Sample_StatMeshSimple.cpp */; + name = "Sample_StatMeshSimple.cpp: 469"; + rLen = 0; + rLoc = 14005; + rType = 0; + vrLen = 1054; + vrLoc = 11131; + }; + 6BF26BD3104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC510FFB8946005BE9CC /* Sample_TileMesh.h */; + name = "Sample_TileMesh.h: 41"; + rLen = 0; + rLoc = 1402; + rType = 0; + vrLen = 573; + vrLoc = 1106; + }; + 6BF26BD4104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; + name = "Sample_StatMeshTiled.cpp: 579"; + rLen = 160; + rLoc = 15836; + rType = 0; + vrLen = 1178; + vrLoc = 15408; + }; + 6BF26BD5104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 842"; + rLen = 0; + rLoc = 22468; + rType = 0; + vrLen = 992; + vrLoc = 21891; + }; + 6BF26BD6104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B920FFCC2AC0088D3A5 /* DetourTileNavMeshBuilder.h */; + name = "DetourTileNavMeshBuilder.h: 26"; + rLen = 0; + rLoc = 1272; + rType = 0; + vrLen = 1461; + vrLoc = 0; + }; + 6BF26BD7104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 30"; + rLen = 0; + rLoc = 1334; + rType = 0; + vrLen = 800; + vrLoc = 1693; + }; + 6BF26BD8104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E060F91112200904EEF /* DetourStatNavMeshBuilder.h */; + name = "DetourStatNavMeshBuilder.h: 27"; + rLen = 0; + rLoc = 1328; + rType = 0; + vrLen = 1416; + vrLoc = 0; + }; + 6BF26BDA104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 94"; + rLen = 0; + rLoc = 3175; + rType = 0; + vrLen = 811; + vrLoc = 2439; + }; + 6BF26BDC104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 98"; + rLen = 0; + rLoc = 3176; + rType = 0; + vrLen = 1004; + vrLoc = 2602; + }; + 6BF26BDE104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 107"; + rLen = 0; + rLoc = 3621; + rType = 0; + vrLen = 1144; + vrLoc = 2669; + }; + 6BF26BE0104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 111"; + rLen = 0; + rLoc = 3818; + rType = 0; + vrLen = 1201; + vrLoc = 2693; + }; + 6BF26BE2104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 128"; + rLen = 0; + rLoc = 4265; + rType = 0; + vrLen = 972; + vrLoc = 3282; + }; + 6BF26BE4104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 205"; + rLen = 0; + rLoc = 6203; + rType = 0; + vrLen = 891; + vrLoc = 4723; + }; + 6BF26BE5104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 37"; + rLen = 258; + rLoc = 1489; + rType = 0; + vrLen = 848; + vrLoc = 1050; + }; + 6BF26BE6104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; + name = "DetourStatNavMesh.cpp: 59"; + rLen = 562; + rLoc = 1883; + rType = 0; + vrLen = 1040; + vrLoc = 1573; + }; + 6BF26BE7104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 97"; + rLen = 0; + rLoc = 3174; + rType = 0; + vrLen = 1094; + vrLoc = 2602; + }; + 6BF26BE8104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 93"; + rLen = 52; + rLoc = 2935; + rType = 0; + vrLen = 1094; + vrLoc = 2602; + }; + 6BF26BE9104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 178"; + rLen = 313; + rLoc = 6828; + rType = 0; + vrLen = 1347; + vrLoc = 6252; + }; + 6BF26BEA104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; + name = "DetourTileNavMesh.h: 259"; + rLen = 79; + rLoc = 10883; + rType = 0; + vrLen = 1032; + vrLoc = 10354; + }; + 6BF26BEC104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 206"; + rLen = 0; + rLoc = 8375; + rType = 0; + vrLen = 1518; + vrLoc = 7058; + }; + 6BF26BED104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; + name = "DetourStatNavMesh.cpp: 244"; + rLen = 0; + rLoc = 6238; + rType = 0; + vrLen = 718; + vrLoc = 6020; + }; + 6BF26BEE104158E90099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E050F91112200904EEF /* DetourStatNavMesh.h */; + name = "DetourStatNavMesh.h: 201"; + rLen = 0; + rLoc = 8093; + rType = 0; + vrLen = 1518; + vrLoc = 7058; + }; + 6BF26C0B10415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; + name = "DetourStatNavMeshBuilder.cpp: 341"; + rLen = 0; + rLoc = 9192; + rType = 0; + vrLen = 877; + vrLoc = 8433; + }; + 6BF26C0C10415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E080F91113800904EEF /* DetourStatNavMesh.cpp */; + name = "DetourStatNavMesh.cpp: 314"; + rLen = 0; + rLoc = 6991; + rType = 0; + vrLen = 623; + vrLoc = 7768; + }; + 6BF26C1110415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E090F91113800904EEF /* DetourStatNavMeshBuilder.cpp */; + name = "DetourStatNavMeshBuilder.cpp: 341"; + rLen = 0; + rLoc = 9192; + rType = 0; + vrLen = 877; + vrLoc = 8433; + }; + 6BF26C1210415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 576"; + rLen = 0; + rLoc = 13945; + rType = 0; + vrLen = 773; + vrLoc = 13920; + }; + 6BF26C1310415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 474"; + rLen = 0; + rLoc = 8146; + rType = 0; + vrLen = 597; + vrLoc = 11954; + }; + 6BF26C1410415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 94"; + rLen = 0; + rLoc = 3028; + rType = 0; + vrLen = 974; + vrLoc = 2602; + }; + 6BF26C1510415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; + name = "DetourTileNavMesh.h: 86"; + rLen = 0; + rLoc = 3595; + rType = 0; + vrLen = 1032; + vrLoc = 3248; + }; + 6BF26C1610415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 366"; + rLen = 0; + rLoc = 9931; + rType = 0; + vrLen = 1011; + vrLoc = 9568; + }; + 6BF26C1710415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; + name = "DetourTileNavMesh.h: 86"; + rLen = 0; + rLoc = 3595; + rType = 0; + vrLen = 1162; + vrLoc = 2892; + }; + 6BF26C1810415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 366"; + rLen = 0; + rLoc = 9931; + rType = 0; + vrLen = 1011; + vrLoc = 9568; + }; + 6BF26C1910415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; + name = "DetourTileNavMesh.h: 86"; + rLen = 0; + rLoc = 3595; + rType = 0; + vrLen = 1162; + vrLoc = 2892; + }; + 6BF26C1A10415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 601"; + rLen = 0; + rLoc = 14420; + rType = 0; + vrLen = 663; + vrLoc = 14368; + }; + 6BF26C1B10415C680099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 449"; + rLen = 0; + rLoc = 8146; + rType = 0; + vrLen = 667; + vrLoc = 11702; + }; + 6BF26C2410415CA60099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 1407"; + rLen = 0; + rLoc = 34846; + rType = 0; + vrLen = 957; + vrLoc = 35296; + }; + 6BF26C2910415D040099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 190"; + rLen = 0; + rLoc = 5415; + rType = 0; + vrLen = 852; + vrLoc = 5424; + }; + 6BF26C301041A5190099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 113"; + rLen = 0; + rLoc = 3621; + rType = 0; + vrLen = 763; + vrLoc = 5603; + }; + 6BF26C311041A5190099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 370"; + rLen = 0; + rLoc = 10145; + rType = 0; + vrLen = 1065; + vrLoc = 9475; + }; + 6BF26C321041A5190099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; + name = "DetourTileNavMesh.h: 40"; + rLen = 0; + rLoc = 1752; + rType = 0; + vrLen = 1039; + vrLoc = 1430; + }; + 6BF26C341041A5190099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 377"; + rLen = 0; + rLoc = 8146; + rType = 0; + vrLen = 652; + vrLoc = 9274; + }; + 6BF26C351041A5190099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B092B930FFCC2BD0088D3A5 /* DetourTileNavMeshBuilder.cpp */; + name = "DetourTileNavMeshBuilder.cpp: 113"; + rLen = 0; + rLoc = 3621; + rType = 0; + vrLen = 763; + vrLoc = 5603; + }; + 6BF26C361041A5190099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; + name = "DetourTileNavMesh.h: 86"; + rLen = 0; + rLoc = 3595; + rType = 0; + vrLen = 1162; + vrLoc = 2892; + }; + 6BF26C371041A5190099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; + name = "DetourTileNavMesh.cpp: 370"; + rLen = 0; + rLoc = 10145; + rType = 0; + vrLen = 1065; + vrLoc = 9475; + }; + 6BF26C381041A5190099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC580FFB8A68005BE9CC /* DetourTileNavMesh.h */; + name = "DetourTileNavMesh.h: 40"; + rLen = 0; + rLoc = 1752; + rType = 0; + vrLen = 1039; + vrLoc = 1430; + }; + 6BF26C3C1041A5F00099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 814"; + rLen = 0; + rLoc = 22039; + rType = 0; + vrLen = 883; + vrLoc = 21638; + }; + 6BF26C3D1041A5F00099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 377"; + rLen = 0; + rLoc = 8146; + rType = 0; + vrLen = 650; + vrLoc = 9276; + }; + 6BF26C3E1041A5F00099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6B2AEC520FFB8958005BE9CC /* Sample_TileMesh.cpp */; + name = "Sample_TileMesh.cpp: 814"; + rLen = 0; + rLoc = 22039; + rType = 0; + vrLen = 883; + vrLoc = 21638; + }; + 6BF26C451042A5530099C14A /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 6BDD9E070F91113800904EEF /* DetourDebugDraw.cpp */; + name = "DetourDebugDraw.cpp: 456"; + rLen = 0; + rLoc = 8146; + rType = 0; + vrLen = 934; + vrLoc = 11193; + }; 8D1107260486CEB800E47090 /* Recast */ = { activeExec = 0; executables = ( diff --git a/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.perspectivev3 b/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.perspectivev3 index afe9ce63..7254d4b9 100644 --- a/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.perspectivev3 +++ b/RecastDemo/Build/Xcode/Recast.xcodeproj/memon.perspectivev3 @@ -279,14 +279,14 @@ PBXSmartGroupTreeModuleOutlineStateSelectionKey - 10 - 3 + 32 + 18 1 0 PBXSmartGroupTreeModuleOutlineStateVisibleRectKey - {{0, 33}, {282, 628}} + {{0, 229}, {282, 628}} PBXTopSmartGroupGIDs @@ -321,7 +321,7 @@ PBXProjectModuleGUID 6B8632A30F78115100E2684A PBXProjectModuleLabel - DetourTileNavMesh.h + RecastMeshDetail.cpp PBXSplitModuleInNavigatorKey Split0 @@ -329,105 +329,99 @@ PBXProjectModuleGUID 6B8632A40F78115100E2684A PBXProjectModuleLabel - DetourTileNavMesh.h + RecastMeshDetail.cpp _historyCapacity 0 bookmark - 6B58CAE510198B2400956BA2 + 6B33154A1042C0A500E98B50 history 6B7707F00FBD90F100D21BAE - 6B995BDF0FE0D9B300D5C493 - 6BC745A70FF527E50083A694 - 6BC745A80FF527E50083A694 6B9B7D9D0FF91AC600A9090F 6B25B43E0FFA1786004F1BC4 6B25B44B0FFA1968004F1BC4 - 6B2AEC620FFB8AB0005BE9CC 6B2AEC670FFB8AB0005BE9CC - 6B2AECED0FFB8B41005BE9CC - 6B092B4F0FFCA0A20088D3A5 6B092B500FFCA0A20088D3A5 - 6B092CC10FFE40160088D3A5 6B0249BE1003793900CF7107 - 6B024BD31006059C00CF7107 6B024C011006098300CF7107 6B024C1110060C7600CF7107 6B1186211006945C0018F96F - 6B1186D1100699A00018F96F 6B7EBB69100721310066EF8C - 6B555D24100B136A00247EA3 6B555D30100B143200247EA3 6B555E01100B285300247EA3 - 6B555E5F100B334900247EA3 - 6B555E60100B334900247EA3 - 6B555EA1100B37AB00247EA3 - 6B555F0C100B473F00247EA3 6B555F0D100B473F00247EA3 6B555F0E100B473F00247EA3 - 6B555F0F100B473F00247EA3 - 6B92CE68100E0577003DA304 6B92CE69100E0577003DA304 6B92CE6A100E0577003DA304 - 6B92CE6F100E0577003DA304 - 6B92CE70100E0577003DA304 - 6B92CE72100E0577003DA304 6B92CE8A100E0739003DA304 6B995F9F100F336B00D7BF5A 6B995FA2100F336B00D7BF5A 6B995FDF100F387200D7BF5A - 6B996059100F42AF00D7BF5A - 6B8AE8DA10121C6000FF1D07 6B8AE8FA10123B5700FF1D07 - 6B8AE8FB10123B5700FF1D07 - 6B8AE8FC10123B5700FF1D07 - 6B8AE8FE10123B5700FF1D07 - 6B8AE90010123B5700FF1D07 - 6B8AE90210123B5700FF1D07 - 6B8AE90310123B5700FF1D07 - 6B8AE90410123B5700FF1D07 - 6B8AE90510123B5700FF1D07 - 6B8AE90610123B5700FF1D07 - 6B8AE90710123B5700FF1D07 - 6BD4DBB910145A50003FF199 - 6BD4DBBA10145A50003FF199 - 6BD4DBC710145C42003FF199 - 6BD4DBC810145C42003FF199 - 6BD4DBDC101485D3003FF199 + 6B9D0AF4102991F0009B1A6C + 6B93FDBB102FFCFE00F0C0DA + 6B6241E91034B2FA0002E346 + 6B6241EB1034B2FA0002E346 + 6B955A0610359EBB00FE9FE3 + 6B955A0810359EBB00FE9FE3 + 6B955A0A10359EBB00FE9FE3 + 6B955A0C10359EBB00FE9FE3 + 6B95069A103869D900213080 + 6B9506F810388A4200213080 + 6B41876A1039827000FBF4A5 + 6B41878E1039854600FBF4A5 + 6B74D091103DDCC300623975 + 6B05B00C10405F0A004A71D1 + 6B05B01010405F0A004A71D1 + 6BF26BC5104158E90099C14A + 6BF26BC9104158E90099C14A + 6B3314EA1042BC8200E98B50 + 6B3314EC1042BC8200E98B50 + 6B3314ED1042BC8200E98B50 + 6B3314EE1042BC8200E98B50 + 6B3314EF1042BC8200E98B50 + 6B3314F01042BC8200E98B50 + 6B3314F11042BC8200E98B50 + 6B3314F21042BC8200E98B50 + 6B3314F31042BC8200E98B50 + 6B3314F41042BC8200E98B50 + 6B3314F51042BC8200E98B50 + 6B3314F61042BC8200E98B50 + 6B3314F71042BC8200E98B50 + 6B3314F81042BC8200E98B50 + 6B3314F91042BC8200E98B50 + 6B3314FB1042BC8200E98B50 + 6B33152E1042BD3500E98B50 + 6B3315321042BE1600E98B50 + 6B3315331042BE1600E98B50 + 6B3315341042BE1600E98B50 + 6B3315351042BE1600E98B50 + 6B3315361042BE1600E98B50 + 6B3315371042BE1600E98B50 + 6B3315381042BE1600E98B50 + 6B3315391042BE1600E98B50 + 6B3315481042C02C00E98B50 prevStack - 6B1E02680F924A8500CC0038 - 6B1E02FC0F92563500CC0038 6B1E032E0F925D9100CC0038 6B8DB3900F9798DE007FA9E1 6B458EA80FB4540500044EA9 6B7707B90FBD66CF00D21BAE 6B7707F90FBD90F100D21BAE 6B7708F70FBDA96300D21BAE - 6BB787C30FC03EAD003C24DB 6BB788290FC0593E003C24DB 6BB7882A0FC0593E003C24DB 6BB7882B0FC0593E003C24DB 6BB85D3E0FCEAA6300758966 - 6BC620920FD7C2380022CACF - 6BC745AD0FF527E50083A694 - 6BC745AE0FF527E50083A694 6BC745AF0FF527E50083A694 - 6B9B7DA30FF91AC600A9090F - 6B9B7DA40FF91AC600A9090F 6B25B4120FFA1545004F1BC4 6B86333B0F7813A600E2684A 6B25B4080FFA13E9004F1BC4 6B25B6250FFA63C8004F1BC4 6B2AEC740FFB8AB0005BE9CC 6B2AEC750FFB8AB0005BE9CC - 6B2AED930FFBA45B005BE9CC - 6B092B1A0FFC98FF0088D3A5 - 6B092B530FFCA0A20088D3A5 6B092BBC0FFCEC1A0088D3A5 - 6B2AEC970FFB8AB0005BE9CC - 6B0249051001EABD00CF7107 6B02498D1003751300CF7107 6B024A721004A2FE00CF7107 6B024BCF1005DFAB00CF7107 @@ -442,15 +436,65 @@ 6B555E13100B285300247EA3 6B555EE0100B39A600247EA3 6B555EF9100B42E600247EA3 - 6B555FB4100B595C00247EA3 6B8AE8DF10121C6000FF1D07 - 6B8AE90D10123B5700FF1D07 - 6B8AE90E10123B5700FF1D07 - 6B8AE90F10123B5700FF1D07 - 6B8AE91010123B5700FF1D07 - 6B8AE91810123B5700FF1D07 - 6B8AE91910123B5700FF1D07 - 6BD4DBCD10145C42003FF199 + 6B93FDF010300CBE00F0C0DA + 6B95065010383C6900213080 + 6B9506891038680900213080 + 6B9507401038910D00213080 + 6B41875F10397C9F00FBF4A5 + 6B4187C41039909100FBF4A5 + 6B418869103ACAC700FBF4A5 + 6B74D052103DD64C00623975 + 6B05AF59104042D5004A71D1 + 6B05AFA810404FAB004A71D1 + 6B05AFA910404FAB004A71D1 + 6BF26BB51041520F0099C14A + 6BF26BD4104158E90099C14A + 6BF26BD5104158E90099C14A + 6BF26BD8104158E90099C14A + 6BF26C1110415C680099C14A + 6BF26C1210415C680099C14A + 6B3314FD1042BC8200E98B50 + 6B3314FE1042BC8200E98B50 + 6B3314FF1042BC8200E98B50 + 6B3315001042BC8200E98B50 + 6B3315011042BC8200E98B50 + 6B3315021042BC8200E98B50 + 6B3315031042BC8200E98B50 + 6B3315041042BC8200E98B50 + 6B3315051042BC8200E98B50 + 6B3315061042BC8200E98B50 + 6B3315071042BC8200E98B50 + 6B3315081042BC8200E98B50 + 6B3315091042BC8200E98B50 + 6B33150A1042BC8200E98B50 + 6B33150B1042BC8200E98B50 + 6B33150C1042BC8200E98B50 + 6B33150D1042BC8200E98B50 + 6B33150E1042BC8200E98B50 + 6B33150F1042BC8200E98B50 + 6B3315101042BC8200E98B50 + 6B3315111042BC8200E98B50 + 6B3315121042BC8200E98B50 + 6B3315131042BC8200E98B50 + 6B3315141042BC8200E98B50 + 6B3315151042BC8200E98B50 + 6B3315161042BC8200E98B50 + 6B3315171042BC8200E98B50 + 6B3315181042BC8200E98B50 + 6B3315191042BC8200E98B50 + 6B33151A1042BC8200E98B50 + 6B33151B1042BC8200E98B50 + 6B33151C1042BC8200E98B50 + 6B3315301042BD3500E98B50 + 6B33153B1042BE1600E98B50 + 6B33153C1042BE1600E98B50 + 6B33153D1042BE1600E98B50 + 6B33153E1042BE1600E98B50 + 6B33153F1042BE1600E98B50 + 6B3315401042BE1600E98B50 + 6B3315411042BE1600E98B50 + 6B3315421042BE1600E98B50 SplitCount @@ -464,18 +508,18 @@ GeometryConfiguration Frame - {{0, 0}, {976, 522}} + {{0, 0}, {976, 490}} RubberWindowFrame 0 91 1280 687 0 0 1280 778 Module PBXNavigatorGroup Proportion - 522pt + 490pt Proportion - 119pt + 151pt Tabs @@ -489,9 +533,7 @@ GeometryConfiguration Frame - {{10, 27}, {976, 92}} - RubberWindowFrame - 0 91 1280 687 0 0 1280 778 + {{10, 27}, {976, 55}} Module XCDetailModule @@ -507,7 +549,7 @@ GeometryConfiguration Frame - {{10, 27}, {976, -27}} + {{10, 27}, {976, 172}} Module PBXProjectFindModule @@ -545,7 +587,9 @@ GeometryConfiguration Frame - {{10, 27}, {976, 165}} + {{10, 27}, {976, 124}} + RubberWindowFrame + 0 91 1280 687 0 0 1280 778 Module PBXBuildResultsModule @@ -573,11 +617,11 @@ TableOfContents - 6B58CAE610198B2400956BA2 + 6B33151E1042BC8200E98B50 1CA23ED40692098700951B8B - 6B58CAE710198B2400956BA2 + 6B33151F1042BC8200E98B50 6B8632A30F78115100E2684A - 6B58CAE810198B2400956BA2 + 6B3315201042BC8200E98B50 1CA23EDF0692099D00951B8B 1CA23EE00692099D00951B8B 1CA23EE10692099D00951B8B @@ -626,12 +670,12 @@ GeometryConfiguration Frame - {{0, 0}, {1280, 242}} + {{0, 0}, {1280, 356}} Module PBXDebugCLIModule Proportion - 242pt + 356pt ContentConfiguration @@ -650,8 +694,8 @@ yes sizes - {{0, 0}, {637, 110}} - {{637, 0}, {643, 110}} + {{0, 0}, {623, 117}} + {{623, 0}, {657, 117}} VerticalSplitView @@ -666,8 +710,8 @@ yes sizes - {{0, 0}, {1280, 110}} - {{0, 110}, {1280, 289}} + {{0, 0}, {1280, 117}} + {{0, 117}, {1280, 168}} @@ -687,7 +731,7 @@ DebugSTDIOWindowFrame {{200, 200}, {500, 300}} Frame - {{0, 247}, {1280, 399}} + {{0, 361}, {1280, 285}} PBXDebugSessionStackFrameViewKey DebugVariablesTableConfiguration @@ -697,16 +741,16 @@ Value 85 Summary - 413 + 427 Frame - {{637, 0}, {643, 110}} + {{623, 0}, {657, 117}} Module PBXDebugSessionModule Proportion - 399pt + 285pt Name @@ -724,14 +768,14 @@ TableOfContents - 6B8AE8E410121C6000FF1D07 + 6B3315211042BC8200E98B50 1CCC7628064C1048000F2A68 1CCC7629064C1048000F2A68 - 6B8AE8E510121C6000FF1D07 - 6B8AE8E610121C6000FF1D07 - 6B8AE8E710121C6000FF1D07 - 6B8AE8E810121C6000FF1D07 - 6B8AE8E910121C6000FF1D07 + 6B3315221042BC8200E98B50 + 6B3315231042BC8200E98B50 + 6B3315241042BC8200E98B50 + 6B3315251042BC8200E98B50 + 6B3315261042BC8200E98B50 ToolbarConfiguration xcode.toolbar.config.debugV3 @@ -1293,7 +1337,6 @@ PBXSmartGroupTreeModuleOutlineStateSelectionKey - 2 0 @@ -1364,8 +1407,8 @@ TableOfContents - 6BB788730FC05EB9003C24DB - 6BB788740FC05EB9003C24DB + 6B74D0B7103DE14B00623975 + 6B74D0B8103DE14B00623975 1CE0B1FE06471DED0097A5F4 1CA1AED706398EBD00589147 @@ -1374,7 +1417,7 @@ WindowString 21 346 744 409 0 0 1280 778 WindowToolGUID - 6BB788730FC05EB9003C24DB + 6B74D0B7103DE14B00623975 WindowToolIsVisible diff --git a/RecastDemo/Build/Xcode/Recast.xcodeproj/project.pbxproj b/RecastDemo/Build/Xcode/Recast.xcodeproj/project.pbxproj index 2866c897..9a09e028 100644 --- a/RecastDemo/Build/Xcode/Recast.xcodeproj/project.pbxproj +++ b/RecastDemo/Build/Xcode/Recast.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 6B2AEC560FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B2AEC550FFB89E7005BE9CC /* Sample_StatMeshTiled.cpp */; }; 6B2AEC5A0FFB8A7A005BE9CC /* DetourTileNavMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B2AEC590FFB8A7A005BE9CC /* DetourTileNavMesh.cpp */; }; 6B555DB1100B212E00247EA3 /* imguiRenderGL.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */; }; + 6B62416A103434880002E346 /* RecastMeshDetail.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6B624169103434880002E346 /* RecastMeshDetail.cpp */; }; 6B8632DA0F78122C00E2684A /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B8632D90F78122C00E2684A /* SDL.framework */; }; 6B8632DC0F78123E00E2684A /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B8632DB0F78123E00E2684A /* OpenGL.framework */; }; 6BB788170FC0472B003C24DB /* ChunkyTriMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6BB788160FC0472B003C24DB /* ChunkyTriMesh.cpp */; }; @@ -92,6 +93,7 @@ 6B555DAE100B211D00247EA3 /* imguiRenderGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imguiRenderGL.h; path = ../../Include/imguiRenderGL.h; sourceTree = SOURCE_ROOT; }; 6B555DB0100B212E00247EA3 /* imguiRenderGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imguiRenderGL.cpp; path = ../../Source/imguiRenderGL.cpp; sourceTree = SOURCE_ROOT; }; 6B555DF6100B273500247EA3 /* stb_truetype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = stb_truetype.h; path = ../../Contrib/stb_truetype.h; sourceTree = SOURCE_ROOT; }; + 6B624169103434880002E346 /* RecastMeshDetail.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RecastMeshDetail.cpp; path = ../../../Recast/Source/RecastMeshDetail.cpp; sourceTree = SOURCE_ROOT; }; 6B8632D90F78122C00E2684A /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = Library/Frameworks/SDL.framework; sourceTree = SDKROOT; }; 6B8632DB0F78123E00E2684A /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 6BB788160FC0472B003C24DB /* ChunkyTriMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ChunkyTriMesh.cpp; path = ../../Source/ChunkyTriMesh.cpp; sourceTree = SOURCE_ROOT; }; @@ -226,6 +228,7 @@ 6B137C7F0F7FCBFE00459200 /* RecastDebugDraw.h */, 6B137C800F7FCBFE00459200 /* RecastLog.h */, 6B137C810F7FCBFE00459200 /* RecastTimer.h */, + 6B624169103434880002E346 /* RecastMeshDetail.cpp */, ); name = Recast; sourceTree = ""; @@ -351,6 +354,7 @@ 6B1185F51006895B0018F96F /* DetourNode.cpp in Sources */, 6B1185FE10068B150018F96F /* DetourCommon.cpp in Sources */, 6B555DB1100B212E00247EA3 /* imguiRenderGL.cpp in Sources */, + 6B62416A103434880002E346 /* RecastMeshDetail.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/RecastDemo/Include/Sample.h b/RecastDemo/Include/Sample.h index 7706f8af..00239c54 100644 --- a/RecastDemo/Include/Sample.h +++ b/RecastDemo/Include/Sample.h @@ -23,6 +23,8 @@ protected: float m_edgeMaxLen; float m_edgeMaxError; float m_vertsPerPoly; + float m_detailSampleDist; + float m_detailSampleMaxError; public: Sample(); diff --git a/RecastDemo/Include/Sample_StatMeshSimple.h b/RecastDemo/Include/Sample_StatMeshSimple.h index c381df61..be89dea8 100644 --- a/RecastDemo/Include/Sample_StatMeshSimple.h +++ b/RecastDemo/Include/Sample_StatMeshSimple.h @@ -17,8 +17,9 @@ protected: rcHeightfield* m_solid; rcCompactHeightfield* m_chf; rcContourSet* m_cset; - rcPolyMesh* m_polyMesh; + rcPolyMesh* m_pmesh; rcConfig m_cfg; + rcPolyMeshDetail* m_dmesh; enum DrawMode { @@ -37,6 +38,7 @@ protected: DRAWMODE_BOTH_CONTOURS, DRAWMODE_CONTOURS, DRAWMODE_POLYMESH, + DRAWMODE_POLYMESH_DETAIL, MAX_DRAWMODE }; diff --git a/RecastDemo/Include/Sample_StatMeshTiled.h b/RecastDemo/Include/Sample_StatMeshTiled.h index 0220707d..fca0b419 100644 --- a/RecastDemo/Include/Sample_StatMeshTiled.h +++ b/RecastDemo/Include/Sample_StatMeshTiled.h @@ -13,11 +13,13 @@ protected: struct Tile { - inline Tile() : chf(0), solid(0), cset(0), buildTime(0) {} - inline ~Tile() { delete chf; delete cset; delete solid; } + inline Tile() : chf(0), solid(0), cset(0), pmesh(0), dmesh(0), buildTime(0) {} + inline ~Tile() { delete chf; delete cset; delete solid; delete pmesh; delete dmesh; } rcCompactHeightfield* chf; rcHeightfield* solid; rcContourSet* cset; + rcPolyMesh* pmesh; + rcPolyMeshDetail* dmesh; int buildTime; }; @@ -37,7 +39,8 @@ protected: rcBuildTimes m_buildTimes; rcChunkyTriMesh* m_chunkyMesh; - rcPolyMesh* m_polyMesh; + rcPolyMesh* m_pmesh; + rcPolyMeshDetail* m_dmesh; rcConfig m_cfg; TileSet* m_tileSet; @@ -65,6 +68,7 @@ protected: DRAWMODE_BOTH_CONTOURS, DRAWMODE_CONTOURS, DRAWMODE_POLYMESH, + DRAWMODE_POLYMESH_DETAIL, MAX_DRAWMODE }; diff --git a/RecastDemo/Include/Sample_TileMesh.h b/RecastDemo/Include/Sample_TileMesh.h index b957312f..2cb8fcdc 100644 --- a/RecastDemo/Include/Sample_TileMesh.h +++ b/RecastDemo/Include/Sample_TileMesh.h @@ -38,7 +38,8 @@ protected: rcHeightfield* m_solid; rcCompactHeightfield* m_chf; rcContourSet* m_cset; - rcPolyMesh* m_polyMesh; + rcPolyMesh* m_pmesh; + rcPolyMeshDetail* m_dmesh; rcConfig m_cfg; float m_tileSize; diff --git a/RecastDemo/Source/Sample.cpp b/RecastDemo/Source/Sample.cpp index 1219547a..1b66782c 100644 --- a/RecastDemo/Source/Sample.cpp +++ b/RecastDemo/Source/Sample.cpp @@ -74,6 +74,8 @@ void Sample::resetCommonSettings() m_edgeMaxLen = 12.0f; m_edgeMaxError = 1.3f; m_vertsPerPoly = 6.0f; + m_detailSampleDist = 6.0f; + m_detailSampleMaxError = 1.0f; } void Sample::handleCommonSettings() @@ -106,6 +108,11 @@ void Sample::handleCommonSettings() imguiSlider("Max Edge Error", &m_edgeMaxError, 0.1f, 3.0f, 0.1f); imguiSlider("Verts Per Poly", &m_vertsPerPoly, 3.0f, 12.0f, 1.0f); + imguiSeparator(); + imguiLabel("Detail Mesh"); + imguiSlider("Sample Distance", &m_detailSampleDist, 0.0f, 16.0f, 1.0f); + imguiSlider("Max Sample Error", &m_detailSampleMaxError, 0.0f, 16.0f, 1.0f); + imguiSeparator(); } diff --git a/RecastDemo/Source/Sample_StatMesh.cpp b/RecastDemo/Source/Sample_StatMesh.cpp index a2c875f7..a172379c 100644 --- a/RecastDemo/Source/Sample_StatMesh.cpp +++ b/RecastDemo/Source/Sample_StatMesh.cpp @@ -219,14 +219,14 @@ void Sample_StatMesh::toolRender(int flags) } if (m_nstraightPath) { - glColor4ub(128,16,0,220); + glColor4ub(64,16,0,220); glLineWidth(3.0f); glBegin(GL_LINE_STRIP); for (int i = 0; i < m_nstraightPath; ++i) glVertex3f(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2]); glEnd(); glLineWidth(1.0f); - glPointSize(4.0f); + glPointSize(6.0f); glBegin(GL_POINTS); for (int i = 0; i < m_nstraightPath; ++i) glVertex3f(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2]); @@ -243,7 +243,7 @@ void Sample_StatMesh::toolRender(int flags) for (int i = 1; i < m_npolys; ++i) dtDebugDrawStatNavMeshPoly(m_navMesh, m_polys[i], pathCol); - glColor4ub(128,16,0,220); + glColor4ub(64,16,0,220); glLineWidth(3.0f); glBegin(GL_LINE_STRIP); for (int i = 0; i < m_nstraightPath; ++i) diff --git a/RecastDemo/Source/Sample_StatMeshSimple.cpp b/RecastDemo/Source/Sample_StatMeshSimple.cpp index 4b13c887..9452c61a 100644 --- a/RecastDemo/Source/Sample_StatMeshSimple.cpp +++ b/RecastDemo/Source/Sample_StatMeshSimple.cpp @@ -25,7 +25,8 @@ Sample_StatMeshSimple::Sample_StatMeshSimple() : m_solid(0), m_chf(0), m_cset(0), - m_polyMesh(0), + m_pmesh(0), + m_dmesh(0), m_drawMode(DRAWMODE_NAVMESH) { } @@ -45,8 +46,10 @@ void Sample_StatMeshSimple::cleanup() m_chf = 0; delete m_cset; m_cset = 0; - delete m_polyMesh; - m_polyMesh = 0; + delete m_pmesh; + m_pmesh = 0; + delete m_dmesh; + m_dmesh = 0; toolCleanup(); } @@ -83,7 +86,8 @@ void Sample_StatMeshSimple::handleDebugMode() valid[DRAWMODE_RAW_CONTOURS] = m_cset != 0; valid[DRAWMODE_BOTH_CONTOURS] = m_cset != 0; valid[DRAWMODE_CONTOURS] = m_cset != 0; - valid[DRAWMODE_POLYMESH] = m_polyMesh != 0; + valid[DRAWMODE_POLYMESH] = m_pmesh != 0; + valid[DRAWMODE_POLYMESH_DETAIL] = m_dmesh != 0; } int unavail = 0; @@ -124,6 +128,8 @@ void Sample_StatMeshSimple::handleDebugMode() m_drawMode = DRAWMODE_CONTOURS; if (imguiCheck("Poly Mesh", m_drawMode == DRAWMODE_POLYMESH, valid[DRAWMODE_POLYMESH])) m_drawMode = DRAWMODE_POLYMESH; + if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL])) + m_drawMode = DRAWMODE_POLYMESH_DETAIL; if (unavail) { @@ -198,20 +204,20 @@ void Sample_StatMeshSimple::handleRender() if (m_cset && m_drawMode == DRAWMODE_RAW_CONTOURS) { glDepthMask(GL_FALSE); - rcDebugDrawRawContours(*m_cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch); + rcDebugDrawRawContours(*m_cset); glDepthMask(GL_TRUE); } if (m_cset && m_drawMode == DRAWMODE_BOTH_CONTOURS) { glDepthMask(GL_FALSE); - rcDebugDrawRawContours(*m_cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch, 0.5f); - rcDebugDrawContours(*m_cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch); + rcDebugDrawRawContours(*m_cset, 0.5f); + rcDebugDrawContours(*m_cset); glDepthMask(GL_TRUE); } if (m_cset && m_drawMode == DRAWMODE_CONTOURS) { glDepthMask(GL_FALSE); - rcDebugDrawContours(*m_cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch); + rcDebugDrawContours(*m_cset); glDepthMask(GL_TRUE); } if (m_chf && m_cset && m_drawMode == DRAWMODE_REGION_CONNECTIONS) @@ -219,16 +225,22 @@ void Sample_StatMeshSimple::handleRender() rcDebugDrawCompactHeightfieldRegions(*m_chf); glDepthMask(GL_FALSE); - rcDebugDrawRegionConnections(*m_cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch); + rcDebugDrawRegionConnections(*m_cset); glDepthMask(GL_TRUE); } - if (m_polyMesh && m_drawMode == DRAWMODE_POLYMESH) + if (m_pmesh && m_drawMode == DRAWMODE_POLYMESH) { glDepthMask(GL_FALSE); - rcDebugDrawPolyMesh(*m_polyMesh); + rcDebugDrawPolyMesh(*m_pmesh); glDepthMask(GL_TRUE); } - + if (m_dmesh && m_drawMode == DRAWMODE_POLYMESH_DETAIL) + { + glDepthMask(GL_FALSE); + rcDebugDrawPolyMeshDetail(*m_dmesh); + glDepthMask(GL_TRUE); + } + static const float startCol[4] = { 0.5f, 0.1f, 0.0f, 0.75f }; static const float endCol[4] = { 0.2f, 0.4f, 0.0f, 0.75f }; if (m_sposSet) @@ -236,6 +248,7 @@ void Sample_StatMeshSimple::handleRender() if (m_eposSet) drawAgent(m_epos, m_agentRadius, m_agentHeight, m_agentMaxClimb, endCol); + glDepthMask(GL_TRUE); } void Sample_StatMeshSimple::handleRenderOverlay(double* proj, double* model, int* view) @@ -281,6 +294,8 @@ bool Sample_StatMeshSimple::handleBuild() m_cfg.minRegionSize = (int)rcSqr(m_regionMinSize); m_cfg.mergeRegionSize = (int)rcSqr(m_regionMergeSize); m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly; + m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist; + m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError; // Set the area where the navigation will be build. // Here the bounds of the input mesh are used, but the @@ -417,42 +432,56 @@ bool Sample_StatMeshSimple::handleBuild() return false; } - if (!m_keepInterResults) - { - delete m_chf; - m_chf = 0; - } - // // Step 6. Build polygons mesh from contours. // // Build polygon navmesh from the contours. - m_polyMesh = new rcPolyMesh; - if (!m_polyMesh) + m_pmesh = new rcPolyMesh; + if (!m_pmesh) { if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'polyMesh'."); + rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'."); return false; } - if (!rcBuildPolyMesh(*m_cset, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch, m_cfg.maxVertsPerPoly, *m_polyMesh)) + if (!rcBuildPolyMesh(*m_cset, m_cfg.maxVertsPerPoly, *m_pmesh)) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not triangulate contours."); return false; } + // + // Step 7. Create detail mesh which allows to access approximate height on each polygon. + // + + m_dmesh = new rcPolyMeshDetail; + if (!m_dmesh) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmdtl'."); + return false; + } + + if (!rcBuildPolyMeshDetail(*m_pmesh, *m_chf, m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, *m_dmesh)) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build detail mesh."); + } + if (!m_keepInterResults) { + delete m_chf; + m_chf = 0; delete m_cset; m_cset = 0; } - // At this point the navigation mesh data is ready, you can access it from m_polyMesh. + // At this point the navigation mesh data is ready, you can access it from m_pmesh. // See rcDebugDrawPolyMesh or dtCreateNavMeshData as examples how to access the data. // - // (Optional) Step 7. Create Detour data from detour poly mesh. + // (Optional) Step 8. Create Detour data from Recast poly mesh. // // The GUI may allow more max points per polygon than Detour can handle. @@ -461,9 +490,11 @@ bool Sample_StatMeshSimple::handleBuild() { unsigned char* navData = 0; int navDataSize = 0; - if (!dtCreateNavMeshData(m_polyMesh->verts, m_polyMesh->nverts, - m_polyMesh->polys, m_polyMesh->npolys, m_polyMesh->nvp, - m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch, &navData, &navDataSize)) + if (!dtCreateNavMeshData(m_pmesh->verts, m_pmesh->nverts, + m_pmesh->polys, m_pmesh->npolys, m_pmesh->nvp, + m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch, + m_dmesh->meshes, m_dmesh->verts, m_dmesh->nverts, m_dmesh->tris, m_dmesh->ntris, + &navData, &navDataSize)) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "Could not build Detour navmesh."); @@ -517,11 +548,10 @@ bool Sample_StatMeshSimple::handleBuild() rcGetLog()->log(RC_LOG_PROGRESS, " - trace: %.1fms (%.1f%%)", m_buildTimes.buildContoursTrace/1000.0f, m_buildTimes.buildContoursTrace*pc); rcGetLog()->log(RC_LOG_PROGRESS, " - simplify: %.1fms (%.1f%%)", m_buildTimes.buildContoursSimplify/1000.0f, m_buildTimes.buildContoursSimplify*pc); - rcGetLog()->log(RC_LOG_PROGRESS, "Fixup contours: %.1fms (%.1f%%)", m_buildTimes.fixupContours/1000.0f, m_buildTimes.fixupContours*pc); - rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh: %.1fms (%.1f%%)", m_buildTimes.buildPolymesh/1000.0f, m_buildTimes.buildPolymesh*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh Detail: %.1fms (%.1f%%)", m_buildTimes.buildDetailMesh/1000.0f, m_buildTimes.buildDetailMesh*pc); - rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_polyMesh->nverts, m_polyMesh->npolys); + rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_pmesh->nverts, m_pmesh->npolys); rcGetLog()->log(RC_LOG_PROGRESS, "TOTAL: %.1fms", rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f); } diff --git a/RecastDemo/Source/Sample_StatMeshTiled.cpp b/RecastDemo/Source/Sample_StatMeshTiled.cpp index 40f5f74b..2b45fc86 100644 --- a/RecastDemo/Source/Sample_StatMeshTiled.cpp +++ b/RecastDemo/Source/Sample_StatMeshTiled.cpp @@ -23,7 +23,8 @@ Sample_StatMeshTiled::Sample_StatMeshTiled() : m_keepInterResults(false), m_tileSize(64), m_chunkyMesh(0), - m_polyMesh(0), + m_pmesh(0), + m_dmesh(0), m_tileSet(0), m_statPolysPerTileSamples(0), m_statTimePerTileSamples(0), @@ -42,8 +43,10 @@ void Sample_StatMeshTiled::cleanup() m_chunkyMesh = 0; delete m_tileSet; m_tileSet = 0; - delete m_polyMesh; - m_polyMesh = 0; + delete m_pmesh; + m_pmesh = 0; + delete m_dmesh; + m_dmesh = 0; toolCleanup(); m_statTimePerTileSamples = 0; m_statPolysPerTileSamples = 0; @@ -84,6 +87,8 @@ void Sample_StatMeshTiled::handleDebugMode() bool hasChf = false; bool hasSolid = false; bool hasCset = false; + bool hasPmesh = false; + bool hasDmesh = false; if (m_tileSet) { for (int i = 0; i < m_tileSet->width*m_tileSet->height; ++i) @@ -91,8 +96,12 @@ void Sample_StatMeshTiled::handleDebugMode() if (m_tileSet->tiles[i].solid) hasSolid = true; if (m_tileSet->tiles[i].chf) hasChf = true; if (m_tileSet->tiles[i].cset) hasCset = true; + if (m_tileSet->tiles[i].pmesh) hasPmesh = true; + if (m_tileSet->tiles[i].dmesh) hasDmesh = true; } } + if (m_pmesh) hasPmesh = true; + if (m_dmesh) hasDmesh = true; if (m_verts && m_tris) { @@ -110,7 +119,8 @@ void Sample_StatMeshTiled::handleDebugMode() valid[DRAWMODE_RAW_CONTOURS] = hasCset; valid[DRAWMODE_BOTH_CONTOURS] = hasCset; valid[DRAWMODE_CONTOURS] = hasCset; - valid[DRAWMODE_POLYMESH] = m_polyMesh != 0; + valid[DRAWMODE_POLYMESH] = hasPmesh; + valid[DRAWMODE_POLYMESH_DETAIL] = hasDmesh; } int unavail = 0; @@ -151,6 +161,8 @@ void Sample_StatMeshTiled::handleDebugMode() m_drawMode = DRAWMODE_CONTOURS; if (imguiCheck("Poly Mesh", m_drawMode == DRAWMODE_POLYMESH, valid[DRAWMODE_POLYMESH])) m_drawMode = DRAWMODE_POLYMESH; + if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL])) + m_drawMode = DRAWMODE_POLYMESH_DETAIL; if (unavail) { @@ -295,7 +307,7 @@ void Sample_StatMeshTiled::handleRender() for (int i = 0; i < m_tileSet->width*m_tileSet->height; ++i) { if (m_tileSet->tiles[i].cset) - rcDebugDrawRawContours(*m_tileSet->tiles[i].cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch); + rcDebugDrawRawContours(*m_tileSet->tiles[i].cset); } glDepthMask(GL_TRUE); } @@ -306,8 +318,8 @@ void Sample_StatMeshTiled::handleRender() { if (m_tileSet->tiles[i].cset) { - rcDebugDrawRawContours(*m_tileSet->tiles[i].cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch, 0.5f); - rcDebugDrawContours(*m_tileSet->tiles[i].cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch); + rcDebugDrawRawContours(*m_tileSet->tiles[i].cset, 0.5f); + rcDebugDrawContours(*m_tileSet->tiles[i].cset); } } glDepthMask(GL_TRUE); @@ -318,7 +330,7 @@ void Sample_StatMeshTiled::handleRender() for (int i = 0; i < m_tileSet->width*m_tileSet->height; ++i) { if (m_tileSet->tiles[i].cset) - rcDebugDrawContours(*m_tileSet->tiles[i].cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch); + rcDebugDrawContours(*m_tileSet->tiles[i].cset); } glDepthMask(GL_TRUE); } @@ -334,14 +346,43 @@ void Sample_StatMeshTiled::handleRender() for (int i = 0; i < m_tileSet->width*m_tileSet->height; ++i) { if (m_tileSet->tiles[i].cset) - rcDebugDrawRegionConnections(*m_tileSet->tiles[i].cset, m_cfg.bmin, m_cfg.cs, m_cfg.ch); + rcDebugDrawRegionConnections(*m_tileSet->tiles[i].cset); } glDepthMask(GL_TRUE); } - if (m_polyMesh && m_drawMode == DRAWMODE_POLYMESH) + if (/*m_pmesh &&*/ m_drawMode == DRAWMODE_POLYMESH) { glDepthMask(GL_FALSE); - rcDebugDrawPolyMesh(*m_polyMesh); + if (m_pmesh) + { + rcDebugDrawPolyMesh(*m_pmesh); + } + else + { + for (int i = 0; i < m_tileSet->width*m_tileSet->height; ++i) + { + if (m_tileSet->tiles[i].pmesh) + rcDebugDrawPolyMesh(*m_tileSet->tiles[i].pmesh); + } + } + + glDepthMask(GL_TRUE); + } + if (/*m_dmesh &&*/ m_drawMode == DRAWMODE_POLYMESH_DETAIL) + { + glDepthMask(GL_FALSE); + if (m_dmesh) + { + rcDebugDrawPolyMeshDetail(*m_dmesh); + } + else + { + for (int i = 0; i < m_tileSet->width*m_tileSet->height; ++i) + { + if (m_tileSet->tiles[i].dmesh) + rcDebugDrawPolyMeshDetail(*m_tileSet->tiles[i].dmesh); + } + } glDepthMask(GL_TRUE); } } @@ -535,6 +576,8 @@ bool Sample_StatMeshTiled::handleBuild() m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly; m_cfg.tileSize = (int)m_tileSize; m_cfg.borderSize = m_cfg.walkableRadius*2 + 2; // Reserve enough padding. + m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist; + m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError; // Set the area where the navigation will be build. // Here the bounds of the input mesh are used, but the @@ -719,14 +762,6 @@ bool Sample_StatMeshTiled::handleBuild() continue; } - if (m_keepInterResults) - { - tile.solid = solid; - solid = 0; - tile.chf = chf; - chf = 0; - } - if (!cset->nconts) { delete cset; @@ -734,12 +769,63 @@ bool Sample_StatMeshTiled::handleBuild() continue; } - tile.cset = cset; - // Offset the vertices in the cset. - rcTranslateContours(tile.cset, x*tileCfg.tileSize - tileCfg.borderSize, 0, y*tileCfg.tileSize - tileCfg.borderSize); + tile.pmesh = new rcPolyMesh; + if (!tile.pmesh) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'pmesh'.", x, y); + continue; + } + if (!rcBuildPolyMesh(*cset, tileCfg.maxVertsPerPoly, *tile.pmesh)) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not create poly mesh.", x, y); + continue; + } + + tile.dmesh = new rcPolyMeshDetail; + if (!tile.dmesh) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Out of memory 'dmesh'.", x, y); + continue; + } + + if (!rcBuildPolyMeshDetail(*tile.pmesh, *chf, tileCfg.detailSampleDist, tileCfg .detailSampleMaxError, *tile.dmesh)) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build detail mesh.", x, y); + continue; + } + + if (m_keepInterResults) + { + tile.solid = solid; + solid = 0; + tile.chf = chf; + chf = 0; + tile.cset = cset; + cset = 0; + } rcTimeVal endTime = rcGetPerformanceTimer(); tile.buildTime += rcGetDeltaTimeUsec(startTime, endTime); + + // Some extra code to measure some per tile statistics, + // such as build time and how many polygons there are per tile. + if (tile.pmesh) + { + int bucket = tile.pmesh->npolys; + if (bucket < 0) bucket = 0; + if (bucket >= MAX_STAT_BUCKETS) bucket = MAX_STAT_BUCKETS-1; + m_statPolysPerTile[bucket]++; + m_statPolysPerTileSamples++; + } + int bucket = (tile.buildTime+500)/1000; + if (bucket < 0) bucket = 0; + if (bucket >= MAX_STAT_BUCKETS) bucket = MAX_STAT_BUCKETS-1; + m_statTimePerTile[bucket]++; + m_statTimePerTileSamples++; } } @@ -747,143 +833,58 @@ bool Sample_StatMeshTiled::handleBuild() delete solid; delete chf; - - // Some extra code to measure some per tile statistics, - // such as build time and how many polygons there are per tile. - if (m_measurePerTileTimings) + // Merge per tile poly and detail meshes. + rcPolyMesh** pmmerge = new rcPolyMesh*[m_tileSet->width*m_tileSet->height]; + if (!pmmerge) { - for (int y = 0; y < m_tileSet->height; ++y) - { - for (int x = 0; x < m_tileSet->width; ++x) - { - Tile& tile = m_tileSet->tiles[x + y*m_tileSet->width]; - - if (!tile.cset) - continue; - - rcTimeVal startTime = rcGetPerformanceTimer(); - rcPolyMesh* polyMesh = new rcPolyMesh; - if (!polyMesh) - continue; - if (rcBuildPolyMesh(*tile.cset, m_cfg.bmin, m_cfg.bmax, - m_cfg.cs, m_cfg.ch, m_cfg.maxVertsPerPoly, *polyMesh)) - { - int bucket = polyMesh->npolys; - if (bucket < 0) bucket = 0; - if (bucket >= MAX_STAT_BUCKETS) bucket = MAX_STAT_BUCKETS-1; - m_statPolysPerTile[bucket]++; - m_statPolysPerTileSamples++; - } - delete polyMesh; - - rcTimeVal endTime = rcGetPerformanceTimer(); - int time = tile.buildTime += rcGetDeltaTimeUsec(startTime, endTime); - - int bucket = (time+500)/1000; - if (bucket < 0) bucket = 0; - if (bucket >= MAX_STAT_BUCKETS) bucket = MAX_STAT_BUCKETS-1; - m_statTimePerTile[bucket]++; - m_statTimePerTileSamples++; - } - } - } - - // Make sure that the vertices along the tile edges match, - // so that they can be later properly stitched together. - for (int y = 0; y < m_tileSet->height; ++y) - { - for (int x = 0; x < m_tileSet->width; ++x) - { - rcTimeVal startTime = rcGetPerformanceTimer(); - if ((x+1) < m_tileSet->width) - { - if (!rcFixupAdjacentContours(m_tileSet->tiles[x + y*m_tileSet->width].cset, - m_tileSet->tiles[x+1 + y*m_tileSet->width].cset, - m_cfg.walkableClimb, (x+1)*m_cfg.tileSize, -1)) - { - if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not fixup x+1.", x, y); - return false; - } - } - - if ((y+1) < m_tileSet->height) - { - if (!rcFixupAdjacentContours(m_tileSet->tiles[x + y*m_tileSet->width].cset, - m_tileSet->tiles[x + (y+1)*m_tileSet->width].cset, - m_cfg.walkableClimb, -1, (y+1)*m_cfg.tileSize)) - { - if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not fixup y+1.", x, y); - return false; - } - } - rcTimeVal endTime = rcGetPerformanceTimer(); - m_tileSet->tiles[x+y*m_tileSet->width].buildTime += rcGetDeltaTimeUsec(startTime, endTime); - } + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'pmmerge' (%d).", m_tileSet->width*m_tileSet->height); + return false; } - - - // Combine contours. - rcContourSet combSet; - combSet.nconts = 0; + rcPolyMeshDetail** dmmerge = new rcPolyMeshDetail*[m_tileSet->width*m_tileSet->height]; + if (!dmmerge) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'dmmerge' (%d).", m_tileSet->width*m_tileSet->height); + return false; + } + + int nmerge = 0; for (int y = 0; y < m_tileSet->height; ++y) { for (int x = 0; x < m_tileSet->width; ++x) { Tile& tile = m_tileSet->tiles[x + y*m_tileSet->width]; - if (!tile.cset) continue; - combSet.nconts += tile.cset->nconts; - } - } - combSet.conts = new rcContour[combSet.nconts]; - if (!combSet.conts) - { - if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'combSet.conts' (%d).", combSet.nconts); - return false; - } - int n = 0; - for (int y = 0; y < m_tileSet->height; ++y) - { - for (int x = 0; x < m_tileSet->width; ++x) - { - Tile& tile = m_tileSet->tiles[x + y*m_tileSet->width]; - if (!tile.cset) continue; - for (int i = 0; i < tile.cset->nconts; ++i) + if (tile.pmesh) { - combSet.conts[n].verts = tile.cset->conts[i].verts; - combSet.conts[n].nverts = tile.cset->conts[i].nverts; - combSet.conts[n].reg = tile.cset->conts[i].reg; - n++; + pmmerge[nmerge] = tile.pmesh; + dmmerge[nmerge] = tile.dmesh; + nmerge++; } } } - m_polyMesh = new rcPolyMesh; - if (!m_polyMesh) + m_pmesh = new rcPolyMesh; + if (!m_pmesh) { if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'polyMesh'."); + rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'."); return false; } + rcMergePolyMeshes(pmmerge, nmerge, *m_pmesh); - bool polyRes = rcBuildPolyMesh(combSet, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch, m_cfg.maxVertsPerPoly, *m_polyMesh); - - // Remove vertex binding to avoid double deletion. - for (int i = 0; i < combSet.nconts; ++i) + m_dmesh = new rcPolyMeshDetail; + if (!m_dmesh) { - combSet.conts[i].verts = 0; - combSet.conts[i].nverts = 0; - } - - if (!polyRes) - { if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not triangulate contours."); + rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'dmesh'."); return false; } + rcMergePolyMeshDetails(dmmerge, nmerge, *m_dmesh); + + delete [] pmmerge; + delete [] dmmerge; if (!m_keepInterResults) { @@ -894,17 +895,23 @@ bool Sample_StatMeshTiled::handleBuild() Tile& tile = m_tileSet->tiles[x + y*m_tileSet->width]; delete tile.cset; tile.cset = 0; + delete tile.pmesh; + tile.pmesh = 0; + delete tile.dmesh; + tile.dmesh = 0; } } } - if (m_cfg.maxVertsPerPoly <= DT_STAT_VERTS_PER_POLYGON) + if (m_pmesh && m_cfg.maxVertsPerPoly <= DT_STAT_VERTS_PER_POLYGON) { unsigned char* navData = 0; int navDataSize = 0; - if (!dtCreateNavMeshData(m_polyMesh->verts, m_polyMesh->nverts, - m_polyMesh->polys, m_polyMesh->npolys, m_polyMesh->nvp, - m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch, &navData, &navDataSize)) + if (!dtCreateNavMeshData(m_pmesh->verts, m_pmesh->nverts, + m_pmesh->polys, m_pmesh->npolys, m_pmesh->nvp, + m_pmesh->bmin, m_pmesh->bmax, m_pmesh->cs, m_pmesh->ch, + m_dmesh->meshes, m_dmesh->verts, m_dmesh->nverts, m_dmesh->tris, m_dmesh->ntris, + &navData, &navDataSize)) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "Could not build Detour navmesh."); @@ -958,11 +965,13 @@ bool Sample_StatMeshTiled::handleBuild() rcGetLog()->log(RC_LOG_PROGRESS, " - trace: %.1fms (%.1f%%)", m_buildTimes.buildContoursTrace/1000.0f, m_buildTimes.buildContoursTrace*pc); rcGetLog()->log(RC_LOG_PROGRESS, " - simplify: %.1fms (%.1f%%)", m_buildTimes.buildContoursSimplify/1000.0f, m_buildTimes.buildContoursSimplify*pc); - rcGetLog()->log(RC_LOG_PROGRESS, "Fixup contours: %.1fms (%.1f%%)", m_buildTimes.fixupContours/1000.0f, m_buildTimes.fixupContours*pc); - rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh: %.1fms (%.1f%%)", m_buildTimes.buildPolymesh/1000.0f, m_buildTimes.buildPolymesh*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh Detail: %.1fms (%.1f%%)", m_buildTimes.buildDetailMesh/1000.0f, m_buildTimes.buildDetailMesh*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Merge Polymeshes: %.1fms (%.1f%%)", m_buildTimes.mergePolyMesh/1000.0f, m_buildTimes.mergePolyMesh*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Merge Polymesh Details: %.1fms (%.1f%%)", m_buildTimes.mergePolyMeshDetail/1000.0f, m_buildTimes.mergePolyMeshDetail*pc); - rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_polyMesh->nverts, m_polyMesh->npolys); + if (m_pmesh) + rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_pmesh->nverts, m_pmesh->npolys); rcGetLog()->log(RC_LOG_PROGRESS, "TOTAL: %.1fms", rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f); } diff --git a/RecastDemo/Source/Sample_TileMesh.cpp b/RecastDemo/Source/Sample_TileMesh.cpp index 1c41e390..0cf03fef 100644 --- a/RecastDemo/Source/Sample_TileMesh.cpp +++ b/RecastDemo/Source/Sample_TileMesh.cpp @@ -45,7 +45,8 @@ Sample_TileMesh::Sample_TileMesh() : m_solid(0), m_chf(0), m_cset(0), - m_polyMesh(0), + m_pmesh(0), + m_dmesh(0), m_tileSize(32), m_sposSet(false), m_eposSet(false), @@ -84,8 +85,10 @@ void Sample_TileMesh::cleanup() m_chf = 0; delete m_cset; m_cset = 0; - delete m_polyMesh; - m_polyMesh = 0; + delete m_pmesh; + m_pmesh = 0; + delete m_dmesh; + m_dmesh = 0; } void Sample_TileMesh::handleSettings() @@ -299,28 +302,32 @@ void Sample_TileMesh::handleRender() if (m_sposSet) { const float s = 0.5f; - glColor4ub(128,0,0,255); + glColor4ub(64,16,0,255); + glLineWidth(3.0f); glBegin(GL_LINES); - glVertex3f(m_spos[0]-s,m_spos[1],m_spos[2]); - glVertex3f(m_spos[0]+s,m_spos[1],m_spos[2]); - glVertex3f(m_spos[0],m_spos[1]-s,m_spos[2]); - glVertex3f(m_spos[0],m_spos[1]+s,m_spos[2]); - glVertex3f(m_spos[0],m_spos[1],m_spos[2]-s); - glVertex3f(m_spos[0],m_spos[1],m_spos[2]+s); + glVertex3f(m_spos[0]-s,m_spos[1]+m_cellHeight,m_spos[2]); + glVertex3f(m_spos[0]+s,m_spos[1]+m_cellHeight,m_spos[2]); + glVertex3f(m_spos[0],m_spos[1]-s+m_cellHeight,m_spos[2]); + glVertex3f(m_spos[0],m_spos[1]+s+m_cellHeight,m_spos[2]); + glVertex3f(m_spos[0],m_spos[1]+m_cellHeight,m_spos[2]-s); + glVertex3f(m_spos[0],m_spos[1]+m_cellHeight,m_spos[2]+s); glEnd(); + glLineWidth(1.0f); } if (m_eposSet) { const float s = 0.5f; - glColor4ub(0,128,0,255); + glColor4ub(16,64,0,255); + glLineWidth(3.0f); glBegin(GL_LINES); - glVertex3f(m_epos[0]-s,m_epos[1],m_epos[2]); - glVertex3f(m_epos[0]+s,m_epos[1],m_epos[2]); - glVertex3f(m_epos[0],m_epos[1]-s,m_epos[2]); - glVertex3f(m_epos[0],m_epos[1]+s,m_epos[2]); - glVertex3f(m_epos[0],m_epos[1],m_epos[2]-s); - glVertex3f(m_epos[0],m_epos[1],m_epos[2]+s); + glVertex3f(m_epos[0]-s,m_epos[1]+m_cellHeight,m_epos[2]); + glVertex3f(m_epos[0]+s,m_epos[1]+m_cellHeight,m_epos[2]); + glVertex3f(m_epos[0],m_epos[1]-s+m_cellHeight,m_epos[2]); + glVertex3f(m_epos[0],m_epos[1]+s+m_cellHeight,m_epos[2]); + glVertex3f(m_epos[0],m_epos[1]+m_cellHeight,m_epos[2]-s); + glVertex3f(m_epos[0],m_epos[1]+m_cellHeight,m_epos[2]+s); glEnd(); + glLineWidth(1.0f); } static const float startCol[4] = { 0.5f, 0.1f, 0.0f, 0.75f }; @@ -339,7 +346,7 @@ void Sample_TileMesh::handleRender() } if (m_nstraightPath) { - glColor4ub(128,16,0,220); + glColor4ub(64,16,0,220); glLineWidth(3.0f); glBegin(GL_LINE_STRIP); for (int i = 0; i < m_nstraightPath; ++i) @@ -363,7 +370,7 @@ void Sample_TileMesh::handleRender() for (int i = 1; i < m_npolys; ++i) dtDebugDrawTiledNavMeshPoly(m_navMesh, m_polys[i], pathCol); - glColor4ub(128,16,0,220); + glColor4ub(64,16,0,220); glLineWidth(3.0f); glBegin(GL_LINE_STRIP); for (int i = 0; i < m_nstraightPath; ++i) @@ -607,11 +614,8 @@ unsigned char* Sample_TileMesh::buildTileMesh(const float* bmin, const float* bm m_cfg.borderSize = m_cfg.walkableRadius*2 + 2; // Reserve enough padding. m_cfg.width = m_cfg.tileSize + m_cfg.borderSize*2; m_cfg.height = m_cfg.tileSize + m_cfg.borderSize*2; - -/* if (m_cfg.maxVertsPerPoly == DT_VERTS_PER_POLYGON) - m_drawMode = DRAWMODE_NAVMESH; - else - m_drawMode = DRAWMODE_POLYMESH;*/ + m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist; + m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError; vcopy(m_cfg.bmin, bmin); vcopy(m_cfg.bmax, bmax); @@ -754,29 +758,43 @@ unsigned char* Sample_TileMesh::buildTileMesh(const float* bmin, const float* bm return 0; } - if (!m_keepInterResults) - { - delete m_chf; - m_chf = 0; - } - // Build polygon navmesh from the contours. - m_polyMesh = new rcPolyMesh; - if (!m_polyMesh) + m_pmesh = new rcPolyMesh; + if (!m_pmesh) { if (rcGetLog()) - rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'polyMesh'."); + rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'."); return 0; } - if (!rcBuildPolyMesh(*m_cset, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch, m_cfg.maxVertsPerPoly, *m_polyMesh)) + if (!rcBuildPolyMesh(*m_cset, m_cfg.maxVertsPerPoly, *m_pmesh)) { if (rcGetLog()) rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not triangulate contours."); return 0; } + + // Build detail mesh. + m_dmesh = new rcPolyMeshDetail; + if (!m_dmesh) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'dmesh'."); + return 0; + } + + if (!rcBuildPolyMeshDetail(*m_pmesh, *m_chf, + m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, + *m_dmesh)) + { + if (rcGetLog()) + rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could build polymesh detail."); + return 0; + } if (!m_keepInterResults) { + delete m_chf; + m_chf = 0; delete m_cset; m_cset = 0; } @@ -785,16 +803,17 @@ unsigned char* Sample_TileMesh::buildTileMesh(const float* bmin, const float* bm int navDataSize = 0; if (m_cfg.maxVertsPerPoly == DT_TILE_VERTS_PER_POLYGON) { - // Remove padding from the polymesh data. - for (int i = 0; i < m_polyMesh->nverts; ++i) + // Remove padding from the polymesh data. TODO: Remove this odditity. + for (int i = 0; i < m_pmesh->nverts; ++i) { - unsigned short* v = &m_polyMesh->verts[i*3]; + unsigned short* v = &m_pmesh->verts[i*3]; v[0] -= (unsigned short)m_cfg.borderSize; v[2] -= (unsigned short)m_cfg.borderSize; } - if (!dtCreateNavMeshTileData(m_polyMesh->verts, m_polyMesh->nverts, - m_polyMesh->polys, m_polyMesh->npolys, m_polyMesh->nvp, + if (!dtCreateNavMeshTileData(m_pmesh->verts, m_pmesh->nverts, + m_pmesh->polys, m_pmesh->npolys, m_pmesh->nvp, + m_dmesh->meshes, m_dmesh->verts, m_dmesh->nverts, m_dmesh->tris, m_dmesh->ntris, bmin, bmax, m_cfg.cs, m_cfg.ch, m_cfg.tileSize, m_cfg.walkableClimb, &navData, &navDataSize)) { if (rcGetLog()) @@ -833,11 +852,15 @@ unsigned char* Sample_TileMesh::buildTileMesh(const float* bmin, const float* bm rcGetLog()->log(RC_LOG_PROGRESS, " - trace: %.1fms (%.1f%%)", m_buildTimes.buildContoursTrace/1000.0f, m_buildTimes.buildContoursTrace*pc); rcGetLog()->log(RC_LOG_PROGRESS, " - simplify: %.1fms (%.1f%%)", m_buildTimes.buildContoursSimplify/1000.0f, m_buildTimes.buildContoursSimplify*pc); - rcGetLog()->log(RC_LOG_PROGRESS, "Fixup contours: %.1fms (%.1f%%)", m_buildTimes.fixupContours/1000.0f, m_buildTimes.fixupContours*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh: %.1fms (%.1f%%)", m_buildTimes.buildPolymesh/1000.0f, m_buildTimes.buildPolymesh*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh Detail: %.1fms (%.1f%%)", m_buildTimes.buildDetailMesh/1000.0f, m_buildTimes.buildDetailMesh*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Merge Polymeshes: %.1fms (%.1f%%)", m_buildTimes.mergePolyMesh/1000.0f, m_buildTimes.mergePolyMesh*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Merge Polymesh Details: %.1fms (%.1f%%)", m_buildTimes.mergePolyMeshDetail/1000.0f, m_buildTimes.mergePolyMeshDetail*pc); + rcGetLog()->log(RC_LOG_PROGRESS, "Build Polymesh: %.1fms (%.1f%%)", m_buildTimes.buildPolymesh/1000.0f, m_buildTimes.buildPolymesh*pc); - rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_polyMesh->nverts, m_polyMesh->npolys); + rcGetLog()->log(RC_LOG_PROGRESS, "Polymesh: Verts:%d Polys:%d", m_pmesh->nverts, m_pmesh->npolys); rcGetLog()->log(RC_LOG_PROGRESS, "TOTAL: %.1fms", rcGetDeltaTimeUsec(totStartTime, totEndTime)/1000.0f); } diff --git a/RecastDemo/Source/imgui.cpp b/RecastDemo/Source/imgui.cpp index 4f6140af..831f4d75 100644 --- a/RecastDemo/Source/imgui.cpp +++ b/RecastDemo/Source/imgui.cpp @@ -132,7 +132,7 @@ struct GuiState mx(-1), my(-1), scroll(0), active(0), hot(0), hotToBe(0), isHot(false), isActive(false), wentActive(false), dragX(0), dragY(0), dragOrig(0), widgetX(0), widgetY(0), widgetW(100), - areaId(0), widgetId(0) + insideCurrentScroll(false), areaId(0), widgetId(0) { } @@ -149,6 +149,7 @@ struct GuiState int dragX, dragY; float dragOrig; int widgetX, widgetY, widgetW; + bool insideCurrentScroll; unsigned int areaId; unsigned int widgetId; @@ -171,9 +172,9 @@ inline bool isHot(unsigned int id) return g_state.hot == id; } -inline bool inRect(int x, int y, int w, int h) +inline bool inRect(int x, int y, int w, int h, bool checkScroll = true) { - return g_state.mx >= x && g_state.mx <= x+w && g_state.my >= y && g_state.my <= y+h; + return (!checkScroll || g_state.insideCurrentScroll) && g_state.mx >= x && g_state.mx <= x+w && g_state.my >= y && g_state.my <= y+h; } inline void clearInput() @@ -324,14 +325,15 @@ bool imguiBeginScrollArea(const char* name, int x, int y, int w, int h, int* scr g_focusTop = y-AREA_HEADER; g_focusBottom = y-AREA_HEADER+h; + g_insideScrollArea = inRect(x, y, w, h, false); + g_state.insideCurrentScroll = g_insideScrollArea; + addGfxCmdRoundedRect(x, y, w, h, 6, imguiRGBA(0,0,0,192)); addGfxCmdText(x+AREA_HEADER/2, y+h-AREA_HEADER/2-TEXT_HEIGHT/2, IMGUI_ALIGN_LEFT, name, imguiRGBA(255,255,255,128)); addGfxCmdScissor(x+SCROLL_AREA_PADDING, y+SCROLL_AREA_PADDING, w-SCROLL_AREA_PADDING*4, h-AREA_HEADER-SCROLL_AREA_PADDING); - g_insideScrollArea = inRect(x, y, w, h); - return g_insideScrollArea; } @@ -403,8 +405,8 @@ void imguiEndScrollArea() if (*g_scrollVal > (sh - h)) *g_scrollVal = (sh - h); } } - } + g_state.insideCurrentScroll = false; } bool imguiButton(const char* text, bool enabled)