Added option to tesselate edges between areas. Fixed bug in orphan contour merging, which could create overlapping contour.

This commit is contained in:
Mikko Mononen 2010-05-26 09:20:57 +00:00
parent 49f2b03cd8
commit 11386cedcf
10 changed files with 3285 additions and 1821 deletions

View File

@ -160,7 +160,7 @@ struct rcContourSet
// z = bmin[2] + verts[i*3+2]*cs;
struct rcPolyMesh
{
inline rcPolyMesh() : verts(0), polys(0), regs(0), flags(0), areas(0), nverts(0), npolys(0), nvp(3) {}
inline rcPolyMesh() : verts(0), polys(0), regs(0), flags(0), areas(0), nverts(0), npolys(0), maxpolys(0), nvp(3) {}
inline ~rcPolyMesh() { delete [] verts; delete [] polys; delete [] regs; delete [] flags; delete [] areas; }
@ -171,6 +171,7 @@ struct rcPolyMesh
unsigned char* areas; // Area ID of polygons.
int nverts; // Number of vertices.
int npolys; // Number of polygons.
int maxpolys; // Number of allocated polygons.
int nvp; // Max number of vertices per polygon.
float bmin[3], bmax[3]; // Bounding box of the mesh.
float cs, ch; // Cell size and height.
@ -250,6 +251,12 @@ static const int RC_BORDER_VERTEX = 0x10000;
static const int RC_AREA_BORDER = 0x20000;
enum rcBuildContoursFlags
{
RC_CONTOUR_TESS_WALL_EDGES = 0x01, // Tesselate wall edges
RC_CONTOUR_TESS_AREA_EDGES = 0x02, // Tesselate edges between areas.
};
// Mask used with contours to extract region id.
static const int RC_CONTOUR_REG_MASK = 0xffff;
@ -552,7 +559,6 @@ void rcMarkConvexPolyArea(const float* verts, const int nverts,
const float hmin, const float hmax, unsigned char areaId,
rcCompactHeightfield& chf);
// Builds distance field and stores it into the combat heightfield.
// Params:
// chf - (in/out) compact heightfield representing the open space.
@ -573,7 +579,7 @@ bool rcBuildDistanceField(rcCompactHeightfield& chf);
// maxMergeRegionSize - (in) the largest allowed regions size which can be merged.
// Returns false if operation ran out of memory.
bool rcBuildRegions(rcCompactHeightfield& chf,
int borderSize, int minRegionSize, int mergeRegionSize);
const int borderSize, const int minRegionSize, const int mergeRegionSize);
// Divides the walkable heighfied into simple regions using simple monotone partitioning.
// Each region has only one contour and no overlaps.
@ -589,7 +595,7 @@ bool rcBuildRegions(rcCompactHeightfield& chf,
// maxMergeRegionSize - (in) the largest allowed regions size which can be merged.
// Returns false if operation ran out of memory.
bool rcBuildRegionsMonotone(rcCompactHeightfield& chf,
int borderSize, int minRegionSize, int mergeRegionSize);
const int borderSize, const int minRegionSize, const int mergeRegionSize);
// Builds simplified contours from the regions outlines.
// Params:
@ -597,10 +603,11 @@ bool rcBuildRegionsMonotone(rcCompactHeightfield& chf,
// maxError - (in) maximum allowed distance between simplified countour and cells.
// maxEdgeLen - (in) maximum allowed contour edge length in cells.
// cset - (out) Resulting contour set.
// flags - (in) build flags, see rcBuildContoursFlags.
// Returns false if operation ran out of memory.
bool rcBuildContours(rcCompactHeightfield& chf,
const float maxError, const int maxEdgeLen,
rcContourSet& cset);
rcContourSet& cset, const int flags = RC_CONTOUR_TESS_WALL_EDGES);
// Builds connected convex polygon mesh from contour polygons.
// Params:

View File

@ -321,6 +321,4 @@ void rcMarkConvexPolyArea(const float* verts, const int nverts,
}
}
}

View File

@ -227,7 +227,8 @@ static float distancePtSeg(const int x, const int z,
return dx*dx + dz*dz;
}
static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float maxError, int maxEdgeLen)
static void simplifyContour(rcIntArray& points, rcIntArray& simplified,
const float maxError, const int maxEdgeLen, const int buildFlags)
{
// Add initial points.
bool noConnections = true;
@ -382,7 +383,7 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
}
// Split too long edges.
if (maxEdgeLen > 0)
if (maxEdgeLen > 0 && (buildFlags & (RC_CONTOUR_TESS_WALL_EDGES|RC_CONTOUR_TESS_AREA_EDGES)) != 0)
{
for (int i = 0; i < simplified.size()/4; )
{
@ -395,20 +396,39 @@ static void simplifyContour(rcIntArray& points, rcIntArray& simplified, float ma
const int bx = simplified[ii*4+0];
const int bz = simplified[ii*4+2];
const int bi = simplified[ii*4+3];
// Find maximum deviation from the segment.
int maxi = -1;
int ci = (ai+1) % pn;
// Tesselate only outer edges or edges between areas.
bool tess = false;
// Wall edges.
if ((buildFlags & RC_CONTOUR_TESS_WALL_EDGES) && (points[ci*4+3] & RC_CONTOUR_REG_MASK) == 0)
tess = true;
// Edges between areas.
if ((buildFlags & RC_CONTOUR_TESS_AREA_EDGES) && (points[ci*4+3] & RC_AREA_BORDER))
tess = true;
// Tesselate only outer edges.
if ((points[ci*4+3] & RC_CONTOUR_REG_MASK) == 0)
if (tess)
{
int dx = bx - ax;
int dz = bz - az;
if (dx*dx + dz*dz > maxEdgeLen*maxEdgeLen)
{
int n = bi < ai ? (bi+pn - ai) : (bi - ai);
maxi = (ai + n/2) % pn;
// Round based on the segments in lexilogical order so that the
// max tesselation is consistent regardles in which direction
// segments are traversed.
if (bx > ax || (bx == ax && bz > az))
{
const int n = bi < ai ? (bi+pn - ai) : (bi - ai);
maxi = (ai + n/2) % pn;
}
else
{
const int n = bi < ai ? (bi+pn - ai) : (bi - ai);
maxi = (ai + (n+1)/2) % pn;
}
}
}
@ -488,25 +508,40 @@ static int calcAreaOfPolygon2D(const int* verts, const int nverts)
return (area+1) / 2;
}
inline bool ileft(const int* a, const int* b, const int* c)
{
return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]) <= 0;
}
static void getClosestIndices(const int* vertsa, const int nvertsa,
const int* vertsb, const int nvertsb,
int& ia, int& ib)
{
int closestDist = 0xfffffff;
ia = -1, ib = -1;
for (int i = 0; i < nvertsa; ++i)
{
const int in = (i+1) % nvertsa;
const int ip = (i+nvertsa-1) % nvertsa;
const int* va = &vertsa[i*4];
const int* van = &vertsa[in*4];
const int* vap = &vertsa[ip*4];
for (int j = 0; j < nvertsb; ++j)
{
const int* vb = &vertsb[j*4];
const int dx = vb[0] - va[0];
const int dz = vb[2] - va[2];
const int d = dx*dx + dz*dz;
if (d < closestDist)
// vb must be "infront" of va.
if (ileft(vap,va,vb) && ileft(va,van,vb))
{
ia = i;
ib = j;
closestDist = d;
const int dx = vb[0] - va[0];
const int dz = vb[2] - va[2];
const int d = dx*dx + dz*dz;
if (d < closestDist)
{
ia = i;
ib = j;
closestDist = d;
}
}
}
}
@ -558,7 +593,7 @@ static bool mergeContours(rcContour& ca, rcContour& cb, int ia, int ib)
bool rcBuildContours(rcCompactHeightfield& chf,
const float maxError, const int maxEdgeLen,
rcContourSet& cset)
rcContourSet& cset, const int buildFlags)
{
const int w = chf.width;
const int h = chf.height;
@ -647,7 +682,7 @@ bool rcBuildContours(rcCompactHeightfield& chf,
verts.resize(0);
simplified.resize(0);
walkContour(x, y, i, chf, flags, verts);
simplifyContour(verts, simplified, maxError, maxEdgeLen);
simplifyContour(verts, simplified, maxError, maxEdgeLen, buildFlags);
removeDegenerateSegments(simplified);
// Store region->contour remap info.
@ -738,10 +773,17 @@ bool rcBuildContours(rcCompactHeightfield& chf,
// Merge by closest points.
int ia = 0, ib = 0;
getClosestIndices(mcont.verts, mcont.nverts, cont.verts, cont.nverts, ia, ib);
if (ia == -1 || ib == -1)
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_WARNING, "rcBuildContours: Failed to find merge points for %d and %d.", i, mergeIdx);
continue;
}
if (!mergeContours(mcont, cont, ia, ib))
{
if (rcGetLog())
rcGetLog()->log(RC_LOG_WARNING, "rcBuildContours: Failed to merge contours %d and %d.", i, mergeIdx);
continue;
}
}
}

View File

@ -494,15 +494,19 @@ static int removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int ma
for (int i = 0; i < mesh.npolys; ++i)
{
unsigned short* p = &mesh.polys[i*nvp*2];
for (int j = 0; j < nvp; ++j)
const int nv = countPolyVerts(p, nvp);
int numRemoved = 0;
int numVerts = 0;
for (int j = 0; j < nv; ++j)
{
if (p[j] == RC_MESH_NULL_IDX) break;
numRemainingEdges++;
if (p[j] == rem)
{
numRemovedVerts++;
numRemainingEdges -= 2;
}
numRemoved++;
numVerts++;
}
if (numRemoved)
{
numRemovedVerts += numRemoved;
numRemainingEdges += numVerts-(numRemoved+1);
}
}
@ -574,6 +578,7 @@ static int removeVertex(rcPolyMesh& mesh, const unsigned short rem, const int ma
// Remove the polygon.
unsigned short* p2 = &mesh.polys[(mesh.npolys-1)*nvp*2];
memcpy(p,p2,sizeof(unsigned short)*nvp);
memset(p+nvp,0xff,sizeof(unsigned short)*nvp);
mesh.regs[i] = mesh.regs[mesh.npolys-1];
mesh.areas[i] = mesh.areas[mesh.npolys-1];
mesh.npolys--;
@ -884,6 +889,7 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
mesh.nverts = 0;
mesh.npolys = 0;
mesh.nvp = nvp;
mesh.maxpolys = maxTris;
memset(mesh.verts, 0, sizeof(unsigned short)*maxVertices*3);
memset(mesh.polys, 0xff, sizeof(unsigned short)*maxTris*nvp*2);
@ -948,18 +954,16 @@ bool rcBuildPolyMesh(rcContourSet& cset, int nvp, rcPolyMesh& mesh)
if (ntris <= 0)
{
// Bad triangulation, should not happen.
/* for (int k = 0; k < cont.nverts; ++k)
/* printf("\tconst float bmin[3] = {%ff,%ff,%ff};\n", cset.bmin[0], cset.bmin[1], cset.bmin[2]);
printf("\tconst float cs = %ff;\n", cset.cs);
printf("\tconst float ch = %ff;\n", cset.ch);
printf("\tconst int verts[] = {\n");
for (int k = 0; k < cont.nverts; ++k)
{
const int* v = &cont.verts[k*4];
printf("\t\t%d,%d,%d,%d,\n", v[0], v[1], v[2], v[3]);
if (nBadPos < 100)
{
badPos[nBadPos*3+0] = v[0];
badPos[nBadPos*3+1] = v[1];
badPos[nBadPos*3+2] = v[2];
nBadPos++;
}
}*/
}
printf("\t};\n\tconst int nverts = sizeof(verts)/(sizeof(int)*4);\n");*/
ntris = -ntris;
}

View File

@ -983,7 +983,7 @@ struct rcSweepSpan
};
bool rcBuildRegionsMonotone(rcCompactHeightfield& chf,
int borderSize, int minRegionSize, int mergeRegionSize)
const int borderSize, const int minRegionSize, const int mergeRegionSize)
{
rcTimeVal startTime = rcGetPerformanceTimer();
@ -1134,7 +1134,7 @@ bool rcBuildRegionsMonotone(rcCompactHeightfield& chf,
}
bool rcBuildRegions(rcCompactHeightfield& chf,
int borderSize, int minRegionSize, int mergeRegionSize)
const int borderSize, const int minRegionSize, const int mergeRegionSize)
{
rcTimeVal startTime = rcGetPerformanceTimer();

File diff suppressed because it is too large Load Diff

View File

@ -282,13 +282,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array>
<array>
<integer>46</integer>
<integer>21</integer>
<integer>20</integer>
<integer>1</integer>
<integer>0</integer>
</array>
</array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 348}, {264, 643}}</string>
<string>{{0, 167}, {264, 643}}</string>
</dict>
<key>PBXTopSmartGroupGIDs</key>
<array/>
@ -323,7 +324,7 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>main.cpp</string>
<string>Sample_TileMesh.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key>
<dict>
<key>Split0</key>
@ -331,11 +332,11 @@
<key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key>
<string>main.cpp</string>
<string>Sample_TileMesh.cpp</string>
<key>_historyCapacity</key>
<integer>0</integer>
<key>bookmark</key>
<string>6B5562FE1193F50A00843384</string>
<string>6B10017F11AD1F0E0098A59A</string>
<key>history</key>
<array>
<string>6BBB4A96115B4F3400CF791D</string>
@ -348,9 +349,7 @@
<string>6BBB4AB2115B4F3400CF791D</string>
<string>6BBB4ABB115B4F3400CF791D</string>
<string>6BBB4ABF115B4F3400CF791D</string>
<string>6BBB4AC2115B4F3400CF791D</string>
<string>6BBB4AC4115B4F3400CF791D</string>
<string>6BBB4AC6115B4F3400CF791D</string>
<string>6BBB4ACB115B4F3400CF791D</string>
<string>6BBB4ACD115B4F3400CF791D</string>
<string>6BBB4B7F115B639200CF791D</string>
@ -363,17 +362,12 @@
<string>6BF5F2E711748884000502A6</string>
<string>6BF5F31C117490A1000502A6</string>
<string>6BF5F32E11759C3C000502A6</string>
<string>6BF5F32F11759C3C000502A6</string>
<string>6BF5F33111759C3C000502A6</string>
<string>6BF5F474117644A2000502A6</string>
<string>6BF5F475117644A2000502A6</string>
<string>6BF5F476117644A2000502A6</string>
<string>6BF5F477117644A2000502A6</string>
<string>6BF5F478117644A2000502A6</string>
<string>6BF5F47E117644A2000502A6</string>
<string>6BF5F47F117644A2000502A6</string>
<string>6BF5F5041176F5F8000502A6</string>
<string>6BF5F5051176F5F8000502A6</string>
<string>6BF5F50D1176F5F8000502A6</string>
<string>6B4214AB11802FAA006C347B</string>
<string>6B4214AD11802FAA006C347B</string>
@ -382,26 +376,35 @@
<string>6B6F8E2311837A7400A069D7</string>
<string>6B6F8E2411837A7400A069D7</string>
<string>6B6F8E2511837A7400A069D7</string>
<string>6B555F431191AA4400843384</string>
<string>6B555F441191AA4400843384</string>
<string>6B555F451191AA4400843384</string>
<string>6B55622C119305F200843384</string>
<string>6B55623D1193E79A00843384</string>
<string>6B5562501193EF2F00843384</string>
<string>6B5562511193EF2F00843384</string>
<string>6B5562531193EF2F00843384</string>
<string>6B5562541193EF2F00843384</string>
<string>6B5562841193EFC500843384</string>
<string>6B5562D41193F20700843384</string>
<string>6B5562D51193F20700843384</string>
<string>6B5562DF1193F2A300843384</string>
<string>6B5562E01193F2A300843384</string>
<string>6B5562E11193F2A300843384</string>
<string>6B5562F21193F4CC00843384</string>
<string>6B5562F31193F4CC00843384</string>
<string>6B5562F41193F4CC00843384</string>
<string>6B5562FB1193F50A00843384</string>
<string>6B5562FC1193F50A00843384</string>
<string>6B5564031194187500843384</string>
<string>6B2CDC911197F0720090FA4D</string>
<string>6B2CDD23119804010090FA4D</string>
<string>6B2CDD3211980B820090FA4D</string>
<string>6B2CDD6111980E3D0090FA4D</string>
<string>6B2CDD6C119810560090FA4D</string>
<string>6B2CDD94119818F90090FA4D</string>
<string>6B2CDDC9119830560090FA4D</string>
<string>6B57E96B11A7695700614060</string>
<string>6B10000A11ACFFFB0098A59A</string>
<string>6B10003311AD03030098A59A</string>
<string>6B1000FB11AD16DC0098A59A</string>
<string>6B10011711AD19F90098A59A</string>
<string>6B10011811AD19F90098A59A</string>
<string>6B10011911AD19F90098A59A</string>
<string>6B10016C11AD1DE70098A59A</string>
<string>6B10017811AD1F0E0098A59A</string>
<string>6B10017911AD1F0E0098A59A</string>
<string>6B10017A11AD1F0E0098A59A</string>
<string>6B10017B11AD1F0E0098A59A</string>
</array>
<key>prevStack</key>
<array>
@ -435,15 +438,10 @@
<string>6BBB4AFD115B4F3400CF791D</string>
<string>6BBB4AFF115B4F3400CF791D</string>
<string>6BBB4B03115B4F3400CF791D</string>
<string>6BBB4B04115B4F3400CF791D</string>
<string>6BBB4B07115B4F3400CF791D</string>
<string>6BBB4B08115B4F3400CF791D</string>
<string>6BBB4B0A115B4F3400CF791D</string>
<string>6BBB4B0C115B4F3400CF791D</string>
<string>6BBB4B0D115B4F3400CF791D</string>
<string>6BBB4B0E115B4F3400CF791D</string>
<string>6BBB4B0F115B4F3400CF791D</string>
<string>6BBB4B10115B4F3400CF791D</string>
<string>6BBB4B11115B4F3400CF791D</string>
<string>6BBB4B87115B639200CF791D</string>
<string>6BBB4C3B115B7A3D00CF791D</string>
@ -459,56 +457,47 @@
<string>6B4215DF1180672F006C347B</string>
<string>6B4216881180725E006C347B</string>
<string>6B4217131180803D006C347B</string>
<string>6B555F471191AA4400843384</string>
<string>6B555F481191AA4400843384</string>
<string>6B55623F1193E79A00843384</string>
<string>6B55625A1193EF2F00843384</string>
<string>6B55625B1193EF2F00843384</string>
<string>6B55625C1193EF2F00843384</string>
<string>6B55625D1193EF2F00843384</string>
<string>6B55625E1193EF2F00843384</string>
<string>6B55625F1193EF2F00843384</string>
<string>6B5562601193EF2F00843384</string>
<string>6B5562611193EF2F00843384</string>
<string>6B5562621193EF2F00843384</string>
<string>6B5562631193EF2F00843384</string>
<string>6B5562641193EF2F00843384</string>
<string>6B5562651193EF2F00843384</string>
<string>6B5562661193EF2F00843384</string>
<string>6B5562671193EF2F00843384</string>
<string>6B5562681193EF2F00843384</string>
<string>6B5562691193EF2F00843384</string>
<string>6B55626A1193EF2F00843384</string>
<string>6B55626B1193EF2F00843384</string>
<string>6B55626C1193EF2F00843384</string>
<string>6B55626D1193EF2F00843384</string>
<string>6B55626E1193EF2F00843384</string>
<string>6B55626F1193EF2F00843384</string>
<string>6B5562701193EF2F00843384</string>
<string>6B55627E1193EF9F00843384</string>
<string>6B5562871193EFC500843384</string>
<string>6B5562881193EFC500843384</string>
<string>6B5562891193EFC500843384</string>
<string>6B5562961193F05700843384</string>
<string>6B5562A21193F08C00843384</string>
<string>6B5562A31193F08C00843384</string>
<string>6B5562A41193F08C00843384</string>
<string>6B5562A51193F08C00843384</string>
<string>6B5562AD1193F0BA00843384</string>
<string>6B5562B91193F10000843384</string>
<string>6B5562CD1193F1C000843384</string>
<string>6B5562D71193F20700843384</string>
<string>6B5562D81193F20700843384</string>
<string>6B5562D91193F20700843384</string>
<string>6B5562DA1193F20700843384</string>
<string>6B5562E31193F2A300843384</string>
<string>6B5562E41193F2A300843384</string>
<string>6B5562E51193F2A300843384</string>
<string>6B5562E61193F2A300843384</string>
<string>6B5562F61193F4CC00843384</string>
<string>6B5562F71193F4CC00843384</string>
<string>6B5562F81193F4CC00843384</string>
<string>6B5562FD1193F50A00843384</string>
<string>6B2CDD181197FE370090FA4D</string>
<string>6B2CDD3511980B820090FA4D</string>
<string>6B2CDD71119810560090FA4D</string>
<string>6B2CDD98119818F90090FA4D</string>
<string>6B57E94D11A7646800614060</string>
<string>6B10FFC911ACF80A0098A59A</string>
<string>6B10FFD711ACF8990098A59A</string>
<string>6B10FFD811ACF8990098A59A</string>
<string>6B10FFD911ACF8990098A59A</string>
<string>6B10FFDA11ACF8990098A59A</string>
<string>6B10FFE411ACF95E0098A59A</string>
<string>6B10005B11AD08FA0098A59A</string>
<string>6B10005C11AD08FA0098A59A</string>
<string>6B10005D11AD08FA0098A59A</string>
<string>6B10006811AD09950098A59A</string>
<string>6B10011D11AD19F90098A59A</string>
<string>6B10011E11AD19F90098A59A</string>
<string>6B10011F11AD19F90098A59A</string>
<string>6B10012011AD19F90098A59A</string>
<string>6B10012111AD19F90098A59A</string>
<string>6B10012211AD19F90098A59A</string>
<string>6B10012311AD19F90098A59A</string>
<string>6B10012411AD19F90098A59A</string>
<string>6B10013011AD1A7B0098A59A</string>
<string>6B10014F11AD1C240098A59A</string>
<string>6B10015711AD1C530098A59A</string>
<string>6B10015811AD1C530098A59A</string>
<string>6B10015911AD1C530098A59A</string>
<string>6B10015A11AD1C530098A59A</string>
<string>6B10016011AD1C900098A59A</string>
<string>6B10016A11AD1D9C0098A59A</string>
<string>6B10016E11AD1DE70098A59A</string>
<string>6B10017211AD1E790098A59A</string>
<string>6B10017C11AD1F0E0098A59A</string>
<string>6B10017D11AD1F0E0098A59A</string>
<string>6B10017E11AD1F0E0098A59A</string>
</array>
</dict>
<key>SplitCount</key>
@ -522,18 +511,18 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {970, 535}}</string>
<string>{{0, 0}, {970, 460}}</string>
<key>RubberWindowFrame</key>
<string>13 75 1256 702 0 0 1280 778 </string>
</dict>
<key>Module</key>
<string>PBXNavigatorGroup</string>
<key>Proportion</key>
<string>535pt</string>
<string>460pt</string>
</dict>
<dict>
<key>Proportion</key>
<string>121pt</string>
<string>196pt</string>
<key>Tabs</key>
<array>
<dict>
@ -547,7 +536,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {970, 56}}</string>
<string>{{10, 27}, {970, 68}}</string>
</dict>
<key>Module</key>
<string>XCDetailModule</string>
@ -563,7 +552,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {970, 287}}</string>
<string>{{10, 27}, {970, 52}}</string>
</dict>
<key>Module</key>
<string>PBXProjectFindModule</string>
@ -601,7 +590,7 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{10, 27}, {970, 94}}</string>
<string>{{10, 27}, {970, 169}}</string>
<key>RubberWindowFrame</key>
<string>13 75 1256 702 0 0 1280 778 </string>
</dict>
@ -631,11 +620,11 @@
</array>
<key>TableOfContents</key>
<array>
<string>6B5562411193E79A00843384</string>
<string>6B10FFC111ACF6790098A59A</string>
<string>1CA23ED40692098700951B8B</string>
<string>6B5562421193E79A00843384</string>
<string>6B10FFC211ACF6790098A59A</string>
<string>6B8632A30F78115100E2684A</string>
<string>6B5562431193E79A00843384</string>
<string>6B10FFC311ACF6790098A59A</string>
<string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string>
@ -686,12 +675,12 @@
<key>GeometryConfiguration</key>
<dict>
<key>Frame</key>
<string>{{0, 0}, {1256, 133}}</string>
<string>{{0, 0}, {1256, 251}}</string>
</dict>
<key>Module</key>
<string>PBXDebugCLIModule</string>
<key>Proportion</key>
<string>133pt</string>
<string>251pt</string>
</dict>
<dict>
<key>ContentConfiguration</key>
@ -710,8 +699,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {533, 123}}</string>
<string>{{533, 0}, {723, 123}}</string>
<string>{{0, 0}, {567, 93}}</string>
<string>{{567, 0}, {689, 93}}</string>
</array>
</dict>
<key>VerticalSplitView</key>
@ -726,8 +715,8 @@
<string>yes</string>
<key>sizes</key>
<array>
<string>{{0, 0}, {1256, 123}}</string>
<string>{{0, 123}, {1256, 400}}</string>
<string>{{0, 0}, {1256, 93}}</string>
<string>{{0, 93}, {1256, 312}}</string>
</array>
</dict>
</dict>
@ -747,7 +736,7 @@
<key>DebugSTDIOWindowFrame</key>
<string>{{200, 200}, {500, 300}}</string>
<key>Frame</key>
<string>{{0, 138}, {1256, 523}}</string>
<string>{{0, 256}, {1256, 405}}</string>
<key>PBXDebugSessionStackFrameViewKey</key>
<dict>
<key>DebugVariablesTableConfiguration</key>
@ -757,16 +746,16 @@
<string>Value</string>
<real>85</real>
<string>Summary</string>
<real>430</real>
<real>396</real>
</array>
<key>Frame</key>
<string>{{533, 0}, {723, 123}}</string>
<string>{{567, 0}, {689, 93}}</string>
</dict>
</dict>
<key>Module</key>
<string>PBXDebugSessionModule</string>
<key>Proportion</key>
<string>523pt</string>
<string>405pt</string>
</dict>
</array>
<key>Name</key>
@ -784,14 +773,14 @@
</array>
<key>TableOfContents</key>
<array>
<string>6B5562721193EF2F00843384</string>
<string>6B10FFCC11ACF80A0098A59A</string>
<string>1CCC7628064C1048000F2A68</string>
<string>1CCC7629064C1048000F2A68</string>
<string>6B5562731193EF2F00843384</string>
<string>6B5562741193EF2F00843384</string>
<string>6B5562751193EF2F00843384</string>
<string>6B5562761193EF2F00843384</string>
<string>6B5562771193EF2F00843384</string>
<string>6B10FFCD11ACF80A0098A59A</string>
<string>6B10FFCE11ACF80A0098A59A</string>
<string>6B10FFCF11ACF80A0098A59A</string>
<string>6B10FFD011ACF80A0098A59A</string>
<string>6B10FFD111ACF80A0098A59A</string>
</array>
<key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string>
@ -823,8 +812,8 @@
<integer>5</integer>
<key>WindowOrderList</key>
<array>
<string>6B5562811193EF9F00843384</string>
<string>6B5562821193EF9F00843384</string>
<string>6B10001111ACFFFB0098A59A</string>
<string>6B10001211ACFFFB0098A59A</string>
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
</array>
<key>WindowString</key>

View File

@ -72,6 +72,8 @@ public:
virtual void handleMeshChanged(class InputGeom* geom);
virtual bool handleBuild();
void getTilePos(const float* pos, int& tx, int& ty);
void buildTile(const float* pos);
void removeTile(const float* pos);
void buildAllTiles();

View File

@ -57,7 +57,7 @@ Sample_Debug::Sample_Debug() :
resetCommonSettings();
// Test
m_chf = new rcCompactHeightfield;
/* m_chf = new rcCompactHeightfield;
FileIO io;
if (!io.openForRead("test.chf"))
{
@ -71,7 +71,7 @@ Sample_Debug::Sample_Debug() :
delete m_chf;
m_chf = 0;
}
}
}*/
/* if (m_chf)
{
@ -131,6 +131,8 @@ Sample_Debug::Sample_Debug() :
vcopy(m_ext, ext);
vcopy(m_center, center);*/
}
Sample_Debug::~Sample_Debug()
@ -175,6 +177,102 @@ void Sample_Debug::handleRender()
if (m_cset)
duDebugDrawRawContours(&dd, *m_cset);
dd.depthMask(false);
{
const float bmin[3] = {-32.000004f,-11.488281f,-115.343544f};
const float cs = 0.300000f;
const float ch = 0.200000f;
const int verts[] = {
158,46,336,0,
157,47,331,0,
161,53,330,0,
162,52,335,0,
158,46,336,0,
154,46,339,5,
161,46,365,5,
171,46,385,5,
174,46,400,5,
177,46,404,5,
177,46,410,5,
183,46,416,5,
188,49,416,5,
193,52,411,6,
194,53,382,6,
188,52,376,6,
188,57,363,6,
174,57,349,6,
174,60,342,6,
168,58,336,6,
167,59,328,6,
162,55,324,6,
159,53,324,5,
152,46,328,5,
151,46,336,5,
154,46,339,5,
158,46,336,0,
160,46,340,0,
164,52,339,0,
168,55,343,0,
168,50,351,0,
182,54,364,0,
182,47,378,0,
188,50,383,0,
188,49,409,0,
183,46,409,0,
183,46,403,0,
180,46,399,0,
177,46,384,0,
165,46,359,0,
160,46,340,0,
};
const int nverts = sizeof(verts)/(sizeof(int)*4);
const unsigned int colln = duRGBA(255,255,255,128);
dd.begin(DU_DRAW_LINES, 1.0f);
for (int i = 0, j = nverts-1; i < nverts; j=i++)
{
const int* va = &verts[j*4];
const int* vb = &verts[i*4];
dd.vertex(bmin[0]+va[0]*cs, bmin[1]+va[1]*ch+j*0.01f, bmin[2]+va[2]*cs, colln);
dd.vertex(bmin[0]+vb[0]*cs, bmin[1]+vb[1]*ch+i*0.01f, bmin[2]+vb[2]*cs, colln);
}
dd.end();
const unsigned int colpt = duRGBA(255,255,255,255);
dd.begin(DU_DRAW_POINTS, 3.0f);
for (int i = 0, j = nverts-1; i < nverts; j=i++)
{
const int* va = &verts[j*4];
dd.vertex(bmin[0]+va[0]*cs, bmin[1]+va[1]*ch+j*0.01f, bmin[2]+va[2]*cs, colpt);
}
dd.end();
extern int triangulate(int n, const int* verts, int* indices, int* tris);
static int indices[nverts];
static int tris[nverts*3];
for (int j = 0; j < nverts; ++j)
indices[j] = j;
static int ntris = 0;
if (!ntris)
{
ntris = triangulate(nverts, verts, &indices[0], &tris[0]);
if (ntris < 0) ntris = -ntris;
}
const unsigned int coltri = duRGBA(255,255,255,64);
dd.begin(DU_DRAW_TRIS);
for (int i = 0; i < ntris*3; ++i)
{
const int* va = &verts[indices[tris[i]]*4];
dd.vertex(bmin[0]+va[0]*cs, bmin[1]+va[1]*ch, bmin[2]+va[2]*cs, coltri);
}
dd.end();
}
dd.depthMask(true);
}
void Sample_Debug::handleRenderOverlay(double* /*proj*/, double* /*model*/, int* /*view*/)

View File

@ -146,8 +146,19 @@ public:
}
}
virtual void handleRenderOverlay(double* /*proj*/, double* /*model*/, int* /*view*/)
virtual void handleRenderOverlay(double* proj, double* model, int* view)
{
GLdouble x, y, z;
if (m_hitPosSet && gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2],
model, proj, view, &x, &y, &z))
{
int tx=0, ty=0;
m_sample->getTilePos(m_hitPos, tx, ty);
char text[32];
snprintf(text,32,"(%d,%d)", tx,ty);
imguiDrawText((int)x, (int)y-25, IMGUI_ALIGN_CENTER, text, imguiRGBA(0,0,0,220));
}
}
};
@ -577,6 +588,17 @@ void Sample_TileMesh::buildTile(const float* pos)
}
}
void Sample_TileMesh::getTilePos(const float* pos, int& tx, int& ty)
{
if (!m_geom) return;
const float* bmin = m_geom->getMeshBoundsMin();
const float ts = m_tileSize*m_cellSize;
tx = (int)((pos[0] - bmin[0]) / ts);
ty = (int)((pos[2] - bmin[2]) / ts);
}
void Sample_TileMesh::removeTile(const float* pos)
{
if (!m_geom) return;
@ -624,6 +646,8 @@ void Sample_TileMesh::buildAllTiles()
{
for (int x = 0; x < tw; ++x)
{
printf("processing: %d,%d\n", x,y);
m_tileBmin[0] = bmin[0] + x*tcs;
m_tileBmin[1] = bmin[1];
m_tileBmin[2] = bmin[2] + y*tcs;