92 const int w = chf.
width;
101 memset(srcReg,0xff,
sizeof(
unsigned char)*chf.
spanCount);
103 const int nsweeps = chf.
width;
107 ctx->
log(
RC_LOG_ERROR,
"rcBuildHeightfieldLayers: Out of memory 'sweeps' (%d).", nsweeps);
114 unsigned char regId = 0;
116 for (
int y = borderSize;
y < h-borderSize; ++
y)
118 memset(prevCount,0,
sizeof(
int)*regId);
119 unsigned char sweepId = 0;
121 for (
int x = borderSize;
x < w-borderSize; ++
x)
130 unsigned char sid = 0xff;
145 sweeps[sid].nei = 0xff;
155 const unsigned char nr = srcReg[ai];
159 if (sweeps[sid].ns == 0)
160 sweeps[sid].nei = nr;
162 if (sweeps[sid].nei == nr)
172 sweeps[sid].nei = 0xff;
182 for (
int i = 0; i < sweepId; ++i)
186 if (sweeps[i].nei != 0xff && prevCount[sweeps[i].nei] == (
int)sweeps[i].ns)
188 sweeps[i].id = sweeps[i].nei;
194 ctx->
log(
RC_LOG_ERROR,
"rcBuildHeightfieldLayers: Region ID overflow.");
197 sweeps[i].id = regId++;
202 for (
int x = borderSize;
x < w-borderSize; ++
x)
207 if (srcReg[i] != 0xff)
208 srcReg[i] = sweeps[srcReg[i]].id;
214 const int nregs = (int)regId;
218 ctx->
log(
RC_LOG_ERROR,
"rcBuildHeightfieldLayers: Out of memory 'regs' (%d).", nregs);
222 for (
int i = 0; i < nregs; ++i)
224 regs[i].layerId = 0xff;
225 regs[i].ymin = 0xffff;
230 for (
int y = 0;
y < h; ++
y)
232 for (
int x = 0;
x < w; ++
x)
242 const unsigned char ri = srcReg[i];
243 if (ri == 0xff)
continue;
245 regs[ri].ymin =
rcMin(regs[ri].ymin, s.
y);
246 regs[ri].ymax =
rcMax(regs[ri].ymax, s.
y);
250 lregs[nlregs++] = ri;
253 for (
int dir = 0; dir < 4; ++dir)
260 const unsigned char rai = srcReg[ai];
261 if (rai != 0xff && rai != ri)
262 addUnique(regs[ri].neis, regs[ri].nneis, rai);
269 for (
int i = 0; i < nlregs-1; ++i)
271 for (
int j = i+1; j < nlregs; ++j)
273 if (lregs[i] != lregs[j])
287 unsigned char layerId = 0;
289 static const int MAX_STACK = 64;
290 unsigned char stack[MAX_STACK];
293 for (
int i = 0; i < nregs; ++i)
305 stack[nstack++] = (
unsigned char)i;
312 for (
int j = 0; j < nstack; ++j)
313 stack[j] = stack[j+1];
315 const int nneis = (int)reg.
nneis;
316 for (
int j = 0; j < nneis; ++j)
318 const unsigned char nei = reg.
neis[j];
329 if ((ymax - ymin) >= 255)
332 if (nstack < MAX_STACK)
335 stack[nstack++] = (
unsigned char)nei;
340 for (
int k = 0; k < regn.
nlayers; ++k)
352 const unsigned short mergeHeight = (
unsigned short)walkableHeight * 4;
354 for (
int i = 0; i < nregs; ++i)
357 if (!ri.
base)
continue;
359 unsigned char newId = ri.
layerId;
363 unsigned char oldId = 0xff;
365 for (
int j = 0; j < nregs; ++j)
367 if (i == j)
continue;
369 if (!rj.
base)
continue;
377 if ((ymax - ymin) >= 255)
381 bool overlap =
false;
383 for (
int k = 0; k < nregs; ++k)
385 if (regs[k].layerId != rj.
layerId)
409 for (
int j = 0; j < nregs; ++j)
418 for (
int k = 0; k < rj.
nlayers; ++k)
429 unsigned char remap[256];
430 memset(remap, 0, 256);
434 for (
int i = 0; i < nregs; ++i)
435 remap[regs[i].layerId] = 1;
436 for (
int i = 0; i < 256; ++i)
439 remap[i] = layerId++;
444 for (
int i = 0; i < nregs; ++i)
445 regs[i].layerId = remap[regs[i].layerId];
457 const int lw = w - borderSize*2;
458 const int lh = h - borderSize*2;
461 float bmin[3], bmax[3];
464 bmin[0] += borderSize*chf.
cs;
465 bmin[2] += borderSize*chf.
cs;
466 bmax[0] -= borderSize*chf.
cs;
467 bmax[2] -= borderSize*chf.
cs;
481 for (
int i = 0; i < lset.
nlayers; ++i)
483 unsigned char curId = (
unsigned char)i;
487 const int gridSize =
sizeof(
unsigned char)*lw*lh;
492 ctx->
log(
RC_LOG_ERROR,
"rcBuildHeightfieldLayers: Out of memory 'heights' (%d).", gridSize);
495 memset(layer->
heights, 0xff, gridSize);
500 ctx->
log(
RC_LOG_ERROR,
"rcBuildHeightfieldLayers: Out of memory 'areas' (%d).", gridSize);
503 memset(layer->
areas, 0, gridSize);
508 ctx->
log(
RC_LOG_ERROR,
"rcBuildHeightfieldLayers: Out of memory 'cons' (%d).", gridSize);
511 memset(layer->
cons, 0, gridSize);
514 int hmin = 0, hmax = 0;
515 for (
int j = 0; j < nregs; ++j)
517 if (regs[j].base && regs[j].layerId == curId)
519 hmin = (int)regs[j].ymin;
520 hmax = (int)regs[j].ymax;
532 layer->
bmin[1] = bmin[1] + hmin*chf.
ch;
533 layer->
bmax[1] = bmin[1] + hmax*chf.
ch;
544 for (
int y = 0;
y < lh; ++
y)
546 for (
int x = 0;
x < lw; ++
x)
548 const int cx = borderSize+
x;
549 const int cy = borderSize+
y;
555 if (srcReg[j] == 0xff)
558 unsigned char lid = regs[srcReg[j]].layerId;
569 const int idx = x+y*lw;
570 layer->
heights[idx] = (
unsigned char)(s.
y - hmin);
574 unsigned char portal = 0;
575 unsigned char con = 0;
576 for (
int dir = 0; dir < 4; ++dir)
583 unsigned char alid = srcReg[ai] != 0xff ? regs[srcReg[ai]].layerId : 0xff;
587 portal |= (
unsigned char)(1<<dir);
596 const int nx = ax - borderSize;
597 const int ny = ay - borderSize;
598 if (nx >= 0 && ny >= 0 && nx < lw && ny < lh)
599 con |= (
unsigned char)(1<<dir);
604 layer->
cons[idx] = (portal << 4) | con;
rcHeightfieldLayer * layers
The layers in the set. [Size: nlayers].
Definition: Recast.h:351
int height
The height of the heightfield. (Along the z-axis in cell units.)
Definition: Recast.h:308
#define rcAssert
Definition: RecastAssert.h:30
Definition: RecastLayers.cpp:33
static void addUnique(unsigned char *a, unsigned char &an, unsigned char v)
Definition: RecastLayers.cpp:45
Represents a span of unobstructed space within a compact heightfield.
Definition: Recast.h:295
int hmax
The maximum height bounds of usable data. (Along the y-axis.)
Definition: Recast.h:340
unsigned char neis[RC_MAX_NEIS]
Definition: RecastLayers.cpp:36
static const int RC_NOT_CONNECTED
Definition: Recast.h:547
unsigned char * heights
The heightfield. [Size: width * height].
Definition: Recast.h:341
rcCompactCell * cells
Array of cells. [Size: width*height].
Definition: Recast.h:319
int rcGetDirOffsetY(int dir)
Definition: Recast.h:1048
unsigned short y
The lower extent of the span. (Measured from the heightfield's base.)
Definition: Recast.h:297
rcCompactSpan * spans
Array of spans. [Size: spanCount].
Definition: Recast.h:320
T rcMin(T a, T b)
Definition: Recast.h:566
int rcGetCon(const rcCompactSpan &s, int dir)
Definition: Recast.h:1028
unsigned int index
Index to the first span in the column.
Definition: Recast.h:290
unsigned short ymin
Definition: RecastLayers.cpp:37
Provides information on the content of a cell column in a compact heightfield.
Definition: Recast.h:288
Definition: RecastLayers.cpp:72
unsigned char * areas
Area ids. [Size: Same as heights].
Definition: Recast.h:342
unsigned int count
Number of spans in the column.
Definition: Recast.h:291
An error log entry.
Definition: Recast.h:31
Definition: RecastAlloc.h:105
int height
The height of the heightfield. (Along the z-axis in cell units.)
Definition: Recast.h:334
static bool contains(const unsigned char *a, const unsigned char an, const unsigned char v)
Definition: RecastLayers.cpp:55
static const int RC_MAX_LAYERS
Definition: RecastLayers.cpp:30
The time to build heightfield layers. (See: rcBuildHeightfieldLayers)
Definition: Recast.h:89
float bmin[3]
The minimum bounds in world space. [(x, y, z)].
Definition: Recast.h:329
int maxx
The maximum x-bounds of usable data.
Definition: Recast.h:336
unsigned char layers[RC_MAX_LAYERS]
Definition: RecastLayers.cpp:35
void * rcAlloc(int size, rcAllocHint hint)
Definition: RecastAlloc.cpp:44
int rcGetDirOffsetX(int dir)
Definition: Recast.h:1038
int minx
The minimum x-bounds of usable data.
Definition: Recast.h:335
unsigned char nlayers
Definition: RecastLayers.cpp:39
unsigned char * areas
Array containing area id data. [Size: spanCount].
Definition: Recast.h:322
float ch
The height of each cell. (The minimum increment along the y-axis.)
Definition: Recast.h:332
G3D::int16 y
Definition: Vector2int16.h:38
float bmax[3]
The maximum bounds in world space. [(x, y, z)].
Definition: Recast.h:316
int width
The width of the heightfield. (Along the x-axis in cell units.)
Definition: Recast.h:307
void rcVcopy(float *dest, const float *v)
Definition: Recast.h:677
void startTimer(const rcTimerLabel label)
Definition: Recast.h:131
int spanCount
The number of spans in the heightfield.
Definition: Recast.h:309
unsigned char * cons
Packed neighbor connection information. [Size: Same as heights].
Definition: Recast.h:343
int maxy
The maximum y-bounds of usable data. (Along the z-axis.)
Definition: Recast.h:338
Memory will persist after a function call.
Definition: RecastAlloc.h:26
float cs
The size of each cell. (On the xz-plane.)
Definition: Recast.h:317
float ch
The height of each cell. (The minimum increment along the y-axis.)
Definition: Recast.h:318
static const unsigned char RC_NULL_AREA
Definition: Recast.h:538
int nlayers
The number of layers in the set.
Definition: Recast.h:352
Memory used temporarily within a function.
Definition: RecastAlloc.h:27
T rcMax(T a, T b)
Definition: Recast.h:572
void log(const rcLogCategory category, const char *format,...)
Definition: Recast.cpp:55
unsigned char layerId
Definition: RecastLayers.cpp:38
unsigned short ymax
Definition: RecastLayers.cpp:37
G3D::int16 x
Definition: Vector2int16.h:37
int width
The width of the heightfield. (Along the x-axis in cell units.)
Definition: Recast.h:333
void stopTimer(const rcTimerLabel label)
Definition: Recast.h:135
unsigned char nneis
Definition: RecastLayers.cpp:40
float bmax[3]
The maximum bounds in world space. [(x, y, z)].
Definition: Recast.h:330
unsigned char base
Definition: RecastLayers.cpp:41
int hmin
The minimum height bounds of usable data. (Along the y-axis.)
Definition: Recast.h:339
float cs
The size of each cell. (On the xz-plane.)
Definition: Recast.h:331
float bmin[3]
The minimum bounds in world space. [(x, y, z)].
Definition: Recast.h:315
bool overlapRange(const unsigned short amin, const unsigned short amax, const unsigned short bmin, const unsigned short bmax)
Definition: RecastLayers.cpp:64
int miny
The minimum y-bounds of usable data. (Along the z-axis.)
Definition: Recast.h:337