Removed layer portals, added cons, which stores connectivity and portals. Layer heights is stored as bytes.

This commit is contained in:
Mikko Mononen 2011-03-11 15:12:15 +00:00
parent 9f2390e196
commit b6a93f063a
7 changed files with 156 additions and 245 deletions

View File

@ -385,7 +385,44 @@ static void drawLayerPortals(duDebugDraw* dd, const rcHeightfieldLayer* layer, c
{
const float cs = layer->cs;
const float ch = layer->ch;
const float h = (layer->ymax-layer->ymin+1)*ch;
const int w = layer->width;
const int h = layer->height;
unsigned int pcol = duRGBA(255,255,255,255);
const int segs[4*4] = {0,0,0,1, 0,1,1,1, 1,1,1,0, 1,0,0,0};
// Layer portals
dd->begin(DU_DRAW_LINES, 2.0f);
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 == 255) continue;
for (int dir = 0; dir < 4; ++dir)
{
if (layer->cons[idx] & (1<<(dir+4)))
{
const int* seg = &segs[dir*4];
const float ax = layer->bmin[0] + (x+seg[0])*cs;
const float ay = layer->bmin[1] + (h+2)*ch;
const float az = layer->bmin[2] + (y+seg[1])*cs;
const float bx = layer->bmin[0] + (x+seg[2])*cs;
const float by = layer->bmin[1] + (h+2)*ch;
const float bz = layer->bmin[2] + (y+seg[3])*cs;
dd->vertex(ax, ay, az, pcol);
dd->vertex(bx, by, bz, pcol);
}
}
}
}
dd->end();
/* const float h = rcMax(layer->bmax[1]-layer->bmin[1], ch);
unsigned int pcol = duLerpCol(color,duRGBA(255,255,255,255),64);
dd->begin(DU_DRAW_LINES, 2.0f);
@ -396,34 +433,32 @@ static void drawLayerPortals(duDebugDraw* dd, const rcHeightfieldLayer* layer, c
{
const int xx = portal->dir == 0 ? (int)portal->pos : (int)portal->pos+1;
const float fx = layer->bmin[0] + xx*cs;
const float fya = layer->bmin[1] + (layer->ymin)*ch;
const float fyb = layer->bmin[1] + (layer->ymin)*ch;
const float fy = layer->bmin[1];
const float fza = layer->bmin[2] + portal->smin*cs;
const float fzb = layer->bmin[2] + portal->smax*cs;
dd->vertex(fx, fya+h, fza, pcol);
dd->vertex(fx, fyb+h, fzb, pcol);
dd->vertex(fx, fya, fza, pcol);
dd->vertex(fx, fya+h, fza, pcol);
dd->vertex(fx, fyb, fzb, pcol);
dd->vertex(fx, fyb+h, fzb, pcol);
dd->vertex(fx, fy+h, fza, pcol);
dd->vertex(fx, fy+h, fzb, pcol);
dd->vertex(fx, fy, fza, pcol);
dd->vertex(fx, fy+h, fza, pcol);
dd->vertex(fx, fy, fzb, pcol);
dd->vertex(fx, fy+h, fzb, pcol);
}
else if (portal->dir == 3 || portal->dir == 1)
{
const int yy = portal->dir == 3 ? (int)portal->pos : (int)portal->pos+1;
const float fxa = layer->bmin[0] + portal->smin*cs;
const float fxb = layer->bmin[0] + portal->smax*cs;
const float fya = layer->bmin[1] + (layer->ymin)*ch;
const float fyb = layer->bmin[1] + (layer->ymin)*ch;
const float fy = layer->bmin[1];
const float fz = layer->bmin[2] + yy*cs;
dd->vertex(fxa, fya+h, fz, pcol);
dd->vertex(fxb, fyb+h, fz, pcol);
dd->vertex(fxa, fya, fz, pcol);
dd->vertex(fxa, fya+h, fz, pcol);
dd->vertex(fxb, fyb, fz, pcol);
dd->vertex(fxb, fyb+h, fz, pcol);
dd->vertex(fxa, fy+h, fz, pcol);
dd->vertex(fxb, fy+h, fz, pcol);
dd->vertex(fxa, fy, fz, pcol);
dd->vertex(fxa, fy+h, fz, pcol);
dd->vertex(fxb, fy, fz, pcol);
dd->vertex(fxb, fy+h, fz, pcol);
}
}
dd->end();
dd->end();*/
}
void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLayerSet& lset)
@ -445,8 +480,6 @@ void duDebugDrawHeightfieldLayers(duDebugDraw* dd, const struct rcHeightfieldLay
float bmin[3], bmax[3];
rcVcopy(bmin, layer->bmin);
rcVcopy(bmax, layer->bmax);
bmin[1] = layer->bmin[1] + (layer->ymin-1)*ch;
bmax[1] = layer->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
@ -505,8 +538,6 @@ void duDebugDrawHeightfieldLayersRegions(duDebugDraw* dd, const struct rcHeightf
float bmin[3], bmax[3];
rcVcopy(bmin, layer->bmin);
rcVcopy(bmax, layer->bmax);
bmin[1] = layer->bmin[1] + (layer->ymin-1)*ch;
bmax[1] = layer->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

View File

@ -222,14 +222,6 @@ struct rcLeanHeightfield
struct rcHeightfieldLayerPortal
{
unsigned char pos; // Position of the portal.
unsigned char dir; // Direction of the portal (same as used by rcGetCon()).
unsigned char smin, smax; // Span min/max of the portal.
unsigned short hmin, hmax; // Span min/max of the portal.
};
struct rcHeightfieldLayer
{
float bmin[3], bmax[3]; // Bounding box of the heightfield.
@ -237,11 +229,11 @@ struct rcHeightfieldLayer
int width, height; // Width and height of the layer.
int nportals; // Number of portals.
unsigned char regCount;
unsigned short ymin, ymax; // Height min/max range.
unsigned short* heights; // Heighfield.
unsigned char maxHeight; // Height min/max range.
unsigned char* heights; // Heighfield.
unsigned char* areas; // Area types.
unsigned char* regs; // Regions.
rcHeightfieldLayerPortal* portals; // Portals.
unsigned char* cons; // Connections.
};
struct rcHeightfieldLayerSet

View File

@ -106,7 +106,7 @@ 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[i].cons);
}
rcFree(lset->layers);
rcFree(lset);

View File

@ -89,24 +89,6 @@ struct rcLayerSweepSpan
};
rcHeightfieldLayerPortal* allocPortal(rcHeightfieldLayerPortal** portals, int& nportals, int& cportals)
{
if (nportals+1 >= cportals)
{
cportals *= 2;
rcHeightfieldLayerPortal* np = (rcHeightfieldLayerPortal*)rcAlloc(sizeof(rcHeightfieldLayerPortal)*cportals,RC_ALLOC_PERM);
if (!np)
return 0;
if (nportals > 0)
memcpy(np,*portals,sizeof(rcHeightfieldLayerPortal)*nportals);
rcFree(*portals);
*portals = np;
}
nportals++;
return &(*portals)[nportals-1];
}
bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
const int borderSize, const int walkableHeight,
rcHeightfieldLayerSet& lset)
@ -345,19 +327,24 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
for (int j = 0; j < nneis; ++j)
{
const unsigned char nei = reg.neis[j];
rcLayerRegion& regn = regs[nei];
// Skip already visited.
if (regs[nei].layerId != 0xff)
if (regn.layerId != 0xff)
continue;
// Skip if the neighbour is overlapping root region.
if (contains(root.layers, root.nlayers, nei))
continue;
// Skip if the height range would become too large.
const int ymin = rcMin(root.ymin, regn.ymin);
const int ymax = rcMin(root.ymax, regn.ymax);
if ((ymax - ymin) >= 255)
continue;
if (nstack < MAX_STACK)
{
// Deepen
stack[nstack++] = (unsigned char)nei;
rcLayerRegion& regn = regs[nei];
// Mark layer id
regn.layerId = layerId;
// Merge current layers to root.
@ -395,6 +382,11 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
// Skip if teh regions are not close to each other.
if (!overlapRange(ri.ymin,ri.ymax+mergeHeight, rj.ymin,rj.ymax+mergeHeight))
continue;
// Skip if the height range would become too large.
const int ymin = rcMin(ri.ymin, rj.ymin);
const int ymax = rcMin(ri.ymax, rj.ymax);
if ((ymax - ymin) >= 255)
continue;
// Make sure that there is no overlap when mergin 'ri' and 'rj'.
bool overlap = false;
@ -495,13 +487,6 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
}
memset(lset.layers, 0, sizeof(rcHeightfieldLayer)*lset.nlayers);
rcScopedDelete<unsigned char> cons = (unsigned char*)rcAlloc(sizeof(unsigned char)*lw*lh, RC_ALLOC_TEMP);
if (!cons)
{
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'con' (%d).", lw*lh);
return false;
}
// Store layers.
for (int i = 0; i < lset.nlayers; ++i)
@ -515,17 +500,14 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
layer->height = lh;
layer->cs = chf.cs;
layer->ch = chf.ch;
// TODO: Should this be local bbox instead?
rcVcopy(layer->bmin, bmin);
rcVcopy(layer->bmax, bmax);
layer->heights = (unsigned short*)rcAlloc(sizeof(unsigned short)*lw*lh, RC_ALLOC_PERM);
layer->heights = (unsigned char*)rcAlloc(sizeof(unsigned char)*lw*lh, RC_ALLOC_PERM);
if (!layer->heights)
{
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'heights' (%d).", w*h);
return false;
}
memset(layer->heights, 0xff, sizeof(unsigned short)*lw*lh);
memset(layer->heights, 0xff, sizeof(unsigned char)*lw*lh);
layer->areas = (unsigned char*)rcAlloc(sizeof(unsigned char)*lw*lh, RC_ALLOC_PERM);
if (!layer->areas)
@ -535,18 +517,31 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
}
memset(layer->areas, RC_NULL_AREA, sizeof(unsigned char)*lw*lh);
memset(cons, 0, sizeof(unsigned char)*lw*lh);
layer->cons = (unsigned char*)rcAlloc(sizeof(unsigned char)*lw*lh, RC_ALLOC_PERM);
if (!layer->cons)
{
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'cons' (%d).", w*h);
return false;
}
memset(layer->cons, 0, sizeof(unsigned char)*lw*lh);
// Find layer height bounds.
int ymin = 0, ymax = 0;
for (int j = 0; j < nregs; ++j)
{
if (regs[j].start && regs[j].layerId == curId)
{
layer->ymin = regs[j].ymin;
layer->ymax = regs[j].ymax;
ymin = (int)regs[j].ymin;
ymax = (int)regs[j].ymax;
}
}
// Adjust the bbox to fit the heighfield.
rcVcopy(layer->bmin, bmin);
rcVcopy(layer->bmax, bmax);
layer->bmin[1] = bmin[1] + ymin*chf.ch;
layer->bmax[1] = bmin[1] + ymax*chf.ch;
// Copy height and area from compact heighfield.
for (int y = 0; y < lh; ++y)
{
@ -567,10 +562,11 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
continue;
// Store height and area type.
const int idx = x+y*lw;
layer->heights[idx] = s.y;
layer->heights[idx] = (unsigned char)(s.y - ymin);
layer->areas[idx] = chf.areas[i];
// Check connection.
unsigned char portal = 0;
unsigned char con = 0;
for (int dir = 0; dir < 4; ++dir)
{
@ -580,109 +576,21 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
const int ay = cy + rcGetDirOffsetY(dir);
const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
unsigned char alid = srcReg[ai] != 0xff ? regs[srcReg[ai]].layerId : 0xff;
// Portal mask
if (chf.areas[ai] != RC_NULL_AREA && lid != alid)
portal |= (unsigned char)(1<<dir);
// Valid connection mask
if (chf.areas[ai] != RC_NULL_AREA && lid == alid)
{
const int nx = ax - borderSize;
const int ny = ay - borderSize;
if (nx >= 0 && ny >= 0 && nx < lw && ny < lh)
con |= (unsigned char)(1<<dir);
}
}
cons[idx] = con;
}
}
}
// Create portals
int cportals = 6;
layer->portals = (rcHeightfieldLayerPortal*)rcAlloc(sizeof(rcHeightfieldLayerPortal)*cportals,RC_ALLOC_PERM);
if (!layer->portals)
{
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'portals' (%d).", cportals);
return false;
}
layer->nportals = 0;
// Directions same as rcGetCon()
const unsigned char XM = 1<<0; // x-
const unsigned char YP = 1<<1; // y+
const unsigned char XP = 1<<2; // x+
const unsigned char YM = 1<<3; // y-
// Portals along x-axis
for (int y = 0; y < lh; ++y)
{
const unsigned char dir[2] = {3,1};
const unsigned char mask[2] = {YM,YP};
int start[2] = { -1, -1};
for (int x = 0; x < lw+1; ++x)
{
const int idx = x+y*lw;
for (int j = 0; j < 2; ++j)
{
unsigned char set = x<lw ? (cons[idx] & mask[j]) : 0;
if (set)
{
if (start[j] == -1)
start[j] = x;
}
else
{
if (start[j] != -1)
{
// Add portal.
rcHeightfieldLayerPortal* portal = allocPortal(&layer->portals, layer->nportals, cportals);
if (!portal)
{
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'portals' (%d).", cportals);
return false;
}
portal->pos = (unsigned char)y/*+off[j]*/;
portal->smin = (unsigned char)start[j];
portal->smax = (unsigned char)x;
portal->dir = dir[j];
start[j] = -1;
}
}
}
}
}
// Portals along y-axis
for (int x = 0; x < lw; ++x)
{
const unsigned char dir[2] = {0,2};
const unsigned char mask[2] = {XM,XP};
int start[2] = { -1, -1};
for (int y = 0; y < lh+1; ++y)
{
const int idx = x+y*lw;
for (int j = 0; j < 2; ++j)
{
unsigned char set = y<lh ? (cons[idx] & mask[j]) : 0;
if (set)
{
if (start[j] == -1)
start[j] = y;
}
else
{
if (start[j] != -1)
{
// Add portal.
rcHeightfieldLayerPortal* portal = allocPortal(&layer->portals,layer->nportals,cportals);
if (!portal)
{
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'portals' (%d).", cportals);
return false;
}
portal->pos = (unsigned char)x/*+off[j]*/;
portal->smin = (unsigned char)start[j];
portal->smax = (unsigned char)y;
portal->dir = dir[j];
start[j] = -1;
}
}
layer->cons[idx] = (portal << 4) | con;
}
}
}
@ -1005,37 +913,30 @@ static bool appendVertex(rcTempContour& cont, const int x, const int y, const in
static unsigned char getNeighbourReg(rcHeightfieldLayer& layer,
const unsigned char* cons,
const int ax, const int ay, const int dir,
const int walkableClimb)
const int ax, const int ay, const int dir)
{
const int ia = ax+ay*layer.width;
const unsigned char con = layer.cons[ia] & 0xf;
const unsigned char portal = layer.cons[ia] >> 4;
const unsigned char mask = (unsigned char)(1<<dir);
if ((con & mask) == 0)
{
// No connection, return portal or hard edge.
if (portal & mask)
return 0xfe - dir;
return 0xff;
}
const int bx = ax + rcGetDirOffsetX(dir);
const int by = ay + rcGetDirOffsetY(dir);
if (bx < 0 || by < 0 || bx >= layer.width || by >= layer.height)
{
if (cons[ia] & (1<<dir))
return 0xfe - dir;
return 0xff;
}
const int ib = bx+by*layer.width;
if (rcAbs((int)layer.heights[ia] - (int)layer.heights[ib]) > walkableClimb)
{
if (cons[ia] & (1<<dir))
return 0xfe - dir;
return 0xff;
}
return layer.regs[ib];
}
static bool walkContour(rcHeightfieldLayer& layer,
const unsigned char* cons,
int x, int y, const int walkableClimb,
rcTempContour& cont)
static bool walkContour(rcHeightfieldLayer& layer, int x, int y, rcTempContour& cont)
{
const int w = layer.width;
const int h = layer.height;
@ -1049,7 +950,7 @@ static bool walkContour(rcHeightfieldLayer& layer,
for (int i = 0; i < 4; ++i)
{
const int dir = (i+3)&3;
unsigned char rn = getNeighbourReg(layer, cons, x, y, dir, walkableClimb);
unsigned char rn = getNeighbourReg(layer, x, y, dir);
if (rn != layer.regs[x+y*w])
{
startDir = dir;
@ -1065,7 +966,7 @@ static bool walkContour(rcHeightfieldLayer& layer,
int iter = 0;
while (iter < maxIter)
{
unsigned char rn = getNeighbourReg(layer, cons, x, y, dir, walkableClimb);
unsigned char rn = getNeighbourReg(layer, x, y, dir);
int nx = x;
int ny = y;
@ -1269,19 +1170,18 @@ static void simplifyContour(rcTempContour& cont, const float maxError)
}
}
static int getCornerHeight(rcHeightfieldLayer& layer, const unsigned char* cons,
const int x, const int y, const int z, const int walkableClimb,
static int getCornerHeight(rcHeightfieldLayer& layer,
const int x, const int y, const int z,
const int walkableClimb,
bool& shouldRemove)
{
const int w = layer.width;
const int h = layer.height;
// unsigned char ic[4];
// unsigned char ia[4];
int n = 0;
unsigned char ic = 0xff;
int ih = 0;
unsigned char portal = 0xf;
int height = 0;
for (int dz = -1; dz <= 0; ++dz)
{
@ -1292,25 +1192,29 @@ static int getCornerHeight(rcHeightfieldLayer& layer, const unsigned char* cons,
if (px >= 0 && pz >= 0 && px < w && pz < h)
{
const int idx = px + pz*w;
const int hh = (int)layer.heights[idx];
if (rcAbs(hh-y) <= walkableClimb)
const int h = (int)layer.heights[idx];
if (rcAbs(h-y) <= walkableClimb)
{
ih = rcMax(ih, hh);
ic &= cons[idx];
//ia[n] = layer.areas[idx];
height = rcMax(height, h);
portal &= (layer.cons[idx] >> 4);
n++;
}
}
}
}
int portalCount = 0;
for (int dir = 0; dir < 4; ++dir)
if (portal & (1<<dir))
portalCount++;
shouldRemove = false;
if (n > 1 && (ic == 1 || ic == 2 || ic == 4 || ic == 8))
if (n > 1 && portalCount == 1)
{
shouldRemove = true;
}
return ih;
return height;
}
@ -1340,14 +1244,6 @@ bool rcBuildLayerContours(rcContext* ctx,
}
memset(lcset.conts, 0, sizeof(rcLayerContour)*lcset.nconts);
rcScopedDelete<unsigned char> cons = (unsigned char*)rcAlloc(sizeof(unsigned char)*w*h, RC_ALLOC_TEMP);
if (!cons)
{
ctx->log(RC_LOG_ERROR, "rcBuildLayerContours: Out of memory 'cons' (%d).", w*h);
return false;
}
memset(cons,0,sizeof(unsigned char)*w*h);
// Allocate temp buffer for contour tracing.
const int maxTempVerts = (w*h*2)*2; // Twice around the layer.
rcTempContour temp;
@ -1357,37 +1253,19 @@ bool rcBuildLayerContours(rcContext* ctx,
temp.cpoly = maxTempVerts;
temp.verts = (unsigned char*)rcAlloc(sizeof(unsigned char)*temp.cverts, RC_ALLOC_TEMP);
if (!cons)
if (!temp.verts)
{
ctx->log(RC_LOG_ERROR, "rcBuildLayerContours: Out of memory 'temp.verts' (%d).", temp.cverts);
return false;
}
temp.poly = (unsigned short*)rcAlloc(sizeof(unsigned short)*temp.cpoly, RC_ALLOC_TEMP);
if (!cons)
if (!temp.poly)
{
ctx->log(RC_LOG_ERROR, "rcBuildLayerContours: Out of memory 'temp.poly' (%d).", temp.cpoly);
return false;
}
// Paint portals
for (int i = 0; i < layer.nportals; ++i)
{
const rcHeightfieldLayerPortal* portal = &layer.portals[i];
if (portal->dir == 0 || portal->dir == 2)
{
const unsigned char mask = (const unsigned char)(1 << portal->dir);
for (int j = (int)portal->smin; j < (int)portal->smax; ++j)
cons[(int)portal->pos + j*w] |= mask;
}
else
{
const unsigned char mask = (const unsigned char)(1 << portal->dir);
for (int j = (int)portal->smin; j < (int)portal->smax; ++j)
cons[j + (int)portal->pos*w] |= mask;
}
}
// Find contours.
for (int y = 0; y < h; ++y)
{
@ -1406,7 +1284,7 @@ bool rcBuildLayerContours(rcContext* ctx,
cont.reg = ri;
cont.area = layer.areas[idx];
if (!walkContour(layer, cons, x, y, walkableClimb, temp))
if (!walkContour(layer, x, y, temp))
{
ctx->log(RC_LOG_ERROR, "rcBuildLayerContours: Failed to walk contour (nverts=%d cverts=%d).", temp.nverts, temp.cverts);
return false;
@ -1429,7 +1307,7 @@ bool rcBuildLayerContours(rcContext* ctx,
{
bool shouldRemove;
unsigned char* v = &temp.verts[i*4];
v[1] = getCornerHeight(layer, cons, (int)v[0], (int)v[1], (int)v[2], walkableClimb, shouldRemove);
v[1] = getCornerHeight(layer, (int)v[0], (int)v[1], (int)v[2], walkableClimb, shouldRemove);
v[3] = shouldRemove ? 1 : 0;
}

View File

@ -40,6 +40,7 @@ protected:
rcPolyMeshDetail* m_dmesh;
rcConfig m_cfg;
static const int MAX_LAYERS = 128;
rcHeightfieldLayerSet* m_lset;
rcLayerContourSet* m_lcsets[MAX_LAYERS];
@ -47,6 +48,7 @@ protected:
rcLayerPolyMesh* m_lmeshes[MAX_LAYERS];
int m_nlmeshes;
enum DrawMode
{
DRAWMODE_NAVMESH,

View File

@ -36,6 +36,7 @@
#include "ConvexVolumeTool.h"
#include "CrowdTool.h"
#ifdef WIN32
# define snprintf _snprintf
#endif
@ -740,7 +741,7 @@ void Sample_TileMesh::handleRenderOverlay(double* proj, double* model, int* view
unsigned int color = duIntToCol(i+1, 255);
float pos[3];
rcVcopy(pos, layer->bmin);
pos[1] = layer->bmin[1] + ((layer->ymin+layer->ymax)/2)*layer->ch;
pos[1] = (layer->bmin[1] + layer->bmax[1])*0.5f;
if (gluProject((GLdouble)pos[0], (GLdouble)pos[1], (GLdouble)pos[2], model, proj, view, &x, &y, &z))
{
char text[32];
@ -946,6 +947,7 @@ void Sample_TileMesh::buildAllTiles()
m_ctx->stopTimer(RC_TIMER_TEMP);
m_totalBuildTimeMs = m_ctx->getAccumulatedTime(RC_TIMER_TEMP)/1000.0f;
}
void Sample_TileMesh::removeAllTiles()
@ -963,6 +965,7 @@ void Sample_TileMesh::removeAllTiles()
m_navMesh->removeTile(m_navMesh->getTileRefAt(x,y),0,0);
}
unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const float* bmin, const float* bmax, int& dataSize)
{
if (!m_geom || !m_geom->getMesh() || !m_geom->getChunkyMesh())
@ -1166,13 +1169,18 @@ unsigned char* Sample_TileMesh::buildTileMesh(const int tx, const int ty, const
if (!rcBuildLayerContours(m_ctx, m_lset->layers[i],
m_cfg.walkableClimb, m_cfg.maxSimplificationError,
*m_lcsets[m_nlcsets]))
{
break;
}
m_lmeshes[m_nlmeshes] = rcAllocLayerPolyMesh();
if (!rcBuildLayerPolyMesh(m_ctx, *m_lcsets[m_nlcsets],
m_cfg.maxVertsPerPoly,
*m_lmeshes[m_nlmeshes]))
{
break;
}
m_nlcsets++;
m_nlmeshes++;