Skip to content

Commit

Permalink
Fixed mem leaks with layers. Added layer region generation test.
Browse files Browse the repository at this point in the history
git-svn-id: http://recastnavigation.googlecode.com/svn/trunk@278 678f7576-1c49-11de-8b5c-13accb87f508
  • Loading branch information
memononen committed Feb 27, 2011
1 parent 29a9f34 commit 38a2f5f
Show file tree
Hide file tree
Showing 7 changed files with 397 additions and 44 deletions.
1 change: 1 addition & 0 deletions DebugUtils/Include/RecastDebugDraw.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void duDebugDrawCompactHeightfieldDistance(struct duDebugDraw* dd, const struct
void duDebugDrawLeanHeightfieldSolid(duDebugDraw* dd, const struct rcLeanHeightfield& lhf);

void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset);
void duDebugDrawHeightfieldLayersRegions(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset);

void duDebugDrawRegionConnections(struct duDebugDraw* dd, const struct rcContourSet& cset, const float alpha = 1.0f);
void duDebugDrawRawContours(struct duDebugDraw* dd, const struct rcContourSet& cset, const float alpha = 1.0f);
Expand Down
94 changes: 91 additions & 3 deletions DebugUtils/Source/RecastDebugDraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,13 +329,14 @@ void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLay

const float cs = lset.cs;
const float ch = lset.ch;
const int w = lset.width;
const int h = lset.height;

for (int i = 0; i < lset.nlayers; ++i)
{
const rcHeightfieldLayer* layer = &lset.layers[i];


const int w = layer->width;
const int h = layer->height;

unsigned int color = duIntToCol(i+1, 255);

// Layer bounds
Expand Down Expand Up @@ -415,6 +416,93 @@ void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLay

}

void duDebugDrawHeightfieldLayersRegions(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset)
{
if (!dd) return;

const float cs = lset.cs;
const float ch = lset.ch;

for (int i = 0; i < lset.nlayers; ++i)
{
const rcHeightfieldLayer* layer = &lset.layers[i];

const int w = layer->width;
const int h = layer->height;

unsigned int color = duIntToCol(i+1, 255);

// Layer bounds
float bmin[3], bmax[3];
rcVcopy(bmin, lset.bmin);
rcVcopy(bmax, lset.bmax);
bmin[1] = lset.bmin[1] + (layer->ymin-1)*ch;
bmax[1] = lset.bmin[1] + (layer->ymax+1)*ch;
duDebugDrawBoxWire(dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duTransCol(color,128), 2.0f);

// Layer height
dd->begin(DU_DRAW_QUADS);
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
const int idx = x+y*w;
const int h = (int)layer->heights[idx];
if (h == 0xffff) continue;
const unsigned char area = layer->regs ? layer->regs[idx]+1 : 1;

unsigned int col = duLerpCol(color, duIntToCol(area, 255), 128);

const float fx = lset.bmin[0] + x*cs;
const float fy = lset.bmin[1] + (h+1)*ch;
const float fz = lset.bmin[2] + y*cs;

dd->vertex(fx, fy, fz, col);
dd->vertex(fx, fy, fz+cs, col);
dd->vertex(fx+cs, fy, fz+cs, col);
dd->vertex(fx+cs, fy, fz, col);
}
}
dd->end();

/* // Portals
unsigned int pcol = duLerpCol(color,duRGBA(255,255,255,255),128);
dd->begin(DU_DRAW_LINES, 2.0f);
for (int j = 0; j < layer->nportals; ++j)
{
const rcHeightfieldLayerPortal* portal = &layer->portals[j];
if (portal->dir == 0 || portal->dir == 2)
{
const int ha = (int)layer->heights[portal->pos + portal->smin*w];
const int hb = (int)layer->heights[portal->pos + (portal->smax-1)*w];
const int xx = (portal->dir == 0) ? portal->pos : portal->pos+1;
const float fx = lset.bmin[0] + xx*cs;
const float fya = lset.bmin[1] + (ha+4)*ch;
const float fyb = lset.bmin[1] + (hb+4)*ch;
const float fza = lset.bmin[2] + portal->smin*cs;
const float fzb = lset.bmin[2] + portal->smax*cs;
dd->vertex(fx, fya, fza, pcol);
dd->vertex(fx, fyb, fzb, pcol);
}
else if (portal->dir == 3 || portal->dir == 1)
{
const int ha = (int)layer->heights[portal->smin + portal->pos*w];
const int hb = (int)layer->heights[(portal->smax-1) + portal->pos*w];
const int yy = (portal->dir == 3) ? portal->pos : portal->pos+1;
const float fxa = lset.bmin[0] + portal->smin*cs;
const float fxb = lset.bmin[0] + portal->smax*cs;
const float fya = lset.bmin[1] + (ha+3)*ch;
const float fyb = lset.bmin[1] + (hb+3)*ch;
const float fz = lset.bmin[2] + yy*cs;
dd->vertex(fxa, fya, fz, pcol);
dd->vertex(fxb, fyb, fz, pcol);
}
}
dd->end();*/
}

}

static void getContourCenter(const rcContour* cont, const float* orig, float cs, float ch, float* center)
{
center[0] = 0;
Expand Down
85 changes: 49 additions & 36 deletions Recast/Include/Recast.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,38 @@ struct rcLeanHeightfield
};



struct rcHeightfieldLayerPortal
{
unsigned short pos; // Position of the portal.
unsigned short smin, smax; // Span min/max of the portal.
unsigned char dir; // Direction of the portal (same as used by rcGetCon()).
};

struct rcHeightfieldLayer
{
int width, height; // Width and height of the layer.
int nportals; // Number of portals.
unsigned short ymin, ymax; // Height min/max range.
unsigned short* heights; // Heighfield.
unsigned char* areas; // Area types.
unsigned char* regs; // Regions.
rcHeightfieldLayerPortal* portals; // Portals.
};

struct rcHeightfieldLayerSet
{
rcHeightfieldLayer* layers; // Pointer to layers.
int nlayers; // Number of layers.
float bmin[3], bmax[3]; // Bounding box of the heightfield.
float cs, ch; // Cell size and height.
};

rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet();
void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset);



struct rcContour
{
int* verts; // Vertex coordinates, each vertex contains 4 components.
Expand Down Expand Up @@ -680,6 +712,7 @@ bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf);
// Here area means the count of spans in an area.
// Params:
// chf - (in/out) compact heightfield representing the open space.
// borderSize - (in) Non-navigable Border around the heightfield.
// minRegionArea - (in) the smallest allowed region area.
// maxMergeRegionArea - (in) the largest allowed region area which can be merged.
// Returns false if operation ran out of memory.
Expand All @@ -696,12 +729,28 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
// Here area means the count of spans in an area.
// Params:
// chf - (in/out) compact heightfield representing the open space.
// borderSize - (in) Non-navigable Border around the heightfield.
// minRegionArea - (in) the smallest allowed regions size.
// maxMergeRegionArea - (in) the largest allowed regions size which can be merged.
// Returns false if operation ran out of memory.
bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf,
const int borderSize, const int minRegionArea, const int mergeRegionArea);

// Builds 2D layer representation of a heighfield.
// Params:
// chf - (in) compact heightfield representing the open space.
// borderSize - (in) Non-navigable Border around the heightfield.
// walkableHeight - (in) minimum height where the agent can still walk.
// lset - (out) set of 2D heighfield layers.
// Returns false if operation ran out of memory.
bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
const int borderSize, const int walkableHeight,
rcHeightfieldLayerSet& lset);

// TODO: move this somewhere else, once the layer meshing is done.
bool rcBuildLayerRegions(rcContext* ctx, rcHeightfieldLayer& layer, const int walkableClimb);


// Builds simplified contours from the regions outlines.
// Params:
// chf - (in) compact heightfield which has regions set.
Expand Down Expand Up @@ -740,40 +789,4 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int



// TODO: Put in right place!
struct rcHeightfieldLayerPortal
{
unsigned short pos, smin, smax;
unsigned char dir;
};

struct rcHeightfieldLayer
{
unsigned short ymin, ymax;
unsigned short* heights;
unsigned char* areas;
rcHeightfieldLayerPortal* portals;
int nportals;
};

struct rcHeightfieldLayerSet
{
rcHeightfieldLayer* layers;
int nlayers;
int width, height;
int borderSize;
float bmin[3], bmax[3]; // Bounding box of the heightfield.
float cs, ch; // Cell size and height.
};

rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet();
void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset);


bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
const int borderSize, const int walkableHeight,
rcHeightfieldLayerSet& lset);



#endif // RECAST_H
2 changes: 2 additions & 0 deletions Recast/Source/Recast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset)
{
rcFree(lset->layers[i].heights);
rcFree(lset->layers[i].areas);
rcFree(lset->layers[i].regs);
rcFree(lset->layers[i].portals);
}
rcFree(lset->layers);
rcFree(lset);
Expand Down
Loading

0 comments on commit 38a2f5f

Please sign in to comment.