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

Macros

#define _USE_MATH_DEFINES
 

Functions

void rcFilterLowHangingWalkableObstacles (rcContext *ctx, const int walkableClimb, rcHeightfield &solid)
 
void rcFilterLedgeSpans (rcContext *ctx, const int walkableHeight, const int walkableClimb, rcHeightfield &solid)
 
void rcFilterWalkableLowHeightSpans (rcContext *ctx, int walkableHeight, rcHeightfield &solid)
 

Macro Definition Documentation

#define _USE_MATH_DEFINES

Function Documentation

void rcFilterLedgeSpans ( rcContext ctx,
const int  walkableHeight,
const int  walkableClimb,
rcHeightfield solid 
)

A ledge is a span with one or more neighbors whose maximum is further away than walkableClimb from the current span's maximum. This method removes the impact of the overestimation of conservative voxelization so the resulting mesh will not have regions hanging in the air over ledges.

A span is a ledge if: rcAbs(currentSpan.smax - neighborSpan.smax) > walkableClimb

See also
rcHeightfield, rcConfig
86 {
87  rcAssert(ctx);
88 
90 
91  const int w = solid.width;
92  const int h = solid.height;
93  const int MAX_HEIGHT = 0xffff;
94 
95  // Mark border spans.
96  for (int y = 0; y < h; ++y)
97  {
98  for (int x = 0; x < w; ++x)
99  {
100  for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next)
101  {
102  // Skip non walkable spans.
103  if (s->area == RC_NULL_AREA)
104  continue;
105 
106  const int bot = (int)(s->smax);
107  const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT;
108 
109  // Find neighbours minimum height.
110  int minh = MAX_HEIGHT;
111 
112  // Min and max height of accessible neighbours.
113  int asmin = s->smax;
114  int asmax = s->smax;
115 
116  for (int dir = 0; dir < 4; ++dir)
117  {
118  int dx = x + rcGetDirOffsetX(dir);
119  int dy = y + rcGetDirOffsetY(dir);
120  // Skip neighbours which are out of bounds.
121  if (dx < 0 || dy < 0 || dx >= w || dy >= h)
122  {
123  minh = rcMin(minh, -walkableClimb - bot);
124  continue;
125  }
126 
127  // From minus infinity to the first span.
128  rcSpan* ns = solid.spans[dx + dy*w];
129  int nbot = -walkableClimb;
130  int ntop = ns ? (int)ns->smin : MAX_HEIGHT;
131  // Skip neightbour if the gap between the spans is too small.
132  if (rcMin(top,ntop) - rcMax(bot,nbot) > walkableHeight)
133  minh = rcMin(minh, nbot - bot);
134 
135  // Rest of the spans.
136  for (ns = solid.spans[dx + dy*w]; ns; ns = ns->next)
137  {
138  nbot = (int)ns->smax;
139  ntop = ns->next ? (int)ns->next->smin : MAX_HEIGHT;
140  // Skip neightbour if the gap between the spans is too small.
141  if (rcMin(top,ntop) - rcMax(bot,nbot) > walkableHeight)
142  {
143  minh = rcMin(minh, nbot - bot);
144 
145  // Find min/max accessible neighbour height.
146  if (rcAbs(nbot - bot) <= walkableClimb)
147  {
148  if (nbot < asmin) asmin = nbot;
149  if (nbot > asmax) asmax = nbot;
150  }
151 
152  }
153  }
154  }
155 
156  // The current span is close to a ledge if the drop to any
157  // neighbour span is less than the walkableClimb.
158  if (minh < -walkableClimb)
159  s->area = RC_NULL_AREA;
160 
161  // If the difference between all neighbours is too large,
162  // we are at steep slope, mark the span as ledge.
163  if ((asmax - asmin) > walkableClimb)
164  {
165  s->area = RC_NULL_AREA;
166  }
167  }
168  }
169  }
170 
172 }
#define rcAssert
Definition: RecastAssert.h:30
int width
The width of the heightfield. (Along the x-axis in cell units.)
Definition: Recast.h:276
T rcAbs(T a)
Definition: Recast.h:577
int rcGetDirOffsetY(int dir)
Definition: Recast.h:1048
T rcMin(T a, T b)
Definition: Recast.h:566
Definition: Recast.h:256
int rcGetDirOffsetX(int dir)
Definition: Recast.h:1038
G3D::int16 y
Definition: Vector2int16.h:38
unsigned int smin
The lower limit of the span. [Limit: < smax].
Definition: Recast.h:258
void startTimer(const rcTimerLabel label)
Definition: Recast.h:131
unsigned int smax
The upper limit of the span. [Limit: <= RC_SPAN_MAX_HEIGHT].
Definition: Recast.h:259
rcSpan * next
The next span higher up in column.
Definition: Recast.h:261
static const unsigned char RC_NULL_AREA
Definition: Recast.h:538
T rcMax(T a, T b)
Definition: Recast.h:572
G3D::int16 x
Definition: Vector2int16.h:37
int height
The height of the heightfield. (Along the z-axis in cell units.)
Definition: Recast.h:277
void stopTimer(const rcTimerLabel label)
Definition: Recast.h:135
#define MAX_HEIGHT
Definition: Map.h:247
The time to filter ledge spans. (See: rcFilterLedgeSpans)
Definition: Recast.h:53
rcSpan ** spans
Heightfield of spans (width*height).
Definition: Recast.h:282

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void rcFilterLowHangingWalkableObstacles ( rcContext ctx,
const int  walkableClimb,
rcHeightfield solid 
)

Allows the formation of walkable regions that will flow over low lying objects such as curbs, and up structures such as stairways.

Two neighboring spans are walkable if: rcAbs(currentSpan.smax - neighborSpan.smax) < waklableClimb

Warning
Will override the effect of rcFilterLedgeSpans. So if both filters are used, call rcFilterLedgeSpans after calling this filter.
See also
rcHeightfield, rcConfig
37 {
38  rcAssert(ctx);
39 
41 
42  const int w = solid.width;
43  const int h = solid.height;
44 
45  for (int y = 0; y < h; ++y)
46  {
47  for (int x = 0; x < w; ++x)
48  {
49  rcSpan* ps = 0;
50  bool previousWalkable = false;
51  unsigned char previousArea = RC_NULL_AREA;
52 
53  for (rcSpan* s = solid.spans[x + y*w]; s; ps = s, s = s->next)
54  {
55  const bool walkable = s->area != RC_NULL_AREA;
56  // If current span is not walkable, but there is walkable
57  // span just below it, mark the span above it walkable too.
58  if (!walkable && previousWalkable)
59  {
60  if (rcAbs((int)s->smax - (int)ps->smax) <= walkableClimb)
61  s->area = previousArea;
62  }
63  // Copy walkable flag so that it cannot propagate
64  // past multiple non-walkable objects.
65  previousWalkable = walkable;
66  previousArea = s->area;
67  }
68  }
69  }
70 
72 }
#define rcAssert
Definition: RecastAssert.h:30
int width
The width of the heightfield. (Along the x-axis in cell units.)
Definition: Recast.h:276
T rcAbs(T a)
Definition: Recast.h:577
Definition: Recast.h:256
G3D::int16 y
Definition: Vector2int16.h:38
void startTimer(const rcTimerLabel label)
Definition: Recast.h:131
unsigned int smax
The upper limit of the span. [Limit: <= RC_SPAN_MAX_HEIGHT].
Definition: Recast.h:259
rcSpan * next
The next span higher up in column.
Definition: Recast.h:261
static const unsigned char RC_NULL_AREA
Definition: Recast.h:538
G3D::int16 x
Definition: Vector2int16.h:37
int height
The height of the heightfield. (Along the z-axis in cell units.)
Definition: Recast.h:277
void stopTimer(const rcTimerLabel label)
Definition: Recast.h:135
rcSpan ** spans
Heightfield of spans (width*height).
Definition: Recast.h:282
The time to filter low obstacles. (See: rcFilterLowHangingWalkableObstacles)
Definition: Recast.h:59

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void rcFilterWalkableLowHeightSpans ( rcContext ctx,
int  walkableHeight,
rcHeightfield solid 
)

For this filter, the clearance above the span is the distance from the span's maximum to the next higher span's minimum. (Same grid column.)

See also
rcHeightfield, rcConfig
181 {
182  rcAssert(ctx);
183 
185 
186  const int w = solid.width;
187  const int h = solid.height;
188  const int MAX_HEIGHT = 0xffff;
189 
190  // Remove walkable flag from spans which do not have enough
191  // space above them for the agent to stand there.
192  for (int y = 0; y < h; ++y)
193  {
194  for (int x = 0; x < w; ++x)
195  {
196  for (rcSpan* s = solid.spans[x + y*w]; s; s = s->next)
197  {
198  const int bot = (int)(s->smax);
199  const int top = s->next ? (int)(s->next->smin) : MAX_HEIGHT;
200  if ((top - bot) <= walkableHeight)
201  s->area = RC_NULL_AREA;
202  }
203  }
204  }
205 
207 }
#define rcAssert
Definition: RecastAssert.h:30
int width
The width of the heightfield. (Along the x-axis in cell units.)
Definition: Recast.h:276
Definition: Recast.h:256
The time to filter low height spans. (See: rcFilterWalkableLowHeightSpans)
Definition: Recast.h:55
G3D::int16 y
Definition: Vector2int16.h:38
void startTimer(const rcTimerLabel label)
Definition: Recast.h:131
rcSpan * next
The next span higher up in column.
Definition: Recast.h:261
static const unsigned char RC_NULL_AREA
Definition: Recast.h:538
G3D::int16 x
Definition: Vector2int16.h:37
int height
The height of the heightfield. (Along the z-axis in cell units.)
Definition: Recast.h:277
void stopTimer(const rcTimerLabel label)
Definition: Recast.h:135
#define MAX_HEIGHT
Definition: Map.h:247
rcSpan ** spans
Heightfield of spans (width*height).
Definition: Recast.h:282

+ Here is the call graph for this function:

+ Here is the caller graph for this function: