TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
RecastLayers.cpp File Reference
#include <float.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "Recast.h"
#include "RecastAlloc.h"
#include "RecastAssert.h"
+ Include dependency graph for RecastLayers.cpp:

Classes

struct  rcLayerRegion
 
struct  rcLayerSweepSpan
 

Macros

#define _USE_MATH_DEFINES
 

Functions

static void addUnique (unsigned char *a, unsigned char &an, unsigned char v)
 
static bool contains (const unsigned char *a, const unsigned char an, const unsigned char v)
 
bool overlapRange (const unsigned short amin, const unsigned short amax, const unsigned short bmin, const unsigned short bmax)
 
bool rcBuildHeightfieldLayers (rcContext *ctx, rcCompactHeightfield &chf, const int borderSize, const int walkableHeight, rcHeightfieldLayerSet &lset)
 

Variables

static const int RC_MAX_LAYERS = RC_NOT_CONNECTED
 
static const int RC_MAX_NEIS = 16
 

Macro Definition Documentation

#define _USE_MATH_DEFINES

Function Documentation

static void addUnique ( unsigned char *  a,
unsigned char &  an,
unsigned char  v 
)
static
46 {
47  const int n = (int)an;
48  for (int i = 0; i < n; ++i)
49  if (a[i] == v)
50  return;
51  a[an] = v;
52  an++;
53 }

+ Here is the caller graph for this function:

static bool contains ( const unsigned char *  a,
const unsigned char  an,
const unsigned char  v 
)
static
56 {
57  const int n = (int)an;
58  for (int i = 0; i < n; ++i)
59  if (a[i] == v)
60  return true;
61  return false;
62 }

+ Here is the caller graph for this function:

bool overlapRange ( const unsigned short  amin,
const unsigned short  amax,
const unsigned short  bmin,
const unsigned short  bmax 
)
inline
66 {
67  return (amin > bmax || amax < bmin) ? false : true;
68 }

+ Here is the caller graph for this function:

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

See the rcConfig documentation for more information on the configuration parameters.

See also
rcAllocHeightfieldLayerSet, rcCompactHeightfield, rcHeightfieldLayerSet, rcConfig
87 {
88  rcAssert(ctx);
89 
91 
92  const int w = chf.width;
93  const int h = chf.height;
94 
95  rcScopedDelete<unsigned char> srcReg = (unsigned char*)rcAlloc(sizeof(unsigned char)*chf.spanCount, RC_ALLOC_TEMP);
96  if (!srcReg)
97  {
98  ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'srcReg' (%d).", chf.spanCount);
99  return false;
100  }
101  memset(srcReg,0xff,sizeof(unsigned char)*chf.spanCount);
102 
103  const int nsweeps = chf.width;
105  if (!sweeps)
106  {
107  ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'sweeps' (%d).", nsweeps);
108  return false;
109  }
110 
111 
112  // Partition walkable area into monotone regions.
113  int prevCount[256];
114  unsigned char regId = 0;
115 
116  for (int y = borderSize; y < h-borderSize; ++y)
117  {
118  memset(prevCount,0,sizeof(int)*regId);
119  unsigned char sweepId = 0;
120 
121  for (int x = borderSize; x < w-borderSize; ++x)
122  {
123  const rcCompactCell& c = chf.cells[x+y*w];
124 
125  for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
126  {
127  const rcCompactSpan& s = chf.spans[i];
128  if (chf.areas[i] == RC_NULL_AREA) continue;
129 
130  unsigned char sid = 0xff;
131 
132  // -x
133  if (rcGetCon(s, 0) != RC_NOT_CONNECTED)
134  {
135  const int ax = x + rcGetDirOffsetX(0);
136  const int ay = y + rcGetDirOffsetY(0);
137  const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 0);
138  if (chf.areas[ai] != RC_NULL_AREA && srcReg[ai] != 0xff)
139  sid = srcReg[ai];
140  }
141 
142  if (sid == 0xff)
143  {
144  sid = sweepId++;
145  sweeps[sid].nei = 0xff;
146  sweeps[sid].ns = 0;
147  }
148 
149  // -y
150  if (rcGetCon(s,3) != RC_NOT_CONNECTED)
151  {
152  const int ax = x + rcGetDirOffsetX(3);
153  const int ay = y + rcGetDirOffsetY(3);
154  const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, 3);
155  const unsigned char nr = srcReg[ai];
156  if (nr != 0xff)
157  {
158  // Set neighbour when first valid neighbour is encoutered.
159  if (sweeps[sid].ns == 0)
160  sweeps[sid].nei = nr;
161 
162  if (sweeps[sid].nei == nr)
163  {
164  // Update existing neighbour
165  sweeps[sid].ns++;
166  prevCount[nr]++;
167  }
168  else
169  {
170  // This is hit if there is nore than one neighbour.
171  // Invalidate the neighbour.
172  sweeps[sid].nei = 0xff;
173  }
174  }
175  }
176 
177  srcReg[i] = sid;
178  }
179  }
180 
181  // Create unique ID.
182  for (int i = 0; i < sweepId; ++i)
183  {
184  // If the neighbour is set and there is only one continuous connection to it,
185  // the sweep will be merged with the previous one, else new region is created.
186  if (sweeps[i].nei != 0xff && prevCount[sweeps[i].nei] == (int)sweeps[i].ns)
187  {
188  sweeps[i].id = sweeps[i].nei;
189  }
190  else
191  {
192  if (regId == 255)
193  {
194  ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Region ID overflow.");
195  return false;
196  }
197  sweeps[i].id = regId++;
198  }
199  }
200 
201  // Remap local sweep ids to region ids.
202  for (int x = borderSize; x < w-borderSize; ++x)
203  {
204  const rcCompactCell& c = chf.cells[x+y*w];
205  for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
206  {
207  if (srcReg[i] != 0xff)
208  srcReg[i] = sweeps[srcReg[i]].id;
209  }
210  }
211  }
212 
213  // Allocate and init layer regions.
214  const int nregs = (int)regId;
216  if (!regs)
217  {
218  ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'regs' (%d).", nregs);
219  return false;
220  }
221  memset(regs, 0, sizeof(rcLayerRegion)*nregs);
222  for (int i = 0; i < nregs; ++i)
223  {
224  regs[i].layerId = 0xff;
225  regs[i].ymin = 0xffff;
226  regs[i].ymax = 0;
227  }
228 
229  // Find region neighbours and overlapping regions.
230  for (int y = 0; y < h; ++y)
231  {
232  for (int x = 0; x < w; ++x)
233  {
234  const rcCompactCell& c = chf.cells[x+y*w];
235 
236  unsigned char lregs[RC_MAX_LAYERS];
237  int nlregs = 0;
238 
239  for (int i = (int)c.index, ni = (int)(c.index+c.count); i < ni; ++i)
240  {
241  const rcCompactSpan& s = chf.spans[i];
242  const unsigned char ri = srcReg[i];
243  if (ri == 0xff) continue;
244 
245  regs[ri].ymin = rcMin(regs[ri].ymin, s.y);
246  regs[ri].ymax = rcMax(regs[ri].ymax, s.y);
247 
248  // Collect all region layers.
249  if (nlregs < RC_MAX_LAYERS)
250  lregs[nlregs++] = ri;
251 
252  // Update neighbours
253  for (int dir = 0; dir < 4; ++dir)
254  {
255  if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
256  {
257  const int ax = x + rcGetDirOffsetX(dir);
258  const int ay = y + rcGetDirOffsetY(dir);
259  const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
260  const unsigned char rai = srcReg[ai];
261  if (rai != 0xff && rai != ri)
262  addUnique(regs[ri].neis, regs[ri].nneis, rai);
263  }
264  }
265 
266  }
267 
268  // Update overlapping regions.
269  for (int i = 0; i < nlregs-1; ++i)
270  {
271  for (int j = i+1; j < nlregs; ++j)
272  {
273  if (lregs[i] != lregs[j])
274  {
275  rcLayerRegion& ri = regs[lregs[i]];
276  rcLayerRegion& rj = regs[lregs[j]];
277  addUnique(ri.layers, ri.nlayers, lregs[j]);
278  addUnique(rj.layers, rj.nlayers, lregs[i]);
279  }
280  }
281  }
282 
283  }
284  }
285 
286  // Create 2D layers from regions.
287  unsigned char layerId = 0;
288 
289  static const int MAX_STACK = 64;
290  unsigned char stack[MAX_STACK];
291  int nstack = 0;
292 
293  for (int i = 0; i < nregs; ++i)
294  {
295  rcLayerRegion& root = regs[i];
296  // Skip already visited.
297  if (root.layerId != 0xff)
298  continue;
299 
300  // Start search.
301  root.layerId = layerId;
302  root.base = 1;
303 
304  nstack = 0;
305  stack[nstack++] = (unsigned char)i;
306 
307  while (nstack)
308  {
309  // Pop front
310  rcLayerRegion& reg = regs[stack[0]];
311  nstack--;
312  for (int j = 0; j < nstack; ++j)
313  stack[j] = stack[j+1];
314 
315  const int nneis = (int)reg.nneis;
316  for (int j = 0; j < nneis; ++j)
317  {
318  const unsigned char nei = reg.neis[j];
319  rcLayerRegion& regn = regs[nei];
320  // Skip already visited.
321  if (regn.layerId != 0xff)
322  continue;
323  // Skip if the neighbour is overlapping root region.
324  if (contains(root.layers, root.nlayers, nei))
325  continue;
326  // Skip if the height range would become too large.
327  const int ymin = rcMin(root.ymin, regn.ymin);
328  const int ymax = rcMax(root.ymax, regn.ymax);
329  if ((ymax - ymin) >= 255)
330  continue;
331 
332  if (nstack < MAX_STACK)
333  {
334  // Deepen
335  stack[nstack++] = (unsigned char)nei;
336 
337  // Mark layer id
338  regn.layerId = layerId;
339  // Merge current layers to root.
340  for (int k = 0; k < regn.nlayers; ++k)
341  addUnique(root.layers, root.nlayers, regn.layers[k]);
342  root.ymin = rcMin(root.ymin, regn.ymin);
343  root.ymax = rcMax(root.ymax, regn.ymax);
344  }
345  }
346  }
347 
348  layerId++;
349  }
350 
351  // Merge non-overlapping regions that are close in height.
352  const unsigned short mergeHeight = (unsigned short)walkableHeight * 4;
353 
354  for (int i = 0; i < nregs; ++i)
355  {
356  rcLayerRegion& ri = regs[i];
357  if (!ri.base) continue;
358 
359  unsigned char newId = ri.layerId;
360 
361  for (;;)
362  {
363  unsigned char oldId = 0xff;
364 
365  for (int j = 0; j < nregs; ++j)
366  {
367  if (i == j) continue;
368  rcLayerRegion& rj = regs[j];
369  if (!rj.base) continue;
370 
371  // Skip if the regions are not close to each other.
372  if (!overlapRange(ri.ymin,ri.ymax+mergeHeight, rj.ymin,rj.ymax+mergeHeight))
373  continue;
374  // Skip if the height range would become too large.
375  const int ymin = rcMin(ri.ymin, rj.ymin);
376  const int ymax = rcMax(ri.ymax, rj.ymax);
377  if ((ymax - ymin) >= 255)
378  continue;
379 
380  // Make sure that there is no overlap when merging 'ri' and 'rj'.
381  bool overlap = false;
382  // Iterate over all regions which have the same layerId as 'rj'
383  for (int k = 0; k < nregs; ++k)
384  {
385  if (regs[k].layerId != rj.layerId)
386  continue;
387  // Check if region 'k' is overlapping region 'ri'
388  // Index to 'regs' is the same as region id.
389  if (contains(ri.layers,ri.nlayers, (unsigned char)k))
390  {
391  overlap = true;
392  break;
393  }
394  }
395  // Cannot merge of regions overlap.
396  if (overlap)
397  continue;
398 
399  // Can merge i and j.
400  oldId = rj.layerId;
401  break;
402  }
403 
404  // Could not find anything to merge with, stop.
405  if (oldId == 0xff)
406  break;
407 
408  // Merge
409  for (int j = 0; j < nregs; ++j)
410  {
411  rcLayerRegion& rj = regs[j];
412  if (rj.layerId == oldId)
413  {
414  rj.base = 0;
415  // Remap layerIds.
416  rj.layerId = newId;
417  // Add overlaid layers from 'rj' to 'ri'.
418  for (int k = 0; k < rj.nlayers; ++k)
419  addUnique(ri.layers, ri.nlayers, rj.layers[k]);
420  // Update height bounds.
421  ri.ymin = rcMin(ri.ymin, rj.ymin);
422  ri.ymax = rcMax(ri.ymax, rj.ymax);
423  }
424  }
425  }
426  }
427 
428  // Compact layerIds
429  unsigned char remap[256];
430  memset(remap, 0, 256);
431 
432  // Find number of unique layers.
433  layerId = 0;
434  for (int i = 0; i < nregs; ++i)
435  remap[regs[i].layerId] = 1;
436  for (int i = 0; i < 256; ++i)
437  {
438  if (remap[i])
439  remap[i] = layerId++;
440  else
441  remap[i] = 0xff;
442  }
443  // Remap ids.
444  for (int i = 0; i < nregs; ++i)
445  regs[i].layerId = remap[regs[i].layerId];
446 
447  // No layers, return empty.
448  if (layerId == 0)
449  {
451  return true;
452  }
453 
454  // Create layers.
455  rcAssert(lset.layers == 0);
456 
457  const int lw = w - borderSize*2;
458  const int lh = h - borderSize*2;
459 
460  // Build contracted bbox for layers.
461  float bmin[3], bmax[3];
462  rcVcopy(bmin, chf.bmin);
463  rcVcopy(bmax, chf.bmax);
464  bmin[0] += borderSize*chf.cs;
465  bmin[2] += borderSize*chf.cs;
466  bmax[0] -= borderSize*chf.cs;
467  bmax[2] -= borderSize*chf.cs;
468 
469  lset.nlayers = (int)layerId;
470 
472  if (!lset.layers)
473  {
474  ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'layers' (%d).", lset.nlayers);
475  return false;
476  }
477  memset(lset.layers, 0, sizeof(rcHeightfieldLayer)*lset.nlayers);
478 
479 
480  // Store layers.
481  for (int i = 0; i < lset.nlayers; ++i)
482  {
483  unsigned char curId = (unsigned char)i;
484 
485  rcHeightfieldLayer* layer = &lset.layers[i];
486 
487  const int gridSize = sizeof(unsigned char)*lw*lh;
488 
489  layer->heights = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM);
490  if (!layer->heights)
491  {
492  ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'heights' (%d).", gridSize);
493  return false;
494  }
495  memset(layer->heights, 0xff, gridSize);
496 
497  layer->areas = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM);
498  if (!layer->areas)
499  {
500  ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'areas' (%d).", gridSize);
501  return false;
502  }
503  memset(layer->areas, 0, gridSize);
504 
505  layer->cons = (unsigned char*)rcAlloc(gridSize, RC_ALLOC_PERM);
506  if (!layer->cons)
507  {
508  ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: Out of memory 'cons' (%d).", gridSize);
509  return false;
510  }
511  memset(layer->cons, 0, gridSize);
512 
513  // Find layer height bounds.
514  int hmin = 0, hmax = 0;
515  for (int j = 0; j < nregs; ++j)
516  {
517  if (regs[j].base && regs[j].layerId == curId)
518  {
519  hmin = (int)regs[j].ymin;
520  hmax = (int)regs[j].ymax;
521  }
522  }
523 
524  layer->width = lw;
525  layer->height = lh;
526  layer->cs = chf.cs;
527  layer->ch = chf.ch;
528 
529  // Adjust the bbox to fit the heightfield.
530  rcVcopy(layer->bmin, bmin);
531  rcVcopy(layer->bmax, bmax);
532  layer->bmin[1] = bmin[1] + hmin*chf.ch;
533  layer->bmax[1] = bmin[1] + hmax*chf.ch;
534  layer->hmin = hmin;
535  layer->hmax = hmax;
536 
537  // Update usable data region.
538  layer->minx = layer->width;
539  layer->maxx = 0;
540  layer->miny = layer->height;
541  layer->maxy = 0;
542 
543  // Copy height and area from compact heightfield.
544  for (int y = 0; y < lh; ++y)
545  {
546  for (int x = 0; x < lw; ++x)
547  {
548  const int cx = borderSize+x;
549  const int cy = borderSize+y;
550  const rcCompactCell& c = chf.cells[cx+cy*w];
551  for (int j = (int)c.index, nj = (int)(c.index+c.count); j < nj; ++j)
552  {
553  const rcCompactSpan& s = chf.spans[j];
554  // Skip unassigned regions.
555  if (srcReg[j] == 0xff)
556  continue;
557  // Skip of does nto belong to current layer.
558  unsigned char lid = regs[srcReg[j]].layerId;
559  if (lid != curId)
560  continue;
561 
562  // Update data bounds.
563  layer->minx = rcMin(layer->minx, x);
564  layer->maxx = rcMax(layer->maxx, x);
565  layer->miny = rcMin(layer->miny, y);
566  layer->maxy = rcMax(layer->maxy, y);
567 
568  // Store height and area type.
569  const int idx = x+y*lw;
570  layer->heights[idx] = (unsigned char)(s.y - hmin);
571  layer->areas[idx] = chf.areas[j];
572 
573  // Check connection.
574  unsigned char portal = 0;
575  unsigned char con = 0;
576  for (int dir = 0; dir < 4; ++dir)
577  {
578  if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
579  {
580  const int ax = cx + rcGetDirOffsetX(dir);
581  const int ay = cy + rcGetDirOffsetY(dir);
582  const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
583  unsigned char alid = srcReg[ai] != 0xff ? regs[srcReg[ai]].layerId : 0xff;
584  // Portal mask
585  if (chf.areas[ai] != RC_NULL_AREA && lid != alid)
586  {
587  portal |= (unsigned char)(1<<dir);
588  // Update height so that it matches on both sides of the portal.
589  const rcCompactSpan& as = chf.spans[ai];
590  if (as.y > hmin)
591  layer->heights[idx] = rcMax(layer->heights[idx], (unsigned char)(as.y - hmin));
592  }
593  // Valid connection mask
594  if (chf.areas[ai] != RC_NULL_AREA && lid == alid)
595  {
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);
600  }
601  }
602  }
603 
604  layer->cons[idx] = (portal << 4) | con;
605  }
606  }
607  }
608 
609  if (layer->minx > layer->maxx)
610  layer->minx = layer->maxx = 0;
611  if (layer->miny > layer->maxy)
612  layer->miny = layer->maxy = 0;
613  }
614 
616 
617  return true;
618 }
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
Definition: Recast.h:327
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

+ Here is the call graph for this function:

Variable Documentation

const int RC_MAX_LAYERS = RC_NOT_CONNECTED
static
const int RC_MAX_NEIS = 16
static