Issue 45:Input triangle based area creation (another try)

This commit is contained in:
Mikko Mononen 2010-07-13 07:19:10 +00:00
parent a48b50d89c
commit 5ebcb453fb
14 changed files with 3665 additions and 4289 deletions

View File

@ -41,22 +41,28 @@ struct rcConfig
float detailSampleMaxError; // Detail mesh simplification max sample error. float detailSampleMaxError; // Detail mesh simplification max sample error.
}; };
// Define number of bits in the above structure for smin/smax.
// The max height is used for clamping rasterized values.
static const int RC_SPAN_HEIGHT_BITS = 13;
static const int RC_SPAN_MAX_HEIGHT = (1<<RC_SPAN_HEIGHT_BITS)-1;
// Heightfield span. // Heightfield span.
struct rcSpan struct rcSpan
{ {
unsigned int smin : 15; // Span min height. unsigned int smin : 13; // Span min height.
unsigned int smax : 15; // Span max height. unsigned int smax : 13; // Span max height.
unsigned int flags : 2; // Span flags. unsigned int area : 6; // Span area type.
rcSpan* next; // Next span in column. rcSpan* next; // Next span in column.
}; };
// Number of spans allocated per pool.
static const int RC_SPANS_PER_POOL = 2048; static const int RC_SPANS_PER_POOL = 2048;
// Memory pool used for quick span allocation. // Memory pool used for quick span allocation.
struct rcSpanPool struct rcSpanPool
{ {
rcSpanPool* next; // Pointer to next pool. rcSpanPool* next; // Pointer to next pool.
rcSpan items[1]; // Array of spans (size RC_SPANS_PER_POOL). rcSpan items[RC_SPANS_PER_POOL]; // Array of spans.
}; };
// Dynamic span-heightfield. // Dynamic span-heightfield.
@ -184,11 +190,11 @@ rcPolyMeshDetail* rcAllocPolyMeshDetail();
void rcFreePolyMeshDetail(rcPolyMeshDetail* dmesh); void rcFreePolyMeshDetail(rcPolyMeshDetail* dmesh);
enum rcSpanFlags /*enum rcSpanFlags
{ {
RC_WALKABLE = 0x01, RC_WALKABLE = 0x01,
RC_LEDGE = 0x02, RC_LEDGE = 0x02,
}; };*/
// If heightfield region ID has the following bit set, the region is on border area // If heightfield region ID has the following bit set, the region is on border area
// and excluded from many calculations. // and excluded from many calculations.
@ -216,7 +222,7 @@ static const unsigned short RC_MESH_NULL_IDX = 0xffff;
static const unsigned char RC_NULL_AREA = 0; static const unsigned char RC_NULL_AREA = 0;
// Area ID that is considered generally walkable. // Area ID that is considered generally walkable.
static const unsigned char RC_WALKABLE_AREA = 255; static const unsigned char RC_WALKABLE_AREA = 63;
// Value returned by rcGetCon() if the direction is not connected. // Value returned by rcGetCon() if the direction is not connected.
static const int RC_NOT_CONNECTED = 0x3f; static const int RC_NOT_CONNECTED = 0x3f;
@ -374,7 +380,7 @@ bool rcCreateHeightfield(rcHeightfield& hf, int width, int height,
const float* bmin, const float* bmax, const float* bmin, const float* bmax,
float cs, float ch); float cs, float ch);
// Sets the WALKABLE flag for every triangle whose slope is below // Sets the RC_WALKABLE_AREA for every triangle whose slope is below
// the maximun walkable slope angle. // the maximun walkable slope angle.
// Params: // Params:
// walkableSlopeAngle - (in) maximun slope angle in degrees. // walkableSlopeAngle - (in) maximun slope angle in degrees.
@ -382,11 +388,25 @@ bool rcCreateHeightfield(rcHeightfield& hf, int width, int height,
// nv - (in) vertex count // nv - (in) vertex count
// tris - (in) array of triangle vertex indices // tris - (in) array of triangle vertex indices
// nt - (in) triangle count // nt - (in) triangle count
// flags - (out) array of triangle flags // areas - (out) array of triangle area types
void rcMarkWalkableTriangles(const float walkableSlopeAngle, void rcMarkWalkableTriangles(const float walkableSlopeAngle,
const float* verts, int nv, const float* verts, int nv,
const int* tris, int nt, const int* tris, int nt,
unsigned char* flags); unsigned char* areas);
// Sets the RC_NULL_AREA for every triangle whose slope is steeper than
// the maximun walkable slope angle.
// Params:
// walkableSlopeAngle - (in) maximun slope angle in degrees.
// verts - (in) array of vertices
// nv - (in) vertex count
// tris - (in) array of triangle vertex indices
// nt - (in) triangle count
// areas - (out) array of triangle are types
void rcClearUnwalkableTriangles(const float walkableSlopeAngle,
const float* verts, int nv,
const int* tris, int nt,
unsigned char* areas);
// Adds span to heighfield. // Adds span to heighfield.
// The span addition can set to favor flags. If the span is merged to // The span addition can set to favor flags. If the span is merged to
@ -400,16 +420,16 @@ void rcMarkWalkableTriangles(const float walkableSlopeAngle,
// flagMergeThr - (in) merge threshold. // flagMergeThr - (in) merge threshold.
void rcAddSpan(rcHeightfield& solid, const int x, const int y, void rcAddSpan(rcHeightfield& solid, const int x, const int y,
const unsigned short smin, const unsigned short smax, const unsigned short smin, const unsigned short smax,
const unsigned short flags, const int flagMergeThr); const unsigned short area, const int flagMergeThr);
// Rasterizes a triangle into heightfield spans. // Rasterizes a triangle into heightfield spans.
// Params: // Params:
// v0,v1,v2 - (in) the vertices of the triangle. // v0,v1,v2 - (in) the vertices of the triangle.
// flags - (in) triangle flags (uses WALKABLE) // area - (in) area type of the triangle.
// solid - (in) heighfield where the triangle is rasterized // solid - (in) heighfield where the triangle is rasterized
// flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable. // flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable.
void rcRasterizeTriangle(const float* v0, const float* v1, const float* v2, void rcRasterizeTriangle(const float* v0, const float* v1, const float* v2,
unsigned char flags, rcHeightfield& solid, const unsigned char area, rcHeightfield& solid,
const int flagMergeThr = 1); const int flagMergeThr = 1);
// Rasterizes indexed triangle mesh into heightfield spans. // Rasterizes indexed triangle mesh into heightfield spans.
@ -417,12 +437,12 @@ void rcRasterizeTriangle(const float* v0, const float* v1, const float* v2,
// verts - (in) array of vertices // verts - (in) array of vertices
// nv - (in) vertex count // nv - (in) vertex count
// tris - (in) array of triangle vertex indices // tris - (in) array of triangle vertex indices
// flags - (in) array of triangle flags (uses WALKABLE) // area - (in) array of triangle area types.
// nt - (in) triangle count // nt - (in) triangle count
// solid - (in) heighfield where the triangles are rasterized // solid - (in) heighfield where the triangles are rasterized
// flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable. // flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable.
void rcRasterizeTriangles(const float* verts, const int nv, void rcRasterizeTriangles(const float* verts, const int nv,
const int* tris, const unsigned char* flags, const int nt, const int* tris, const unsigned char* areas, const int nt,
rcHeightfield& solid, const int flagMergeThr = 1); rcHeightfield& solid, const int flagMergeThr = 1);
// Rasterizes indexed triangle mesh into heightfield spans. // Rasterizes indexed triangle mesh into heightfield spans.
@ -430,21 +450,21 @@ void rcRasterizeTriangles(const float* verts, const int nv,
// verts - (in) array of vertices // verts - (in) array of vertices
// nv - (in) vertex count // nv - (in) vertex count
// tris - (in) array of triangle vertex indices // tris - (in) array of triangle vertex indices
// flags - (in) array of triangle flags (uses WALKABLE) // area - (in) array of triangle area types.
// nt - (in) triangle count // nt - (in) triangle count
// solid - (in) heighfield where the triangles are rasterized // solid - (in) heighfield where the triangles are rasterized
// flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable. // flagMergeThr - (in) distance in voxel where walkable flag is favored over non-walkable.
void rcRasterizeTriangles(const float* verts, const int nv, void rcRasterizeTriangles(const float* verts, const int nv,
const unsigned short* tris, const unsigned char* flags, const int nt, const unsigned short* tris, const unsigned char* areas, const int nt,
rcHeightfield& solid, const int flagMergeThr = 1); rcHeightfield& solid, const int flagMergeThr = 1);
// Rasterizes the triangles into heightfield spans. // Rasterizes the triangles into heightfield spans.
// Params: // Params:
// verts - (in) array of vertices // verts - (in) array of vertices
// flags - (in) array of triangle flags (uses WALKABLE) // area - (in) array of triangle area types.
// nt - (in) triangle count // nt - (in) triangle count
// solid - (in) heighfield where the triangles are rasterized // solid - (in) heighfield where the triangles are rasterized
void rcRasterizeTriangles(const float* verts, const unsigned char* flags, const int nt, void rcRasterizeTriangles(const float* verts, const unsigned char* areas, const int nt,
rcHeightfield& solid, const int flagMergeThr = 1); rcHeightfield& solid, const int flagMergeThr = 1);
// Marks non-walkable low obstacles as walkable if they are closer than walkableClimb // Marks non-walkable low obstacles as walkable if they are closer than walkableClimb
@ -477,10 +497,9 @@ void rcFilterWalkableLowHeightSpans(int walkableHeight,
// Returns number of spans contained in a heightfield. // Returns number of spans contained in a heightfield.
// Params: // Params:
// flags - (in) require flags for a cell to be included.
// hf - (in) heightfield to be compacted // hf - (in) heightfield to be compacted
// Returns number of spans. // Returns number of spans.
int rcGetHeightFieldSpanCount(const unsigned char flags, rcHeightfield& hf); int rcGetHeightFieldSpanCount(rcHeightfield& hf);
// Builds compact representation of the heightfield. // Builds compact representation of the heightfield.
// Params: // Params:
@ -491,16 +510,20 @@ int rcGetHeightFieldSpanCount(const unsigned char flags, rcHeightfield& hf);
// chf - (out) compact heightfield representing the open space. // chf - (out) compact heightfield representing the open space.
// Returns false if operation ran out of memory. // Returns false if operation ran out of memory.
bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb, bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb,
unsigned char flags, rcHeightfield& hf, rcCompactHeightfield& chf);
rcHeightfield& hf,
rcCompactHeightfield& chf);
// Erodes specified area id and replaces the are with null. // Erodes walkable area.
// Params: // Params:
// areaId - (in) area to erode.
// radius - (in) radius of erosion (max 255). // radius - (in) radius of erosion (max 255).
// chf - (in/out) compact heightfield to erode. // chf - (in/out) compact heightfield to erode.
bool rcErodeArea(unsigned char areaId, int radius, rcCompactHeightfield& chf); // Returns false if operation ran out of memory.
bool rcErodeWalkableArea(int radius, rcCompactHeightfield& chf);
// Applies median filter to walkable area types, removing noise.
// Params:
// chf - (in/out) compact heightfield to erode.
// Returns false if operation ran out of memory.
bool rcMedianFilterWalkableArea(rcCompactHeightfield& chf);
// Marks the area of the convex polygon into the area type of the compact heighfield. // Marks the area of the convex polygon into the area type of the compact heighfield.
// Params: // Params:

View File

@ -57,6 +57,7 @@ struct rcBuildTimes
int filterBorder; int filterBorder;
int filterWalkable; int filterWalkable;
int filterMarkReachable; int filterMarkReachable;
int filterMedian;
int buildPolymesh; int buildPolymesh;
int erodeArea; int erodeArea;
int buildDistanceField; int buildDistanceField;

View File

@ -173,7 +173,7 @@ static void calcTriNormal(const float* v0, const float* v1, const float* v2, flo
void rcMarkWalkableTriangles(const float walkableSlopeAngle, void rcMarkWalkableTriangles(const float walkableSlopeAngle,
const float* verts, int /*nv*/, const float* verts, int /*nv*/,
const int* tris, int nt, const int* tris, int nt,
unsigned char* flags) unsigned char* areas)
{ {
const float walkableThr = cosf(walkableSlopeAngle/180.0f*(float)M_PI); const float walkableThr = cosf(walkableSlopeAngle/180.0f*(float)M_PI);
@ -185,11 +185,30 @@ void rcMarkWalkableTriangles(const float walkableSlopeAngle,
calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm); calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm);
// Check if the face is walkable. // Check if the face is walkable.
if (norm[1] > walkableThr) if (norm[1] > walkableThr)
flags[i] |= RC_WALKABLE; areas[i] = RC_WALKABLE_AREA;
} }
} }
int rcGetHeightFieldSpanCount(const unsigned char flags, rcHeightfield& hf) void rcClearUnwalkableTriangles(const float walkableSlopeAngle,
const float* verts, int /*nv*/,
const int* tris, int nt,
unsigned char* areas)
{
const float walkableThr = cosf(walkableSlopeAngle/180.0f*(float)M_PI);
float norm[3];
for (int i = 0; i < nt; ++i)
{
const int* tri = &tris[i*3];
calcTriNormal(&verts[tri[0]*3], &verts[tri[1]*3], &verts[tri[2]*3], norm);
// Check if the face is walkable.
if (norm[1] <= walkableThr)
areas[i] = RC_NULL_AREA;
}
}
int rcGetHeightFieldSpanCount(rcHeightfield& hf)
{ {
const int w = hf.width; const int w = hf.width;
const int h = hf.height; const int h = hf.height;
@ -200,7 +219,7 @@ int rcGetHeightFieldSpanCount(const unsigned char flags, rcHeightfield& hf)
{ {
for (rcSpan* s = hf.spans[x + y*w]; s; s = s->next) for (rcSpan* s = hf.spans[x + y*w]; s; s = s->next)
{ {
if (s->flags == flags) if (s->area != RC_NULL_AREA)
spanCount++; spanCount++;
} }
} }
@ -209,14 +228,13 @@ int rcGetHeightFieldSpanCount(const unsigned char flags, rcHeightfield& hf)
} }
bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb, bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb,
unsigned char flags, rcHeightfield& hf, rcHeightfield& hf, rcCompactHeightfield& chf)
rcCompactHeightfield& chf)
{ {
rcTimeVal startTime = rcGetPerformanceTimer(); rcTimeVal startTime = rcGetPerformanceTimer();
const int w = hf.width; const int w = hf.width;
const int h = hf.height; const int h = hf.height;
const int spanCount = rcGetHeightFieldSpanCount(flags, hf); const int spanCount = rcGetHeightFieldSpanCount(hf);
// Fill in header. // Fill in header.
chf.width = w; chf.width = w;
@ -253,7 +271,7 @@ bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb
rcGetLog()->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.areas' (%d)", spanCount); rcGetLog()->log(RC_LOG_ERROR, "rcBuildCompactHeightfield: Out of memory 'chf.areas' (%d)", spanCount);
return false; return false;
} }
memset(chf.areas, RC_WALKABLE_AREA, sizeof(unsigned char)*spanCount); memset(chf.areas, RC_NULL_AREA, sizeof(unsigned char)*spanCount);
const int MAX_HEIGHT = 0xffff; const int MAX_HEIGHT = 0xffff;
@ -271,12 +289,13 @@ bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb
c.count = 0; c.count = 0;
while (s) while (s)
{ {
if (s->flags == flags) if (s->area != RC_NULL_AREA)
{ {
const int bot = (int)s->smax; const int bot = (int)s->smax;
const int top = s->next ? (int)s->next->smin : MAX_HEIGHT; const int top = s->next ? (int)s->next->smin : MAX_HEIGHT;
chf.spans[idx].y = (unsigned short)rcClamp(bot, 0, 0xffff); chf.spans[idx].y = (unsigned short)rcClamp(bot, 0, 0xffff);
chf.spans[idx].h = (unsigned char)rcClamp(top - bot, 0, 0xff); chf.spans[idx].h = (unsigned char)rcClamp(top - bot, 0, 0xff);
chf.areas[idx] = s->area;
idx++; idx++;
c.count++; c.count++;
} }
@ -286,7 +305,7 @@ bool rcBuildCompactHeightfield(const int walkableHeight, const int walkableClimb
} }
// Find neighbour connections. // Find neighbour connections.
const float MAX_LAYERS = RC_NOT_CONNECTED-1; const int MAX_LAYERS = RC_NOT_CONNECTED-1;
int tooHighNeighbour = 0; int tooHighNeighbour = 0;
for (int y = 0; y < h; ++y) for (int y = 0; y < h; ++y)
{ {

View File

@ -28,7 +28,7 @@
#include "RecastAlloc.h" #include "RecastAlloc.h"
bool rcErodeArea(unsigned char areaId, int radius, rcCompactHeightfield& chf) bool rcErodeWalkableArea(int radius, rcCompactHeightfield& chf)
{ {
const int w = chf.width; const int w = chf.width;
const int h = chf.height; const int h = chf.height;
@ -57,14 +57,8 @@ bool rcErodeArea(unsigned char areaId, int radius, rcCompactHeightfield& chf)
for (int dir = 0; dir < 4; ++dir) for (int dir = 0; dir < 4; ++dir)
{ {
if (rcGetCon(s, dir) != RC_NOT_CONNECTED) if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
{
const int ax = x + rcGetDirOffsetX(dir);
const int ay = y + rcGetDirOffsetY(dir);
const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
if (chf.areas[ai] == areaId)
nc++; nc++;
} }
}
// At least one missing neighbour. // At least one missing neighbour.
if (nc != 4) if (nc != 4)
dist[i] = 0; dist[i] = 0;
@ -194,7 +188,7 @@ bool rcErodeArea(unsigned char areaId, int radius, rcCompactHeightfield& chf)
const unsigned char thr = (unsigned char)(radius*2); const unsigned char thr = (unsigned char)(radius*2);
for (int i = 0; i < chf.spanCount; ++i) for (int i = 0; i < chf.spanCount; ++i)
if (dist[i] < thr) if (dist[i] < thr)
chf.areas[i] = 0; chf.areas[i] = RC_NULL_AREA;
rcFree(dist); rcFree(dist);
@ -208,6 +202,93 @@ bool rcErodeArea(unsigned char areaId, int radius, rcCompactHeightfield& chf)
return true; return true;
} }
static void insertSort(unsigned char* a, const int n)
{
int i, j;
for (i = 1; i < n; i++)
{
const unsigned char value = a[i];
for (j = i - 1; j >= 0 && a[j] > value; j--)
a[j+1] = a[j];
a[j+1] = value;
}
}
bool rcMedianFilterWalkableArea(rcCompactHeightfield& chf)
{
const int w = chf.width;
const int h = chf.height;
rcTimeVal startTime = rcGetPerformanceTimer();
unsigned char* areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
if (!areas)
return false;
// Init distance.
memset(areas, 0xff, sizeof(unsigned char)*chf.spanCount);
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
const rcCompactCell& c = chf.cells[x+y*w];
for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
{
const rcCompactSpan& s = chf.spans[i];
if (chf.areas[i] == RC_NULL_AREA)
{
areas[i] = chf.areas[i];
continue;
}
unsigned char nei[9];
for (int j = 0; j < 9; ++j)
nei[j] = chf.areas[i];
for (int dir = 0; dir < 4; ++dir)
{
if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
{
const int ax = x + rcGetDirOffsetX(dir);
const int ay = y + rcGetDirOffsetY(dir);
const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
if (chf.areas[ai] != RC_NULL_AREA)
nei[dir*2+0] = chf.areas[ai];
const rcCompactSpan& as = chf.spans[ai];
const int dir2 = (dir+1) & 0x3;
if (rcGetCon(as, dir2) != RC_NOT_CONNECTED)
{
const int ax2 = ax + rcGetDirOffsetX(dir2);
const int ay2 = ay + rcGetDirOffsetY(dir2);
const int ai2 = (int)chf.cells[ax2+ay2*w].index + rcGetCon(as, dir2);
if (chf.areas[ai2] != RC_NULL_AREA)
nei[dir*2+1] = chf.areas[ai2];
}
}
}
insertSort(nei, 9);
areas[i] = nei[4];
}
}
}
memcpy(chf.areas, areas, sizeof(unsigned char)*chf.spanCount);
rcFree(areas);
rcTimeVal endTime = rcGetPerformanceTimer();
if (rcGetBuildTimes())
{
rcGetBuildTimes()->filterMedian += rcGetDeltaTimeUsec(startTime, endTime);
}
return true;
}
void rcMarkBoxArea(const float* bmin, const float* bmax, unsigned char areaId, void rcMarkBoxArea(const float* bmin, const float* bmax, unsigned char areaId,
rcCompactHeightfield& chf) rcCompactHeightfield& chf)
{ {

View File

@ -35,10 +35,28 @@ void rcFilterLowHangingWalkableObstacles(const int walkableClimb, rcHeightfield&
for (int x = 0; x < w; ++x) for (int x = 0; x < w; ++x)
{ {
rcSpan* ps = 0; rcSpan* ps = 0;
bool previousWalkable = false;
for (rcSpan* s = solid.spans[x + y*w]; s; ps = s, s = s->next) for (rcSpan* s = solid.spans[x + y*w]; s; ps = s, s = s->next)
{ {
const bool walkable = (s->flags & RC_WALKABLE) != 0; const bool walkable = s->area != RC_NULL_AREA;
const bool previousWalkable = ps && (ps->flags & RC_WALKABLE) != 0; // If current span is not walkable, but there is walkable
// span just below it, mark the span above it walkable too.
if (!walkable && previousWalkable)
{
if (rcAbs((int)s->smax - (int)ps->smax) <= walkableClimb)
s->area = RC_NULL_AREA;
}
// Copy walkable flag so that it cannot propagate
// past multiple non-walkable objects.
previousWalkable = walkable;
}
/* rcSpan* ps = 0;
for (rcSpan* s = solid.spans[x + y*w]; s; ps = s, s = s->next)
{
const bool walkable = s->flags != RC_NULL_AREA;
const bool previousWalkable = ps && ps->flags != RC_NULL_AREA;
// If current span is not walkable, but there is walkable // If current span is not walkable, but there is walkable
// span just below it, mark the span above it walkable too. // span just below it, mark the span above it walkable too.
// Missuse the edge flag so that walkable flag cannot propagate // Missuse the edge flag so that walkable flag cannot propagate
@ -46,7 +64,7 @@ void rcFilterLowHangingWalkableObstacles(const int walkableClimb, rcHeightfield&
if (!walkable && previousWalkable) if (!walkable && previousWalkable)
{ {
if (rcAbs((int)s->smax - (int)ps->smax) <= walkableClimb) if (rcAbs((int)s->smax - (int)ps->smax) <= walkableClimb)
s->flags |= RC_LEDGE; s->flags |= 1;
} }
} }
// Transfer "fake ledges" to walkables. // Transfer "fake ledges" to walkables.
@ -55,7 +73,8 @@ void rcFilterLowHangingWalkableObstacles(const int walkableClimb, rcHeightfield&
if (s->flags & RC_LEDGE) if (s->flags & RC_LEDGE)
s->flags |= RC_WALKABLE; s->flags |= RC_WALKABLE;
s->flags &= ~RC_LEDGE; s->flags &= ~RC_LEDGE;
} }*/
} }
} }
} }
@ -78,7 +97,7 @@ void rcFilterLedgeSpans(const int walkableHeight,
for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next) for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next)
{ {
// Skip non walkable spans. // Skip non walkable spans.
if ((s->flags & RC_WALKABLE) == 0) if (s->area == RC_NULL_AREA)
continue; continue;
const int bot = (int)(s->smax); const int bot = (int)(s->smax);
@ -134,13 +153,13 @@ void rcFilterLedgeSpans(const int walkableHeight,
// The current span is close to a ledge if the drop to any // The current span is close to a ledge if the drop to any
// neighbour span is less than the walkableClimb. // neighbour span is less than the walkableClimb.
if (minh < -walkableClimb) if (minh < -walkableClimb)
s->flags |= RC_LEDGE; s->area = RC_NULL_AREA;
// If the difference between all neighbours is too large, // If the difference between all neighbours is too large,
// we are at steep slope, mark the span as ledge. // we are at steep slope, mark the span as ledge.
if ((asmax - asmin) > walkableClimb) if ((asmax - asmin) > walkableClimb)
{ {
s->flags |= RC_LEDGE; s->area = RC_NULL_AREA;
} }
} }
} }
@ -173,7 +192,7 @@ void rcFilterWalkableLowHeightSpans(int walkableHeight,
const int bot = (int)(s->smax); const int bot = (int)(s->smax);
const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT; const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT;
if ((top - bot) <= walkableHeight) if ((top - bot) <= walkableHeight)
s->flags &= ~RC_WALKABLE; s->area = RC_NULL_AREA;
} }
} }
} }

View File

@ -49,8 +49,7 @@ static rcSpan* allocSpan(rcHeightfield& hf)
{ {
// Create new page. // Create new page.
// Allocate memory for the new pool. // Allocate memory for the new pool.
const int size = (sizeof(rcSpanPool)-sizeof(rcSpan)) + sizeof(rcSpan)*RC_SPANS_PER_POOL; rcSpanPool* pool = (rcSpanPool*)rcAlloc(sizeof(rcSpanPool), RC_ALLOC_PERM);
rcSpanPool* pool = (rcSpanPool*)rcAlloc(size, RC_ALLOC_PERM);
if (!pool) return 0; if (!pool) return 0;
pool->next = 0; pool->next = 0;
// Add the pool into the list of pools. // Add the pool into the list of pools.
@ -86,14 +85,14 @@ static void freeSpan(rcHeightfield& hf, rcSpan* ptr)
void rcAddSpan(rcHeightfield& hf, const int x, const int y, void rcAddSpan(rcHeightfield& hf, const int x, const int y,
const unsigned short smin, const unsigned short smax, const unsigned short smin, const unsigned short smax,
const unsigned short flags, const int flagMergeThr) const unsigned char area, const int flagMergeThr)
{ {
int idx = x + y*hf.width; int idx = x + y*hf.width;
rcSpan* s = allocSpan(hf); rcSpan* s = allocSpan(hf);
s->smin = smin; s->smin = smin;
s->smax = smax; s->smax = smax;
s->flags = flags; s->area = area;
s->next = 0; s->next = 0;
// Empty cell, add he first span. // Empty cell, add he first span.
@ -129,7 +128,7 @@ void rcAddSpan(rcHeightfield& hf, const int x, const int y,
// Merge flags. // Merge flags.
if (rcAbs((int)s->smax - (int)cur->smax) <= flagMergeThr) if (rcAbs((int)s->smax - (int)cur->smax) <= flagMergeThr)
s->flags |= cur->flags; s->area = rcMax(s->area, cur->area);
// Remove current span. // Remove current span.
rcSpan* next = cur->next; rcSpan* next = cur->next;
@ -186,7 +185,7 @@ static int clipPoly(const float* in, int n, float* out, float pnx, float pnz, fl
} }
static void rasterizeTri(const float* v0, const float* v1, const float* v2, static void rasterizeTri(const float* v0, const float* v1, const float* v2,
unsigned char flags, rcHeightfield& hf, const unsigned char area, rcHeightfield& hf,
const float* bmin, const float* bmax, const float* bmin, const float* bmax,
const float cs, const float ics, const float ich, const float cs, const float ics, const float ich,
const int flagMergeThr) const int flagMergeThr)
@ -261,23 +260,23 @@ static void rasterizeTri(const float* v0, const float* v1, const float* v2,
if (smax > by) smax = by; if (smax > by) smax = by;
// Snap the span to the heightfield height grid. // Snap the span to the heightfield height grid.
unsigned short ismin = (unsigned short)rcClamp((int)floorf(smin * ich), 0, 0x7fff); unsigned short ismin = (unsigned short)rcClamp((int)floorf(smin * ich), 0, RC_SPAN_MAX_HEIGHT);
unsigned short ismax = (unsigned short)rcClamp((int)ceilf(smax * ich), (int)ismin+1, 0x7fff); unsigned short ismax = (unsigned short)rcClamp((int)ceilf(smax * ich), (int)ismin+1, RC_SPAN_MAX_HEIGHT);
rcAddSpan(hf, x, y, ismin, ismax, flags, flagMergeThr); rcAddSpan(hf, x, y, ismin, ismax, area, flagMergeThr);
} }
} }
} }
void rcRasterizeTriangle(const float* v0, const float* v1, const float* v2, void rcRasterizeTriangle(const float* v0, const float* v1, const float* v2,
unsigned char flags, rcHeightfield& solid, const unsigned char area, rcHeightfield& solid,
const int flagMergeThr) const int flagMergeThr)
{ {
rcTimeVal startTime = rcGetPerformanceTimer(); rcTimeVal startTime = rcGetPerformanceTimer();
const float ics = 1.0f/solid.cs; const float ics = 1.0f/solid.cs;
const float ich = 1.0f/solid.ch; const float ich = 1.0f/solid.ch;
rasterizeTri(v0, v1, v2, flags, solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr); rasterizeTri(v0, v1, v2, area, solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
rcTimeVal endTime = rcGetPerformanceTimer(); rcTimeVal endTime = rcGetPerformanceTimer();
@ -286,7 +285,7 @@ void rcRasterizeTriangle(const float* v0, const float* v1, const float* v2,
} }
void rcRasterizeTriangles(const float* verts, const int /*nv*/, void rcRasterizeTriangles(const float* verts, const int /*nv*/,
const int* tris, const unsigned char* flags, const int nt, const int* tris, const unsigned char* areas, const int nt,
rcHeightfield& solid, const int flagMergeThr) rcHeightfield& solid, const int flagMergeThr)
{ {
rcTimeVal startTime = rcGetPerformanceTimer(); rcTimeVal startTime = rcGetPerformanceTimer();
@ -300,7 +299,7 @@ void rcRasterizeTriangles(const float* verts, const int /*nv*/,
const float* v1 = &verts[tris[i*3+1]*3]; const float* v1 = &verts[tris[i*3+1]*3];
const float* v2 = &verts[tris[i*3+2]*3]; const float* v2 = &verts[tris[i*3+2]*3];
// Rasterize. // Rasterize.
rasterizeTri(v0, v1, v2, flags[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr); rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
} }
rcTimeVal endTime = rcGetPerformanceTimer(); rcTimeVal endTime = rcGetPerformanceTimer();
@ -310,7 +309,7 @@ void rcRasterizeTriangles(const float* verts, const int /*nv*/,
} }
void rcRasterizeTriangles(const float* verts, const int /*nv*/, void rcRasterizeTriangles(const float* verts, const int /*nv*/,
const unsigned short* tris, const unsigned char* flags, const int nt, const unsigned short* tris, const unsigned char* areas, const int nt,
rcHeightfield& solid, const int flagMergeThr) rcHeightfield& solid, const int flagMergeThr)
{ {
rcTimeVal startTime = rcGetPerformanceTimer(); rcTimeVal startTime = rcGetPerformanceTimer();
@ -324,7 +323,7 @@ void rcRasterizeTriangles(const float* verts, const int /*nv*/,
const float* v1 = &verts[tris[i*3+1]*3]; const float* v1 = &verts[tris[i*3+1]*3];
const float* v2 = &verts[tris[i*3+2]*3]; const float* v2 = &verts[tris[i*3+2]*3];
// Rasterize. // Rasterize.
rasterizeTri(v0, v1, v2, flags[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr); rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
} }
rcTimeVal endTime = rcGetPerformanceTimer(); rcTimeVal endTime = rcGetPerformanceTimer();
@ -333,7 +332,7 @@ void rcRasterizeTriangles(const float* verts, const int /*nv*/,
rcGetBuildTimes()->rasterizeTriangles += rcGetDeltaTimeUsec(startTime, endTime); rcGetBuildTimes()->rasterizeTriangles += rcGetDeltaTimeUsec(startTime, endTime);
} }
void rcRasterizeTriangles(const float* verts, const unsigned char* flags, const int nt, void rcRasterizeTriangles(const float* verts, const unsigned char* areas, const int nt,
rcHeightfield& solid, const int flagMergeThr) rcHeightfield& solid, const int flagMergeThr)
{ {
rcTimeVal startTime = rcGetPerformanceTimer(); rcTimeVal startTime = rcGetPerformanceTimer();
@ -347,7 +346,7 @@ void rcRasterizeTriangles(const float* verts, const unsigned char* flags, const
const float* v1 = &verts[(i*3+1)*3]; const float* v1 = &verts[(i*3+1)*3];
const float* v2 = &verts[(i*3+2)*3]; const float* v2 = &verts[(i*3+2)*3];
// Rasterize. // Rasterize.
rasterizeTri(v0, v1, v2, flags[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr); rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
} }
rcTimeVal endTime = rcGetPerformanceTimer(); rcTimeVal endTime = rcGetPerformanceTimer();

File diff suppressed because it is too large Load Diff

View File

@ -282,14 +282,14 @@
<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key> <key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
<array> <array>
<array> <array>
<integer>32</integer> <integer>42</integer>
<integer>22</integer> <integer>38</integer>
<integer>1</integer> <integer>1</integer>
<integer>0</integer> <integer>0</integer>
</array> </array>
</array> </array>
<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key> <key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
<string>{{0, 270}, {264, 632}}</string> <string>{{0, 184}, {264, 632}}</string>
</dict> </dict>
<key>PBXTopSmartGroupGIDs</key> <key>PBXTopSmartGroupGIDs</key>
<array/> <array/>
@ -324,7 +324,7 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>RecastRegion.cpp</string> <string>Sample_SoloMeshSimple.cpp</string>
<key>PBXSplitModuleInNavigatorKey</key> <key>PBXSplitModuleInNavigatorKey</key>
<dict> <dict>
<key>Split0</key> <key>Split0</key>
@ -332,15 +332,14 @@
<key>PBXProjectModuleGUID</key> <key>PBXProjectModuleGUID</key>
<string>6B8632A40F78115100E2684A</string> <string>6B8632A40F78115100E2684A</string>
<key>PBXProjectModuleLabel</key> <key>PBXProjectModuleLabel</key>
<string>RecastRegion.cpp</string> <string>Sample_SoloMeshSimple.cpp</string>
<key>_historyCapacity</key> <key>_historyCapacity</key>
<integer>0</integer> <integer>0</integer>
<key>bookmark</key> <key>bookmark</key>
<string>6B9847C611E752CC00FA177B</string> <string>6BF9B22211EC4A600043574C</string>
<key>history</key> <key>history</key>
<array> <array>
<string>6BBB4AA1115B4F3400CF791D</string> <string>6BBB4AA1115B4F3400CF791D</string>
<string>6BBB4AA4115B4F3400CF791D</string>
<string>6BBB4AA5115B4F3400CF791D</string> <string>6BBB4AA5115B4F3400CF791D</string>
<string>6BBB4AA6115B4F3400CF791D</string> <string>6BBB4AA6115B4F3400CF791D</string>
<string>6BBB4AAB115B4F3400CF791D</string> <string>6BBB4AAB115B4F3400CF791D</string>
@ -359,23 +358,13 @@
<string>6BF5F32E11759C3C000502A6</string> <string>6BF5F32E11759C3C000502A6</string>
<string>6BF5F474117644A2000502A6</string> <string>6BF5F474117644A2000502A6</string>
<string>6BF5F475117644A2000502A6</string> <string>6BF5F475117644A2000502A6</string>
<string>6BF5F476117644A2000502A6</string>
<string>6BF5F478117644A2000502A6</string> <string>6BF5F478117644A2000502A6</string>
<string>6BF5F5041176F5F8000502A6</string> <string>6BF5F5041176F5F8000502A6</string>
<string>6B4214D911803923006C347B</string> <string>6B4214D911803923006C347B</string>
<string>6B5562501193EF2F00843384</string>
<string>6B5562511193EF2F00843384</string>
<string>6B5562DF1193F2A300843384</string>
<string>6B5562E01193F2A300843384</string>
<string>6B2CDC911197F0720090FA4D</string> <string>6B2CDC911197F0720090FA4D</string>
<string>6B2CDDC9119830560090FA4D</string>
<string>6B10000A11ACFFFB0098A59A</string>
<string>6B10011711AD19F90098A59A</string> <string>6B10011711AD19F90098A59A</string>
<string>6B10011911AD19F90098A59A</string>
<string>6B586E8311CF3E0000704B61</string> <string>6B586E8311CF3E0000704B61</string>
<string>6B77655411E3A9490029917E</string>
<string>6B77655511E3A9490029917E</string> <string>6B77655511E3A9490029917E</string>
<string>6B77655811E3A9490029917E</string>
<string>6B98453411E6013000FA177B</string> <string>6B98453411E6013000FA177B</string>
<string>6B98462E11E6141900FA177B</string> <string>6B98462E11E6141900FA177B</string>
<string>6B98464311E6F9B400FA177B</string> <string>6B98464311E6F9B400FA177B</string>
@ -384,38 +373,47 @@
<string>6B9846B911E7145500FA177B</string> <string>6B9846B911E7145500FA177B</string>
<string>6B9846F311E7282C00FA177B</string> <string>6B9846F311E7282C00FA177B</string>
<string>6B9846F611E7282C00FA177B</string> <string>6B9846F611E7282C00FA177B</string>
<string>6B98470011E7285500FA177B</string>
<string>6B98471A11E734DF00FA177B</string> <string>6B98471A11E734DF00FA177B</string>
<string>6B98471B11E734DF00FA177B</string>
<string>6B98473011E737D800FA177B</string> <string>6B98473011E737D800FA177B</string>
<string>6B98474311E73ABF00FA177B</string> <string>6B98474311E73ABF00FA177B</string>
<string>6B98475E11E73D0100FA177B</string>
<string>6B98475F11E73D0100FA177B</string>
<string>6B98476011E73D0100FA177B</string>
<string>6B98477711E7433F00FA177B</string>
<string>6B98478311E74AB100FA177B</string> <string>6B98478311E74AB100FA177B</string>
<string>6B98478411E74AB100FA177B</string>
<string>6B98478611E74AB100FA177B</string>
<string>6B98478711E74AB100FA177B</string>
<string>6B98478811E74AB100FA177B</string>
<string>6B98478911E74AB100FA177B</string>
<string>6B98478A11E74AB100FA177B</string>
<string>6B98478B11E74AB100FA177B</string>
<string>6B9847A011E74BC100FA177B</string>
<string>6B9847A211E74BC100FA177B</string> <string>6B9847A211E74BC100FA177B</string>
<string>6B9847AE11E74FAB00FA177B</string>
<string>6B9847B911E751AC00FA177B</string>
<string>6B9847BA11E751AC00FA177B</string> <string>6B9847BA11E751AC00FA177B</string>
<string>6B9847BB11E751AC00FA177B</string> <string>6B9847E611E86DBB00FA177B</string>
<string>6B9847C311E752CC00FA177B</string> <string>6B9847E911E86DBB00FA177B</string>
<string>6B9847C411E752CC00FA177B</string> <string>6B9847EA11E86DBB00FA177B</string>
<string>6B9847FB11E9AFC900FA177B</string>
<string>6B9847FC11E9AFC900FA177B</string>
<string>6B9847FE11E9AFC900FA177B</string>
<string>6B98480D11E9B1DC00FA177B</string>
<string>6B98482611E9D23600FA177B</string>
<string>6BF9B12C11EB8CF20043574C</string>
<string>6BF9B12D11EB8CF20043574C</string>
<string>6BF9B12E11EB8CF20043574C</string>
<string>6BF9B12F11EB8CF20043574C</string>
<string>6BF9B13511EB8CF20043574C</string>
<string>6BF9B13611EB8CF20043574C</string>
<string>6BF9B13711EB8CF20043574C</string>
<string>6BF9B18811EC2D470043574C</string>
<string>6BF9B1D111EC3DD80043574C</string>
<string>6BF9B1D311EC3DD80043574C</string>
<string>6BF9B1D411EC3DD80043574C</string>
<string>6BF9B1F011EC43FC0043574C</string>
<string>6BF9B1F111EC43FC0043574C</string>
<string>6BF9B1F211EC43FC0043574C</string>
<string>6BF9B1FC11EC442C0043574C</string>
<string>6BF9B20B11EC450E0043574C</string>
<string>6BF9B21111EC49A30043574C</string>
<string>6BF9B21211EC49A30043574C</string>
<string>6BF9B21311EC49A30043574C</string>
<string>6BF9B21B11EC49F90043574C</string>
<string>6BF9B21C11EC49F90043574C</string>
</array> </array>
<key>prevStack</key> <key>prevStack</key>
<array> <array>
<string>6BBB4AD2115B4F3400CF791D</string> <string>6BBB4AD2115B4F3400CF791D</string>
<string>6BBB4AD3115B4F3400CF791D</string> <string>6BBB4AD3115B4F3400CF791D</string>
<string>6BBB4AD4115B4F3400CF791D</string> <string>6BBB4AD4115B4F3400CF791D</string>
<string>6BBB4ADF115B4F3400CF791D</string>
<string>6BBB4AE0115B4F3400CF791D</string> <string>6BBB4AE0115B4F3400CF791D</string>
<string>6BBB4AE1115B4F3400CF791D</string> <string>6BBB4AE1115B4F3400CF791D</string>
<string>6BBB4AE2115B4F3400CF791D</string> <string>6BBB4AE2115B4F3400CF791D</string>
@ -442,7 +440,6 @@
<string>6BBB4B07115B4F3400CF791D</string> <string>6BBB4B07115B4F3400CF791D</string>
<string>6BBB4B08115B4F3400CF791D</string> <string>6BBB4B08115B4F3400CF791D</string>
<string>6BBB4B0A115B4F3400CF791D</string> <string>6BBB4B0A115B4F3400CF791D</string>
<string>6BBB4B0C115B4F3400CF791D</string>
<string>6BBB4C3B115B7A3D00CF791D</string> <string>6BBB4C3B115B7A3D00CF791D</string>
<string>6BF5F27811747CFA000502A6</string> <string>6BF5F27811747CFA000502A6</string>
<string>6BF5F28011747CFA000502A6</string> <string>6BF5F28011747CFA000502A6</string>
@ -453,253 +450,93 @@
<string>6B4215D1118066FE006C347B</string> <string>6B4215D1118066FE006C347B</string>
<string>6B4215DF1180672F006C347B</string> <string>6B4215DF1180672F006C347B</string>
<string>6B4216881180725E006C347B</string> <string>6B4216881180725E006C347B</string>
<string>6B555F481191AA4400843384</string>
<string>6B55625E1193EF2F00843384</string> <string>6B55625E1193EF2F00843384</string>
<string>6B5562631193EF2F00843384</string> <string>6B5562631193EF2F00843384</string>
<string>6B5562681193EF2F00843384</string> <string>6B5562681193EF2F00843384</string>
<string>6B5562FD1193F50A00843384</string>
<string>6B2CDD181197FE370090FA4D</string> <string>6B2CDD181197FE370090FA4D</string>
<string>6B2CDD71119810560090FA4D</string>
<string>6B57E94D11A7646800614060</string>
<string>6B10005C11AD08FA0098A59A</string> <string>6B10005C11AD08FA0098A59A</string>
<string>6B10011E11AD19F90098A59A</string> <string>6B10011E11AD19F90098A59A</string>
<string>6B10011F11AD19F90098A59A</string> <string>6B10011F11AD19F90098A59A</string>
<string>6BC7619C11B63C7E00FF5E51</string> <string>6BC7619C11B63C7E00FF5E51</string>
<string>6B98453E11E6013000FA177B</string>
<string>6B98453F11E6013000FA177B</string> <string>6B98453F11E6013000FA177B</string>
<string>6B98454311E6013000FA177B</string>
<string>6B98454511E6013000FA177B</string> <string>6B98454511E6013000FA177B</string>
<string>6B98454611E6013000FA177B</string>
<string>6B98454711E6013000FA177B</string>
<string>6B98454811E6013000FA177B</string>
<string>6B98454911E6013000FA177B</string>
<string>6B98454B11E6013000FA177B</string>
<string>6B98454D11E6013000FA177B</string>
<string>6B98454F11E6013000FA177B</string>
<string>6B98455011E6013000FA177B</string>
<string>6B98455111E6013000FA177B</string>
<string>6B98455211E6013000FA177B</string>
<string>6B98455311E6013000FA177B</string>
<string>6B98455411E6013000FA177B</string>
<string>6B98455511E6013000FA177B</string>
<string>6B98455611E6013000FA177B</string>
<string>6B98455711E6013000FA177B</string>
<string>6B98455811E6013000FA177B</string>
<string>6B98455911E6013000FA177B</string>
<string>6B98455A11E6013000FA177B</string>
<string>6B98455B11E6013000FA177B</string>
<string>6B98455C11E6013000FA177B</string>
<string>6B98455D11E6013000FA177B</string>
<string>6B98455E11E6013000FA177B</string>
<string>6B98455F11E6013000FA177B</string>
<string>6B98456011E6013000FA177B</string>
<string>6B98456311E6013000FA177B</string>
<string>6B98456411E6013000FA177B</string>
<string>6B98456511E6013000FA177B</string>
<string>6B98456611E6013000FA177B</string>
<string>6B98456711E6013000FA177B</string>
<string>6B98456811E6013000FA177B</string>
<string>6B98456911E6013000FA177B</string>
<string>6B98456A11E6013000FA177B</string>
<string>6B98456B11E6013000FA177B</string>
<string>6B98456C11E6013000FA177B</string>
<string>6B98456E11E6013000FA177B</string>
<string>6B98457011E6013000FA177B</string>
<string>6B98457211E6013000FA177B</string>
<string>6B98457411E6013000FA177B</string>
<string>6B98458A11E6039A00FA177B</string>
<string>6B98458B11E6039A00FA177B</string>
<string>6B98458C11E6039A00FA177B</string>
<string>6B98458D11E6039A00FA177B</string>
<string>6B98458E11E6039A00FA177B</string> <string>6B98458E11E6039A00FA177B</string>
<string>6B98458F11E6039A00FA177B</string>
<string>6B98459011E6039A00FA177B</string>
<string>6B98459111E6039A00FA177B</string>
<string>6B98459211E6039A00FA177B</string>
<string>6B98459311E6039A00FA177B</string>
<string>6B98459411E6039A00FA177B</string>
<string>6B98459511E6039A00FA177B</string>
<string>6B98459611E6039A00FA177B</string>
<string>6B98459711E6039A00FA177B</string>
<string>6B98459811E6039A00FA177B</string>
<string>6B98459911E6039A00FA177B</string>
<string>6B98459A11E6039A00FA177B</string>
<string>6B98459B11E6039A00FA177B</string>
<string>6B98459C11E6039A00FA177B</string>
<string>6B98459D11E6039A00FA177B</string>
<string>6B98459E11E6039A00FA177B</string>
<string>6B98459F11E6039A00FA177B</string>
<string>6B9845A011E6039A00FA177B</string>
<string>6B9845A111E6039A00FA177B</string>
<string>6B9845A211E6039A00FA177B</string>
<string>6B9845B911E609E600FA177B</string> <string>6B9845B911E609E600FA177B</string>
<string>6B9845BA11E609E600FA177B</string>
<string>6B9845BB11E609E600FA177B</string>
<string>6B9845BC11E609E600FA177B</string>
<string>6B9845BD11E609E600FA177B</string>
<string>6B9845D911E60DBB00FA177B</string>
<string>6B9845DA11E60DBB00FA177B</string>
<string>6B9845DB11E60DBB00FA177B</string>
<string>6B9845DC11E60DBB00FA177B</string>
<string>6B9845DD11E60DBB00FA177B</string>
<string>6B9845DE11E60DBB00FA177B</string>
<string>6B9845DF11E60DBB00FA177B</string>
<string>6B9845E011E60DBB00FA177B</string>
<string>6B9845E111E60DBB00FA177B</string> <string>6B9845E111E60DBB00FA177B</string>
<string>6B9845E211E60DBB00FA177B</string>
<string>6B9845E311E60DBB00FA177B</string>
<string>6B9845E411E60DBB00FA177B</string>
<string>6B9845E511E60DBB00FA177B</string>
<string>6B9845E611E60DBB00FA177B</string>
<string>6B9845E711E60DBB00FA177B</string>
<string>6B9845E811E60DBB00FA177B</string>
<string>6B9845E911E60DBB00FA177B</string>
<string>6B9845EA11E60DBB00FA177B</string>
<string>6B9845EB11E60DBB00FA177B</string>
<string>6B9845EC11E60DBB00FA177B</string>
<string>6B9845ED11E60DBB00FA177B</string>
<string>6B9845EE11E60DBB00FA177B</string>
<string>6B9845EF11E60DBB00FA177B</string>
<string>6B9845F711E60DDC00FA177B</string>
<string>6B98461711E60EE700FA177B</string>
<string>6B98461811E60EE700FA177B</string>
<string>6B98462611E612F100FA177B</string>
<string>6B98465011E6F9B400FA177B</string>
<string>6B98465111E6F9B400FA177B</string>
<string>6B98465211E6F9B400FA177B</string> <string>6B98465211E6F9B400FA177B</string>
<string>6B98465311E6F9B400FA177B</string>
<string>6B98465411E6F9B400FA177B</string> <string>6B98465411E6F9B400FA177B</string>
<string>6B98465611E6F9B400FA177B</string>
<string>6B98465711E6F9B400FA177B</string>
<string>6B98465911E6F9B400FA177B</string>
<string>6B98465A11E6F9B400FA177B</string>
<string>6B98465B11E6F9B400FA177B</string>
<string>6B98465D11E6F9B400FA177B</string>
<string>6B98465E11E6F9B400FA177B</string>
<string>6B98465F11E6F9B400FA177B</string>
<string>6B98466011E6F9B400FA177B</string> <string>6B98466011E6F9B400FA177B</string>
<string>6B98466111E6F9B400FA177B</string> <string>6B98466111E6F9B400FA177B</string>
<string>6B98466211E6F9B400FA177B</string>
<string>6B98466311E6F9B400FA177B</string>
<string>6B98466411E6F9B400FA177B</string>
<string>6B98466511E6F9B400FA177B</string>
<string>6B98466611E6F9B400FA177B</string>
<string>6B98467211E6FC1C00FA177B</string>
<string>6B98467311E6FC1C00FA177B</string>
<string>6B98467411E6FC1C00FA177B</string>
<string>6B98467511E6FC1C00FA177B</string>
<string>6B98467611E6FC1C00FA177B</string>
<string>6B98467711E6FC1C00FA177B</string>
<string>6B98467B11E6FE7000FA177B</string>
<string>6B98468211E6FF2000FA177B</string>
<string>6B98468311E6FF2000FA177B</string>
<string>6B98468411E6FF2000FA177B</string>
<string>6B98468511E6FF2000FA177B</string>
<string>6B98468C11E6FFC300FA177B</string>
<string>6B98468D11E6FFC300FA177B</string>
<string>6B98468E11E6FFC300FA177B</string>
<string>6B98469311E7053800FA177B</string>
<string>6B9846A311E7140300FA177B</string>
<string>6B9846A411E7140300FA177B</string>
<string>6B9846A511E7140300FA177B</string>
<string>6B9846A811E7140300FA177B</string>
<string>6B9846AA11E7140300FA177B</string>
<string>6B9846B411E7140300FA177B</string>
<string>6B9846B511E7140300FA177B</string>
<string>6B9846BB11E7145500FA177B</string>
<string>6B9846CB11E715C700FA177B</string>
<string>6B9846CC11E715C700FA177B</string>
<string>6B9846CD11E715C700FA177B</string>
<string>6B9846CE11E715C700FA177B</string>
<string>6B9846CF11E715C700FA177B</string>
<string>6B9846D011E715C700FA177B</string>
<string>6B9846D111E715C700FA177B</string>
<string>6B9846D711E716A200FA177B</string>
<string>6B9846E411E7172B00FA177B</string>
<string>6B9846E511E7172B00FA177B</string>
<string>6B9846E611E7172B00FA177B</string>
<string>6B9846E711E7172B00FA177B</string>
<string>6B9846E811E7172B00FA177B</string>
<string>6B9846E911E7172B00FA177B</string>
<string>6B9846EA11E7172B00FA177B</string>
<string>6B9846F811E7282C00FA177B</string>
<string>6B9846F911E7282C00FA177B</string>
<string>6B9846FA11E7282C00FA177B</string>
<string>6B9846FB11E7282C00FA177B</string>
<string>6B9846FC11E7282C00FA177B</string>
<string>6B9846FD11E7282C00FA177B</string>
<string>6B98470211E7285500FA177B</string>
<string>6B98470F11E734A100FA177B</string>
<string>6B98471011E734A100FA177B</string> <string>6B98471011E734A100FA177B</string>
<string>6B98471211E734A100FA177B</string> <string>6B98471211E734A100FA177B</string>
<string>6B98471311E734A100FA177B</string>
<string>6B98471411E734A100FA177B</string> <string>6B98471411E734A100FA177B</string>
<string>6B98471611E734A100FA177B</string>
<string>6B98471811E734A100FA177B</string>
<string>6B98471E11E734DF00FA177B</string>
<string>6B98471F11E734DF00FA177B</string>
<string>6B98472011E734DF00FA177B</string>
<string>6B98472111E734DF00FA177B</string>
<string>6B98472511E7356200FA177B</string>
<string>6B98472811E735A300FA177B</string>
<string>6B98472C11E7366600FA177B</string>
<string>6B98472D11E7366600FA177B</string>
<string>6B98473311E737D800FA177B</string>
<string>6B98473411E737D800FA177B</string>
<string>6B98473611E737D800FA177B</string>
<string>6B98473711E737D800FA177B</string>
<string>6B98473811E737D800FA177B</string>
<string>6B98473911E737D800FA177B</string>
<string>6B98473A11E737D800FA177B</string>
<string>6B98473B11E737D800FA177B</string>
<string>6B98473C11E737D800FA177B</string>
<string>6B98473D11E737D800FA177B</string>
<string>6B98473E11E737D800FA177B</string>
<string>6B98473F11E737D800FA177B</string>
<string>6B98474611E73ABF00FA177B</string>
<string>6B98474711E73ABF00FA177B</string>
<string>6B98474811E73ABF00FA177B</string>
<string>6B98474911E73ABF00FA177B</string>
<string>6B98474A11E73ABF00FA177B</string>
<string>6B98474B11E73ABF00FA177B</string>
<string>6B98474C11E73ABF00FA177B</string>
<string>6B98474D11E73ABF00FA177B</string>
<string>6B98474E11E73ABF00FA177B</string>
<string>6B98474F11E73ABF00FA177B</string>
<string>6B98475011E73ABF00FA177B</string>
<string>6B98475111E73ABF00FA177B</string>
<string>6B98475211E73ABF00FA177B</string>
<string>6B98475311E73ABF00FA177B</string>
<string>6B98475511E73ABF00FA177B</string>
<string>6B98475611E73ABF00FA177B</string>
<string>6B98475711E73ABF00FA177B</string>
<string>6B98476211E73D0100FA177B</string>
<string>6B98476311E73D0100FA177B</string>
<string>6B98476411E73D0100FA177B</string>
<string>6B98476511E73D0100FA177B</string>
<string>6B98477411E7406900FA177B</string> <string>6B98477411E7406900FA177B</string>
<string>6B98477911E7433F00FA177B</string> <string>6B98477911E7433F00FA177B</string>
<string>6B98478C11E74AB100FA177B</string>
<string>6B98478D11E74AB100FA177B</string>
<string>6B98478E11E74AB100FA177B</string>
<string>6B98478F11E74AB100FA177B</string>
<string>6B98479011E74AB100FA177B</string>
<string>6B98479111E74AB100FA177B</string>
<string>6B98479211E74AB100FA177B</string>
<string>6B98479311E74AB100FA177B</string>
<string>6B98479411E74AB100FA177B</string>
<string>6B98479511E74AB100FA177B</string>
<string>6B98479611E74AB100FA177B</string>
<string>6B9847A411E74BC100FA177B</string>
<string>6B9847A611E74BC100FA177B</string>
<string>6B9847A711E74BC100FA177B</string>
<string>6B9847A811E74BC100FA177B</string>
<string>6B9847B011E74FAB00FA177B</string>
<string>6B9847BD11E751AC00FA177B</string>
<string>6B9847BE11E751AC00FA177B</string>
<string>6B9847BF11E751AC00FA177B</string>
<string>6B9847C011E751AC00FA177B</string>
<string>6B9847C511E752CC00FA177B</string> <string>6B9847C511E752CC00FA177B</string>
<string>6BF9B13B11EB8CF20043574C</string>
<string>6BF9B13C11EB8CF20043574C</string>
<string>6BF9B13D11EB8CF20043574C</string>
<string>6BF9B13E11EB8CF20043574C</string>
<string>6BF9B13F11EB8CF20043574C</string>
<string>6BF9B14111EB8CF20043574C</string>
<string>6BF9B14211EB8CF20043574C</string>
<string>6BF9B14311EB8CF20043574C</string>
<string>6BF9B14511EB8CF20043574C</string>
<string>6BF9B14611EB8CF20043574C</string>
<string>6BF9B14711EB8CF20043574C</string>
<string>6BF9B14A11EB8CF20043574C</string>
<string>6BF9B14E11EB8CF20043574C</string>
<string>6BF9B15011EB8CF20043574C</string>
<string>6BF9B15111EB8CF20043574C</string>
<string>6BF9B15411EB8CF20043574C</string>
<string>6BF9B15511EB8CF20043574C</string>
<string>6BF9B15611EB8CF20043574C</string>
<string>6BF9B15711EB8CF20043574C</string>
<string>6BF9B15911EB8CF20043574C</string>
<string>6BF9B15C11EB8CF20043574C</string>
<string>6BF9B15D11EB8CF20043574C</string>
<string>6BF9B15E11EB8CF20043574C</string>
<string>6BF9B15F11EB8CF20043574C</string>
<string>6BF9B16011EB8CF20043574C</string>
<string>6BF9B16111EB8CF20043574C</string>
<string>6BF9B16211EB8CF20043574C</string>
<string>6BF9B16311EB8CF20043574C</string>
<string>6BF9B16411EB8CF20043574C</string>
<string>6BF9B16511EB8CF20043574C</string>
<string>6BF9B16611EB8CF20043574C</string>
<string>6BF9B16911EB8CF20043574C</string>
<string>6BF9B17B11EC2B780043574C</string>
<string>6BF9B18B11EC2D470043574C</string>
<string>6BF9B19011EC2DAE0043574C</string>
<string>6BF9B19B11EC35DF0043574C</string>
<string>6BF9B1A211EC361E0043574C</string>
<string>6BF9B1A711EC36460043574C</string>
<string>6BF9B1AE11EC36DA0043574C</string>
<string>6BF9B1B311EC37080043574C</string>
<string>6BF9B1BD11EC3A0D0043574C</string>
<string>6BF9B1BF11EC3A0D0043574C</string>
<string>6BF9B1C111EC3A0D0043574C</string>
<string>6BF9B1C311EC3A0D0043574C</string>
<string>6BF9B1C411EC3A0D0043574C</string>
<string>6BF9B1C511EC3A0D0043574C</string>
<string>6BF9B1D611EC3DD80043574C</string>
<string>6BF9B1D811EC3DD80043574C</string>
<string>6BF9B1D911EC3DD80043574C</string>
<string>6BF9B1DA11EC3DD80043574C</string>
<string>6BF9B1DB11EC3DD80043574C</string>
<string>6BF9B1DC11EC3DD80043574C</string>
<string>6BF9B1E611EC428F0043574C</string>
<string>6BF9B1EB11EC43120043574C</string>
<string>6BF9B1F411EC43FC0043574C</string>
<string>6BF9B1F511EC43FC0043574C</string>
<string>6BF9B1F611EC43FC0043574C</string>
<string>6BF9B1FE11EC442C0043574C</string>
<string>6BF9B14911EB8CF20043574C</string>
<string>6BF9B20D11EC450E0043574C</string>
<string>6BF9B21511EC49A30043574C</string>
<string>6BF9B21611EC49A30043574C</string>
<string>6BF9B21711EC49A30043574C</string>
<string>6BF9B21D11EC49F90043574C</string>
</array> </array>
</dict> </dict>
<key>SplitCount</key> <key>SplitCount</key>
@ -713,18 +550,18 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {887, 441}}</string> <string>{{0, 0}, {887, 444}}</string>
<key>RubberWindowFrame</key> <key>RubberWindowFrame</key>
<string>33 87 1173 691 0 0 1280 778 </string> <string>33 87 1173 691 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXNavigatorGroup</string> <string>PBXNavigatorGroup</string>
<key>Proportion</key> <key>Proportion</key>
<string>441pt</string> <string>444pt</string>
</dict> </dict>
<dict> <dict>
<key>Proportion</key> <key>Proportion</key>
<string>204pt</string> <string>202pt</string>
<key>Tabs</key> <key>Tabs</key>
<array> <array>
<dict> <dict>
@ -738,7 +575,7 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {887, 102}}</string> <string>{{10, 27}, {887, 38}}</string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>XCDetailModule</string> <string>XCDetailModule</string>
@ -754,7 +591,9 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {887, 110}}</string> <string>{{10, 27}, {887, 175}}</string>
<key>RubberWindowFrame</key>
<string>33 87 1173 691 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXProjectFindModule</string> <string>PBXProjectFindModule</string>
@ -792,9 +631,7 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{10, 27}, {887, 177}}</string> <string>{{10, 27}, {887, 113}}</string>
<key>RubberWindowFrame</key>
<string>33 87 1173 691 0 0 1280 778 </string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXBuildResultsModule</string> <string>PBXBuildResultsModule</string>
@ -822,11 +659,11 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>6B98451A11E5E81100FA177B</string> <string>6BF9B11A11EB75D30043574C</string>
<string>1CA23ED40692098700951B8B</string> <string>1CA23ED40692098700951B8B</string>
<string>6B98451B11E5E81100FA177B</string> <string>6BF9B11B11EB75D30043574C</string>
<string>6B8632A30F78115100E2684A</string> <string>6B8632A30F78115100E2684A</string>
<string>6B98451C11E5E81100FA177B</string> <string>6BF9B11C11EB75D30043574C</string>
<string>1CA23EDF0692099D00951B8B</string> <string>1CA23EDF0692099D00951B8B</string>
<string>1CA23EE00692099D00951B8B</string> <string>1CA23EE00692099D00951B8B</string>
<string>1CA23EE10692099D00951B8B</string> <string>1CA23EE10692099D00951B8B</string>
@ -877,12 +714,12 @@
<key>GeometryConfiguration</key> <key>GeometryConfiguration</key>
<dict> <dict>
<key>Frame</key> <key>Frame</key>
<string>{{0, 0}, {1173, 331}}</string> <string>{{0, 0}, {1173, 380}}</string>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXDebugCLIModule</string> <string>PBXDebugCLIModule</string>
<key>Proportion</key> <key>Proportion</key>
<string>331pt</string> <string>380pt</string>
</dict> </dict>
<dict> <dict>
<key>ContentConfiguration</key> <key>ContentConfiguration</key>
@ -901,8 +738,8 @@
<string>yes</string> <string>yes</string>
<key>sizes</key> <key>sizes</key>
<array> <array>
<string>{{0, 0}, {537, 86}}</string> <string>{{0, 0}, {532, 93}}</string>
<string>{{537, 0}, {636, 86}}</string> <string>{{532, 0}, {641, 93}}</string>
</array> </array>
</dict> </dict>
<key>VerticalSplitView</key> <key>VerticalSplitView</key>
@ -917,8 +754,8 @@
<string>yes</string> <string>yes</string>
<key>sizes</key> <key>sizes</key>
<array> <array>
<string>{{0, 0}, {1173, 86}}</string> <string>{{0, 0}, {1173, 93}}</string>
<string>{{0, 86}, {1173, 228}}</string> <string>{{0, 93}, {1173, 172}}</string>
</array> </array>
</dict> </dict>
</dict> </dict>
@ -938,7 +775,7 @@
<key>DebugSTDIOWindowFrame</key> <key>DebugSTDIOWindowFrame</key>
<string>{{200, 200}, {500, 300}}</string> <string>{{200, 200}, {500, 300}}</string>
<key>Frame</key> <key>Frame</key>
<string>{{0, 336}, {1173, 314}}</string> <string>{{0, 385}, {1173, 265}}</string>
<key>PBXDebugSessionStackFrameViewKey</key> <key>PBXDebugSessionStackFrameViewKey</key>
<dict> <dict>
<key>DebugVariablesTableConfiguration</key> <key>DebugVariablesTableConfiguration</key>
@ -948,16 +785,16 @@
<string>Value</string> <string>Value</string>
<real>85</real> <real>85</real>
<string>Summary</string> <string>Summary</string>
<real>343</real> <real>348</real>
</array> </array>
<key>Frame</key> <key>Frame</key>
<string>{{537, 0}, {636, 86}}</string> <string>{{532, 0}, {641, 93}}</string>
</dict> </dict>
</dict> </dict>
<key>Module</key> <key>Module</key>
<string>PBXDebugSessionModule</string> <string>PBXDebugSessionModule</string>
<key>Proportion</key> <key>Proportion</key>
<string>314pt</string> <string>265pt</string>
</dict> </dict>
</array> </array>
<key>Name</key> <key>Name</key>
@ -975,14 +812,14 @@
</array> </array>
<key>TableOfContents</key> <key>TableOfContents</key>
<array> <array>
<string>6B98457611E6013000FA177B</string> <string>6BF9B16D11EB8D0B0043574C</string>
<string>1CCC7628064C1048000F2A68</string> <string>1CCC7628064C1048000F2A68</string>
<string>1CCC7629064C1048000F2A68</string> <string>1CCC7629064C1048000F2A68</string>
<string>6B98457711E6013000FA177B</string> <string>6BF9B16E11EB8D0B0043574C</string>
<string>6B98457811E6013000FA177B</string> <string>6BF9B16F11EB8D0B0043574C</string>
<string>6B98457911E6013000FA177B</string> <string>6BF9B17011EB8D0B0043574C</string>
<string>6B98457A11E6013000FA177B</string> <string>6BF9B17111EB8D0B0043574C</string>
<string>6B98457B11E6013000FA177B</string> <string>6B8632A30F78115100E2684A</string>
</array> </array>
<key>ToolbarConfigUserDefaultsMinorVersion</key> <key>ToolbarConfigUserDefaultsMinorVersion</key>
<string>2</string> <string>2</string>
@ -1014,8 +851,8 @@
<integer>5</integer> <integer>5</integer>
<key>WindowOrderList</key> <key>WindowOrderList</key>
<array> <array>
<string>6B9845FA11E60DDC00FA177B</string> <string>6BF9B17211EB8D0B0043574C</string>
<string>6B9845FB11E60DDC00FA177B</string> <string>6BF9B17311EB8D0B0043574C</string>
<string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string> <string>/Users/memon/Code/recastnavigation/RecastDemo/Build/Xcode/Recast.xcodeproj</string>
</array> </array>
<key>WindowString</key> <key>WindowString</key>

View File

@ -31,7 +31,7 @@ protected:
rcBuildTimes m_buildTimes; rcBuildTimes m_buildTimes;
float m_totalBuildTimeMs; float m_totalBuildTimeMs;
unsigned char* m_triflags; unsigned char* m_triareas;
rcHeightfield* m_solid; rcHeightfield* m_solid;
rcCompactHeightfield* m_chf; rcCompactHeightfield* m_chf;
rcContourSet* m_cset; rcContourSet* m_cset;

View File

@ -34,7 +34,9 @@ protected:
float m_totalBuildTimeMs; float m_totalBuildTimeMs;
bool m_drawPortals; bool m_drawPortals;
unsigned char* m_triflags; int m_smin, m_smax;
unsigned char* m_triareas;
rcHeightfield* m_solid; rcHeightfield* m_solid;
rcCompactHeightfield* m_chf; rcCompactHeightfield* m_chf;
rcContourSet* m_cset; rcContourSet* m_cset;

View File

@ -45,7 +45,7 @@
Sample_SoloMeshSimple::Sample_SoloMeshSimple() : Sample_SoloMeshSimple::Sample_SoloMeshSimple() :
m_keepInterResults(true), m_keepInterResults(true),
m_totalBuildTimeMs(0), m_totalBuildTimeMs(0),
m_triflags(0), m_triareas(0),
m_solid(0), m_solid(0),
m_chf(0), m_chf(0),
m_cset(0), m_cset(0),
@ -63,8 +63,8 @@ Sample_SoloMeshSimple::~Sample_SoloMeshSimple()
void Sample_SoloMeshSimple::cleanup() void Sample_SoloMeshSimple::cleanup()
{ {
delete [] m_triflags; delete [] m_triareas;
m_triflags = 0; m_triareas = 0;
rcFreeHeightField(m_solid); rcFreeHeightField(m_solid);
m_solid = 0; m_solid = 0;
rcFreeCompactHeightfield(m_chf); rcFreeCompactHeightfield(m_chf);
@ -407,28 +407,28 @@ bool Sample_SoloMeshSimple::handleBuild()
return false; return false;
} }
// Allocate array that can hold triangle flags. // Allocate array that can hold triangle area types.
// If you have multiple meshes you need to process, allocate // If you have multiple meshes you need to process, allocate
// and array which can hold the max number of triangles you need to process. // and array which can hold the max number of triangles you need to process.
m_triflags = new unsigned char[ntris]; m_triareas = new unsigned char[ntris];
if (!m_triflags) if (!m_triareas)
{ {
if (rcGetLog()) if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'triangleFlags' (%d).", ntris); rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", ntris);
return false; return false;
} }
// Find triangles which are walkable based on their slope and rasterize them. // Find triangles which are walkable based on their slope and rasterize them.
// If your input data is multiple meshes, you can transform them here, calculate // If your input data is multiple meshes, you can transform them here, calculate
// the flags for each of the meshes and rasterize them. // the are type for each of the meshes and rasterize them.
memset(m_triflags, 0, ntris*sizeof(unsigned char)); memset(m_triareas, 0, ntris*sizeof(unsigned char));
rcMarkWalkableTriangles(m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triflags); rcMarkWalkableTriangles(m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triareas);
rcRasterizeTriangles(verts, nverts, tris, m_triflags, ntris, *m_solid, m_cfg.walkableClimb); rcRasterizeTriangles(verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb);
if (!m_keepInterResults) if (!m_keepInterResults)
{ {
delete [] m_triflags; delete [] m_triareas;
m_triflags = 0; m_triareas = 0;
} }
// //
@ -457,7 +457,7 @@ bool Sample_SoloMeshSimple::handleBuild()
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'."); rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
return false; return false;
} }
if (!rcBuildCompactHeightfield(m_cfg.walkableHeight, m_cfg.walkableClimb, RC_WALKABLE, *m_solid, *m_chf)) if (!rcBuildCompactHeightfield(m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid, *m_chf))
{ {
if (rcGetLog()) if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data."); rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
@ -471,7 +471,7 @@ bool Sample_SoloMeshSimple::handleBuild()
} }
// Erode the walkable area by agent radius. // Erode the walkable area by agent radius.
if (!rcErodeArea(RC_WALKABLE_AREA, m_cfg.walkableRadius, *m_chf)) if (!rcErodeWalkableArea(m_cfg.walkableRadius, *m_chf))
{ {
if (rcGetLog()) if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not erode."); rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not erode.");
@ -668,6 +668,7 @@ bool Sample_SoloMeshSimple::handleBuild()
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Median area: %.1fms (%.1f%%)", m_buildTimes.filterMedian/1000.0f, m_buildTimes.filterMedian*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc); rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc);

View File

@ -764,12 +764,12 @@ bool Sample_SoloMeshTiled::handleBuild()
tileCfg.height = m_cfg.tileSize + m_cfg.borderSize*2; tileCfg.height = m_cfg.tileSize + m_cfg.borderSize*2;
// Allocate array that can hold triangle flags for all geom chunks. // Allocate array that can hold triangle flags for all geom chunks.
unsigned char* triangleFlags = new unsigned char[chunkyMesh->maxTrisPerChunk]; unsigned char* triangleAreas = new unsigned char[chunkyMesh->maxTrisPerChunk];
if (!triangleFlags) if (!triangleAreas)
{ {
if (rcGetLog()) if (rcGetLog())
{ {
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'triangleFlags' (%d).", rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Out of memory 'triangleAreas' (%d).",
chunkyMesh->maxTrisPerChunk); chunkyMesh->maxTrisPerChunk);
} }
return false; return false;
@ -795,11 +795,6 @@ bool Sample_SoloMeshTiled::handleBuild()
tileCfg.bmax[0] = m_cfg.bmin[0] + ((x+1)*m_cfg.tileSize + m_cfg.borderSize)*m_cfg.cs; tileCfg.bmax[0] = m_cfg.bmin[0] + ((x+1)*m_cfg.tileSize + m_cfg.borderSize)*m_cfg.cs;
tileCfg.bmax[2] = m_cfg.bmin[2] + ((y+1)*m_cfg.tileSize + m_cfg.borderSize)*m_cfg.cs; tileCfg.bmax[2] = m_cfg.bmin[2] + ((y+1)*m_cfg.tileSize + m_cfg.borderSize)*m_cfg.cs;
/* delete solid;
delete chf;
solid = 0;
chf = 0;*/
float tbmin[2], tbmax[2]; float tbmin[2], tbmax[2];
tbmin[0] = tileCfg.bmin[0]; tbmin[0] = tileCfg.bmin[0];
tbmin[1] = tileCfg.bmin[2]; tbmin[1] = tileCfg.bmin[2];
@ -830,11 +825,11 @@ bool Sample_SoloMeshTiled::handleBuild()
const int* tris = &chunkyMesh->tris[node.i*3]; const int* tris = &chunkyMesh->tris[node.i*3];
const int ntris = node.n; const int ntris = node.n;
memset(triangleFlags, 0, ntris*sizeof(unsigned char)); memset(triangleAreas, 0, ntris*sizeof(unsigned char));
rcMarkWalkableTriangles(tileCfg.walkableSlopeAngle, rcMarkWalkableTriangles(tileCfg.walkableSlopeAngle,
verts, nverts, tris, ntris, triangleFlags); verts, nverts, tris, ntris, triangleAreas);
rcRasterizeTriangles(verts, nverts, tris, triangleFlags, ntris, *tile.solid, m_cfg.walkableClimb); rcRasterizeTriangles(verts, nverts, tris, triangleAreas, ntris, *tile.solid, m_cfg.walkableClimb);
} }
rcFilterLowHangingWalkableObstacles(m_cfg.walkableClimb, *tile.solid); rcFilterLowHangingWalkableObstacles(m_cfg.walkableClimb, *tile.solid);
@ -849,7 +844,7 @@ bool Sample_SoloMeshTiled::handleBuild()
continue; continue;
} }
if (!rcBuildCompactHeightfield(tileCfg.walkableHeight, tileCfg.walkableClimb, if (!rcBuildCompactHeightfield(tileCfg.walkableHeight, tileCfg.walkableClimb,
RC_WALKABLE, *tile.solid, *tile.chf)) *tile.solid, *tile.chf))
{ {
if (rcGetLog()) if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build compact data.", x, y); rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: [%d,%d] Could not build compact data.", x, y);
@ -857,7 +852,7 @@ bool Sample_SoloMeshTiled::handleBuild()
} }
// Erode the walkable area by agent radius. // Erode the walkable area by agent radius.
if (!rcErodeArea(RC_WALKABLE_AREA, m_cfg.walkableRadius, *tile.chf)) if (!rcErodeWalkableArea(m_cfg.walkableRadius, *tile.chf))
{ {
if (rcGetLog()) if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not erode."); rcGetLog()->log(RC_LOG_ERROR, "buildTiledNavigation: Could not erode.");
@ -957,9 +952,7 @@ bool Sample_SoloMeshTiled::handleBuild()
} }
} }
delete [] triangleFlags; delete [] triangleAreas;
// delete solid;
// delete chf;
// Merge per tile poly and detail meshes. // Merge per tile poly and detail meshes.
rcPolyMesh** pmmerge = new rcPolyMesh*[m_tileSet->width*m_tileSet->height]; rcPolyMesh** pmmerge = new rcPolyMesh*[m_tileSet->width*m_tileSet->height];
@ -1126,6 +1119,7 @@ bool Sample_SoloMeshTiled::handleBuild()
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Median area: %.1fms (%.1f%%)", m_buildTimes.filterMedian/1000.0f, m_buildTimes.filterMedian*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc); rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc);

View File

@ -170,7 +170,7 @@ Sample_TileMesh::Sample_TileMesh() :
m_buildAll(true), m_buildAll(true),
m_totalBuildTimeMs(0), m_totalBuildTimeMs(0),
m_drawPortals(false), m_drawPortals(false),
m_triflags(0), m_triareas(0),
m_solid(0), m_solid(0),
m_chf(0), m_chf(0),
m_cset(0), m_cset(0),
@ -189,6 +189,9 @@ Sample_TileMesh::Sample_TileMesh() :
memset(m_tileBmax, 0, sizeof(m_tileBmax)); memset(m_tileBmax, 0, sizeof(m_tileBmax));
setTool(new NavMeshTileTool); setTool(new NavMeshTileTool);
m_smin = 0x0fffffff;
m_smax = -0xfffffff;
} }
Sample_TileMesh::~Sample_TileMesh() Sample_TileMesh::~Sample_TileMesh()
@ -200,8 +203,8 @@ Sample_TileMesh::~Sample_TileMesh()
void Sample_TileMesh::cleanup() void Sample_TileMesh::cleanup()
{ {
delete [] m_triflags; delete [] m_triareas;
m_triflags = 0; m_triareas = 0;
rcFreeHeightField(m_solid); rcFreeHeightField(m_solid);
m_solid = 0; m_solid = 0;
rcFreeCompactHeightfield(m_chf); rcFreeCompactHeightfield(m_chf);
@ -767,11 +770,11 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
// Allocate array that can hold triangle flags. // Allocate array that can hold triangle flags.
// If you have multiple meshes you need to process, allocate // If you have multiple meshes you need to process, allocate
// and array which can hold the max number of triangles you need to process. // and array which can hold the max number of triangles you need to process.
m_triflags = new unsigned char[chunkyMesh->maxTrisPerChunk]; m_triareas = new unsigned char[chunkyMesh->maxTrisPerChunk];
if (!m_triflags) if (!m_triareas)
{ {
if (rcGetLog()) if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'triangleFlags' (%d).", chunkyMesh->maxTrisPerChunk); rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", chunkyMesh->maxTrisPerChunk);
return 0; return 0;
} }
@ -796,19 +799,38 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
m_tileTriCount += ntris; m_tileTriCount += ntris;
memset(m_triflags, 0, ntris*sizeof(unsigned char)); memset(m_triareas, 0, ntris*sizeof(unsigned char));
rcMarkWalkableTriangles(m_cfg.walkableSlopeAngle, rcMarkWalkableTriangles(m_cfg.walkableSlopeAngle,
verts, nverts, tris, ntris, m_triflags); verts, nverts, tris, ntris, m_triareas);
rcRasterizeTriangles(verts, nverts, tris, m_triflags, ntris, *m_solid, m_cfg.walkableClimb); rcRasterizeTriangles(verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb);
} }
if (!m_keepInterResults) if (!m_keepInterResults)
{ {
delete [] m_triflags; delete [] m_triareas;
m_triflags = 0; m_triareas = 0;
} }
{
const int w = m_solid->width;
const int h = m_solid->height;
int spanCount = 0;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
for (rcSpan* s = m_solid->spans[x + y*w]; s; s = s->next)
{
m_smin = rcMin(m_smin, (int)s->smin);
m_smax = rcMax(m_smax, (int)s->smax);
}
}
}
printf("smin=%d smax=%d\n", m_smin, m_smax);
}
// Once all geoemtry is rasterized, we do initial pass of filtering to // Once all geoemtry is rasterized, we do initial pass of filtering to
// remove unwanted overhangs caused by the conservative rasterization // remove unwanted overhangs caused by the conservative rasterization
// as well as filter spans where the character cannot possibly stand. // as well as filter spans where the character cannot possibly stand.
@ -826,7 +848,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'."); rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
return 0; return 0;
} }
if (!rcBuildCompactHeightfield(m_cfg.walkableHeight, m_cfg.walkableClimb, RC_WALKABLE, *m_solid, *m_chf)) if (!rcBuildCompactHeightfield(m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid, *m_chf))
{ {
if (rcGetLog()) if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data."); rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
@ -840,7 +862,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
} }
// Erode the walkable area by agent radius. // Erode the walkable area by agent radius.
if (!rcErodeArea(RC_WALKABLE_AREA, m_cfg.walkableRadius, *m_chf)) if (!rcErodeWalkableArea(m_cfg.walkableRadius, *m_chf))
{ {
if (rcGetLog()) if (rcGetLog())
rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not erode."); rcGetLog()->log(RC_LOG_ERROR, "buildNavigation: Could not erode.");
@ -1027,6 +1049,7 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Filter Reachable: %.1fms (%.1f%%)", m_buildTimes.filterMarkReachable/1000.0f, m_buildTimes.filterMarkReachable*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Erode walkable area: %.1fms (%.1f%%)", m_buildTimes.erodeArea/1000.0f, m_buildTimes.erodeArea*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Median area: %.1fms (%.1f%%)", m_buildTimes.filterMedian/1000.0f, m_buildTimes.filterMedian*pc);
rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc); rcGetLog()->log(RC_LOG_PROGRESS, "Build Distancefield: %.1fms (%.1f%%)", m_buildTimes.buildDistanceField/1000.0f, m_buildTimes.buildDistanceField*pc);
rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc); rcGetLog()->log(RC_LOG_PROGRESS, " - distance: %.1fms (%.1f%%)", m_buildTimes.buildDistanceFieldDist/1000.0f, m_buildTimes.buildDistanceFieldDist*pc);