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

Macros

#define _USE_MATH_DEFINES
 

Functions

bool overlapBounds (const float *amin, const float *amax, const float *bmin, const float *bmax)
 
bool overlapInterval (unsigned short amin, unsigned short amax, unsigned short bmin, unsigned short bmax)
 
static rcSpanallocSpan (rcHeightfield &hf)
 
static void freeSpan (rcHeightfield &hf, rcSpan *ptr)
 
static void addSpan (rcHeightfield &hf, const int x, const int y, const unsigned short smin, const unsigned short smax, const unsigned char area, const int flagMergeThr)
 
void rcAddSpan (rcContext *, rcHeightfield &hf, const int x, const int y, const unsigned short smin, const unsigned short smax, const unsigned char area, const int flagMergeThr)
 
static void dividePoly (const float *in, int nin, float *out1, int *nout1, float *out2, int *nout2, float x, int axis)
 
static void rasterizeTri (const float *v0, const float *v1, const float *v2, const unsigned char area, rcHeightfield &hf, const float *bmin, const float *bmax, const float cs, const float ics, const float ich, const int flagMergeThr)
 
void rcRasterizeTriangle (rcContext *ctx, const float *v0, const float *v1, const float *v2, const unsigned char area, rcHeightfield &solid, const int flagMergeThr)
 
void rcRasterizeTriangles (rcContext *ctx, const float *verts, const int, const int *tris, const unsigned char *areas, const int nt, rcHeightfield &solid, const int flagMergeThr)
 
void rcRasterizeTriangles (rcContext *ctx, const float *verts, const int, const unsigned short *tris, const unsigned char *areas, const int nt, rcHeightfield &solid, const int flagMergeThr)
 
void rcRasterizeTriangles (rcContext *ctx, const float *verts, const unsigned char *areas, const int nt, rcHeightfield &solid, const int flagMergeThr)
 

Macro Definition Documentation

#define _USE_MATH_DEFINES

Function Documentation

static void addSpan ( rcHeightfield hf,
const int  x,
const int  y,
const unsigned short  smin,
const unsigned short  smax,
const unsigned char  area,
const int  flagMergeThr 
)
static
88 {
89 
90  int idx = x + y*hf.width;
91 
92  rcSpan* s = allocSpan(hf);
93  s->smin = smin;
94  s->smax = smax;
95  s->area = area;
96  s->next = 0;
97 
98  // Empty cell, add the first span.
99  if (!hf.spans[idx])
100  {
101  hf.spans[idx] = s;
102  return;
103  }
104  rcSpan* prev = 0;
105  rcSpan* cur = hf.spans[idx];
106 
107  // Insert and merge spans.
108  while (cur)
109  {
110  if (cur->smin > s->smax)
111  {
112  // Current span is further than the new span, break.
113  break;
114  }
115  else if (cur->smax < s->smin)
116  {
117  // Current span is before the new span advance.
118  prev = cur;
119  cur = cur->next;
120  }
121  else
122  {
123  // Merge spans.
124  if (cur->smin < s->smin)
125  s->smin = cur->smin;
126  if (cur->smax > s->smax)
127  s->smax = cur->smax;
128 
129  // Merge flags.
130  if (rcAbs((int)s->smax - (int)cur->smax) <= flagMergeThr)
131  s->area = rcMax(s->area, cur->area);
132 
133  // Remove current span.
134  rcSpan* next = cur->next;
135  freeSpan(hf, cur);
136  if (prev)
137  prev->next = next;
138  else
139  hf.spans[idx] = next;
140  cur = next;
141  }
142  }
143 
144  // Insert new span.
145  if (prev)
146  {
147  s->next = prev->next;
148  prev->next = s;
149  }
150  else
151  {
152  s->next = hf.spans[idx];
153  hf.spans[idx] = s;
154  }
155 }
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
unsigned char area
The area id assigned to the span.
Definition: Recast.h:260
int next(int i, int n)
Definition: RecastContour.cpp:469
Definition: Recast.h:256
static void freeSpan(rcHeightfield &hf, rcSpan *ptr)
Definition: RecastRasterization.cpp:77
G3D::int16 y
Definition: Vector2int16.h:38
unsigned int smin
The lower limit of the span. [Limit: < smax].
Definition: Recast.h:258
unsigned int smax
The upper limit of the span. [Limit: <= RC_SPAN_MAX_HEIGHT].
Definition: Recast.h:259
int prev(int i, int n)
Definition: RecastContour.cpp:468
rcSpan * next
The next span higher up in column.
Definition: Recast.h:261
static rcSpan * allocSpan(rcHeightfield &hf)
Definition: RecastRasterization.cpp:44
T rcMax(T a, T b)
Definition: Recast.h:572
G3D::int16 x
Definition: Vector2int16.h:37
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:

static rcSpan* allocSpan ( rcHeightfield hf)
static
45 {
46  // If running out of memory, allocate new page and update the freelist.
47  if (!hf.freelist || !hf.freelist->next)
48  {
49  // Create new page.
50  // Allocate memory for the new pool.
52  if (!pool) return 0;
53 
54  // Add the pool into the list of pools.
55  pool->next = hf.pools;
56  hf.pools = pool;
57  // Add new items to the free list.
58  rcSpan* freelist = hf.freelist;
59  rcSpan* head = &pool->items[0];
60  rcSpan* it = &pool->items[RC_SPANS_PER_POOL];
61  do
62  {
63  --it;
64  it->next = freelist;
65  freelist = it;
66  }
67  while (it != head);
68  hf.freelist = it;
69  }
70 
71  // Pop item from in front of the free list.
72  rcSpan* it = hf.freelist;
73  hf.freelist = hf.freelist->next;
74  return it;
75 }
rcSpan items[RC_SPANS_PER_POOL]
Array of spans in the pool.
Definition: Recast.h:269
Definition: Recast.h:256
rcSpan * freelist
The next free span.
Definition: Recast.h:284
static const int RC_SPANS_PER_POOL
Definition: Recast.h:252
void * rcAlloc(int size, rcAllocHint hint)
Definition: RecastAlloc.cpp:44
Definition: Recast.h:266
Memory will persist after a function call.
Definition: RecastAlloc.h:26
rcSpan * next
The next span higher up in column.
Definition: Recast.h:261
rcSpanPool * next
The next span pool.
Definition: Recast.h:268
rcSpanPool * pools
Linked list of span pools.
Definition: Recast.h:283

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void dividePoly ( const float *  in,
int  nin,
float *  out1,
int *  nout1,
float *  out2,
int *  nout2,
float  x,
int  axis 
)
static
177 {
178  float d[12];
179  for (int i = 0; i < nin; ++i)
180  d[i] = x - in[i*3+axis];
181 
182  int m = 0, n = 0;
183  for (int i = 0, j = nin-1; i < nin; j=i, ++i)
184  {
185  bool ina = d[j] >= 0;
186  bool inb = d[i] >= 0;
187  if (ina != inb)
188  {
189  float s = d[j] / (d[j] - d[i]);
190  out1[m*3+0] = in[j*3+0] + (in[i*3+0] - in[j*3+0])*s;
191  out1[m*3+1] = in[j*3+1] + (in[i*3+1] - in[j*3+1])*s;
192  out1[m*3+2] = in[j*3+2] + (in[i*3+2] - in[j*3+2])*s;
193  rcVcopy(out2 + n*3, out1 + m*3);
194  m++;
195  n++;
196  // add the i'th point to the right polygon. Do NOT add points that are on the dividing line
197  // since these were already added above
198  if (d[i] > 0)
199  {
200  rcVcopy(out1 + m*3, in + i*3);
201  m++;
202  }
203  else if (d[i] < 0)
204  {
205  rcVcopy(out2 + n*3, in + i*3);
206  n++;
207  }
208  }
209  else // same side
210  {
211  // add the i'th point to the right polygon. Addition is done even for points on the dividing line
212  if (d[i] >= 0)
213  {
214  rcVcopy(out1 + m*3, in + i*3);
215  m++;
216  if (d[i] != 0)
217  continue;
218  }
219  rcVcopy(out2 + n*3, in + i*3);
220  n++;
221  }
222  }
223 
224  *nout1 = m;
225  *nout2 = n;
226 }
void rcVcopy(float *dest, const float *v)
Definition: Recast.h:677
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static void freeSpan ( rcHeightfield hf,
rcSpan ptr 
)
static
78 {
79  if (!ptr) return;
80  // Add the node in front of the free list.
81  ptr->next = hf.freelist;
82  hf.freelist = ptr;
83 }
rcSpan * freelist
The next free span.
Definition: Recast.h:284
rcSpan * next
The next span higher up in column.
Definition: Recast.h:261

+ Here is the caller graph for this function:

bool overlapBounds ( const float *  amin,
const float *  amax,
const float *  bmin,
const float *  bmax 
)
inline
27 {
28  bool overlap = true;
29  overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap;
30  overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap;
31  overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap;
32  return overlap;
33 }

+ Here is the caller graph for this function:

bool overlapInterval ( unsigned short  amin,
unsigned short  amax,
unsigned short  bmin,
unsigned short  bmax 
)
inline
37 {
38  if (amax < bmin) return false;
39  if (amin > bmax) return false;
40  return true;
41 }
static void rasterizeTri ( const float *  v0,
const float *  v1,
const float *  v2,
const unsigned char  area,
rcHeightfield hf,
const float *  bmin,
const float *  bmax,
const float  cs,
const float  ics,
const float  ich,
const int  flagMergeThr 
)
static
235 {
236  const int w = hf.width;
237  const int h = hf.height;
238  float tmin[3], tmax[3];
239  const float by = bmax[1] - bmin[1];
240 
241  // Calculate the bounding box of the triangle.
242  rcVcopy(tmin, v0);
243  rcVcopy(tmax, v0);
244  rcVmin(tmin, v1);
245  rcVmin(tmin, v2);
246  rcVmax(tmax, v1);
247  rcVmax(tmax, v2);
248 
249  // If the triangle does not touch the bbox of the heightfield, skip the triagle.
250  if (!overlapBounds(bmin, bmax, tmin, tmax))
251  return;
252 
253  // Calculate the footprint of the triangle on the grid's y-axis
254  int y0 = (int)((tmin[2] - bmin[2])*ics);
255  int y1 = (int)((tmax[2] - bmin[2])*ics);
256  y0 = rcClamp(y0, 0, h-1);
257  y1 = rcClamp(y1, 0, h-1);
258 
259  // Clip the triangle into all grid cells it touches.
260  float buf[7*3*4];
261  float *in = buf, *inrow = buf+7*3, *p1 = inrow+7*3, *p2 = p1+7*3;
262 
263  rcVcopy(&in[0], v0);
264  rcVcopy(&in[1*3], v1);
265  rcVcopy(&in[2*3], v2);
266  int nvrow, nvIn = 3;
267 
268  for (int y = y0; y <= y1; ++y)
269  {
270  // Clip polygon to row. Store the remaining polygon as well
271  const float cz = bmin[2] + y*cs;
272  dividePoly(in, nvIn, inrow, &nvrow, p1, &nvIn, cz+cs, 2);
273  rcSwap(in, p1);
274  if (nvrow < 3) continue;
275 
276  // find the horizontal bounds in the row
277  float minX = inrow[0], maxX = inrow[0];
278  for (int i=1; i<nvrow; ++i)
279  {
280  if (minX > inrow[i*3]) minX = inrow[i*3];
281  if (maxX < inrow[i*3]) maxX = inrow[i*3];
282  }
283  int x0 = (int)((minX - bmin[0])*ics);
284  int x1 = (int)((maxX - bmin[0])*ics);
285  x0 = rcClamp(x0, 0, w-1);
286  x1 = rcClamp(x1, 0, w-1);
287 
288  int nv, nv2 = nvrow;
289 
290  for (int x = x0; x <= x1; ++x)
291  {
292  // Clip polygon to column. store the remaining polygon as well
293  const float cx = bmin[0] + x*cs;
294  dividePoly(inrow, nv2, p1, &nv, p2, &nv2, cx+cs, 0);
295  rcSwap(inrow, p2);
296  if (nv < 3) continue;
297 
298  // Calculate min and max of the span.
299  float smin = p1[1], smax = p1[1];
300  for (int i = 1; i < nv; ++i)
301  {
302  smin = rcMin(smin, p1[i*3+1]);
303  smax = rcMax(smax, p1[i*3+1]);
304  }
305  smin -= bmin[1];
306  smax -= bmin[1];
307  // Skip the span if it is outside the heightfield bbox
308  if (smax < 0.0f) continue;
309  if (smin > by) continue;
310  // Clamp the span to the heightfield bbox.
311  if (smin < 0.0f) smin = 0;
312  if (smax > by) smax = by;
313 
314  // Snap the span to the heightfield height grid.
315  unsigned short ismin = (unsigned short)rcClamp((int)floorf(smin * ich), 0, RC_SPAN_MAX_HEIGHT);
316  unsigned short ismax = (unsigned short)rcClamp((int)ceilf(smax * ich), (int)ismin+1, RC_SPAN_MAX_HEIGHT);
317 
318  addSpan(hf, x, y, ismin, ismax, area, flagMergeThr);
319  }
320  }
321 }
int width
The width of the heightfield. (Along the x-axis in cell units.)
Definition: Recast.h:276
void rcSwap(T &a, T &b)
Definition: Recast.h:560
T rcMin(T a, T b)
Definition: Recast.h:566
void rcVmin(float *mn, const float *v)
Definition: Recast.h:657
bool overlapBounds(const float *amin, const float *amax, const float *bmin, const float *bmax)
Definition: RecastRasterization.cpp:26
static const int RC_SPAN_MAX_HEIGHT
Defines the maximum value for rcSpan::smin and rcSpan::smax.
Definition: Recast.h:248
G3D::int16 y
Definition: Vector2int16.h:38
void rcVcopy(float *dest, const float *v)
Definition: Recast.h:677
T rcClamp(T v, T mn, T mx)
Definition: Recast.h:589
static void addSpan(rcHeightfield &hf, const int x, const int y, const unsigned short smin, const unsigned short smax, const unsigned char area, const int flagMergeThr)
Definition: RecastRasterization.cpp:85
T rcMax(T a, T b)
Definition: Recast.h:572
G3D::int16 x
Definition: Vector2int16.h:37
static void dividePoly(const float *in, int nin, float *out1, int *nout1, float *out2, int *nout2, float x, int axis)
Definition: RecastRasterization.cpp:173
int height
The height of the heightfield. (Along the z-axis in cell units.)
Definition: Recast.h:277
void rcVmax(float *mx, const float *v)
Definition: Recast.h:667

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void rcAddSpan ( rcContext ,
rcHeightfield hf,
const int  x,
const int  y,
const unsigned short  smin,
const unsigned short  smax,
const unsigned char  area,
const int  flagMergeThr 
)

The span addition can be set to favor flags. If the span is merged to another span and the new smax is within flagMergeThr units from the existing span, the span flags are merged.

See also
rcHeightfield, rcSpan.
167 {
168 // rcAssert(ctx);
169  addSpan(hf, x,y, smin, smax, area, flagMergeThr);
170 }
G3D::int16 y
Definition: Vector2int16.h:38
static void addSpan(rcHeightfield &hf, const int x, const int y, const unsigned short smin, const unsigned short smax, const unsigned char area, const int flagMergeThr)
Definition: RecastRasterization.cpp:85
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

void rcRasterizeTriangle ( rcContext ctx,
const float *  v0,
const float *  v1,
const float *  v2,
const unsigned char  area,
rcHeightfield solid,
const int  flagMergeThr 
)

No spans will be added if the triangle does not overlap the heightfield grid.

See also
rcHeightfield
331 {
332  rcAssert(ctx);
333 
335 
336  const float ics = 1.0f/solid.cs;
337  const float ich = 1.0f/solid.ch;
338  rasterizeTri(v0, v1, v2, area, solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
339 
341 }
#define rcAssert
Definition: RecastAssert.h:30
float ch
The height of each cell. (The minimum increment along the y-axis.)
Definition: Recast.h:281
The time to rasterize the triangles. (See: rcRasterizeTriangle)
Definition: Recast.h:43
static void rasterizeTri(const float *v0, const float *v1, const float *v2, const unsigned char area, rcHeightfield &hf, const float *bmin, const float *bmax, const float cs, const float ics, const float ich, const int flagMergeThr)
Definition: RecastRasterization.cpp:230
float bmax[3]
The maximum bounds in world space. [(x, y, z)].
Definition: Recast.h:279
float cs
The size of each cell. (On the xz-plane.)
Definition: Recast.h:280
void startTimer(const rcTimerLabel label)
Definition: Recast.h:131
float bmin[3]
The minimum bounds in world space. [(x, y, z)].
Definition: Recast.h:278
void stopTimer(const rcTimerLabel label)
Definition: Recast.h:135

+ Here is the call graph for this function:

void rcRasterizeTriangles ( rcContext ctx,
const float *  verts,
const int  ,
const int *  tris,
const unsigned char *  areas,
const int  nt,
rcHeightfield solid,
const int  flagMergeThr 
)

Spans will only be added for triangles that overlap the heightfield grid.

See also
rcHeightfield
351 {
352  rcAssert(ctx);
353 
355 
356  const float ics = 1.0f/solid.cs;
357  const float ich = 1.0f/solid.ch;
358  // Rasterize triangles.
359  for (int i = 0; i < nt; ++i)
360  {
361  const float* v0 = &verts[tris[i*3+0]*3];
362  const float* v1 = &verts[tris[i*3+1]*3];
363  const float* v2 = &verts[tris[i*3+2]*3];
364  // Rasterize.
365  rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
366  }
367 
369 }
#define rcAssert
Definition: RecastAssert.h:30
float ch
The height of each cell. (The minimum increment along the y-axis.)
Definition: Recast.h:281
The time to rasterize the triangles. (See: rcRasterizeTriangle)
Definition: Recast.h:43
static void rasterizeTri(const float *v0, const float *v1, const float *v2, const unsigned char area, rcHeightfield &hf, const float *bmin, const float *bmax, const float cs, const float ics, const float ich, const int flagMergeThr)
Definition: RecastRasterization.cpp:230
float bmax[3]
The maximum bounds in world space. [(x, y, z)].
Definition: Recast.h:279
float cs
The size of each cell. (On the xz-plane.)
Definition: Recast.h:280
void startTimer(const rcTimerLabel label)
Definition: Recast.h:131
float bmin[3]
The minimum bounds in world space. [(x, y, z)].
Definition: Recast.h:278
void stopTimer(const rcTimerLabel label)
Definition: Recast.h:135

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void rcRasterizeTriangles ( rcContext ctx,
const float *  verts,
const int  ,
const unsigned short *  tris,
const unsigned char *  areas,
const int  nt,
rcHeightfield solid,
const int  flagMergeThr 
)

Spans will only be added for triangles that overlap the heightfield grid.

See also
rcHeightfield
379 {
380  rcAssert(ctx);
381 
383 
384  const float ics = 1.0f/solid.cs;
385  const float ich = 1.0f/solid.ch;
386  // Rasterize triangles.
387  for (int i = 0; i < nt; ++i)
388  {
389  const float* v0 = &verts[tris[i*3+0]*3];
390  const float* v1 = &verts[tris[i*3+1]*3];
391  const float* v2 = &verts[tris[i*3+2]*3];
392  // Rasterize.
393  rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
394  }
395 
397 }
#define rcAssert
Definition: RecastAssert.h:30
float ch
The height of each cell. (The minimum increment along the y-axis.)
Definition: Recast.h:281
The time to rasterize the triangles. (See: rcRasterizeTriangle)
Definition: Recast.h:43
static void rasterizeTri(const float *v0, const float *v1, const float *v2, const unsigned char area, rcHeightfield &hf, const float *bmin, const float *bmax, const float cs, const float ics, const float ich, const int flagMergeThr)
Definition: RecastRasterization.cpp:230
float bmax[3]
The maximum bounds in world space. [(x, y, z)].
Definition: Recast.h:279
float cs
The size of each cell. (On the xz-plane.)
Definition: Recast.h:280
void startTimer(const rcTimerLabel label)
Definition: Recast.h:131
float bmin[3]
The minimum bounds in world space. [(x, y, z)].
Definition: Recast.h:278
void stopTimer(const rcTimerLabel label)
Definition: Recast.h:135

+ Here is the call graph for this function:

void rcRasterizeTriangles ( rcContext ctx,
const float *  verts,
const unsigned char *  areas,
const int  nt,
rcHeightfield solid,
const int  flagMergeThr 
)

Spans will only be added for triangles that overlap the heightfield grid.

See also
rcHeightfield
406 {
407  rcAssert(ctx);
408 
410 
411  const float ics = 1.0f/solid.cs;
412  const float ich = 1.0f/solid.ch;
413  // Rasterize triangles.
414  for (int i = 0; i < nt; ++i)
415  {
416  const float* v0 = &verts[(i*3+0)*3];
417  const float* v1 = &verts[(i*3+1)*3];
418  const float* v2 = &verts[(i*3+2)*3];
419  // Rasterize.
420  rasterizeTri(v0, v1, v2, areas[i], solid, solid.bmin, solid.bmax, solid.cs, ics, ich, flagMergeThr);
421  }
422 
424 }
#define rcAssert
Definition: RecastAssert.h:30
float ch
The height of each cell. (The minimum increment along the y-axis.)
Definition: Recast.h:281
The time to rasterize the triangles. (See: rcRasterizeTriangle)
Definition: Recast.h:43
static void rasterizeTri(const float *v0, const float *v1, const float *v2, const unsigned char area, rcHeightfield &hf, const float *bmin, const float *bmax, const float cs, const float ics, const float ich, const int flagMergeThr)
Definition: RecastRasterization.cpp:230
float bmax[3]
The maximum bounds in world space. [(x, y, z)].
Definition: Recast.h:279
float cs
The size of each cell. (On the xz-plane.)
Definition: Recast.h:280
void startTimer(const rcTimerLabel label)
Definition: Recast.h:131
float bmin[3]
The minimum bounds in world space. [(x, y, z)].
Definition: Recast.h:278
void stopTimer(const rcTimerLabel label)
Definition: Recast.h:135

+ Here is the call graph for this function: