TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
BIH Class Reference

#include <BoundingIntervalHierarchy.h>

Classes

struct  buildData
 
class  BuildStats
 
struct  StackNode
 

Public Member Functions

 BIH ()
 
template<class BoundsFunc , class PrimArray >
void build (const PrimArray &primitives, BoundsFunc &getBounds, uint32 leafSize=3, bool printStats=false)
 
uint32 primCount () const
 
template<typename RayCallback >
void intersectRay (const G3D::Ray &r, RayCallback &intersectCallback, float &maxDist, bool stopAtFirst=false) const
 
template<typename IsectCallback >
void intersectPoint (const G3D::Vector3 &p, IsectCallback &intersectCallback) const
 
bool writeToFile (FILE *wf) const
 
bool readFromFile (FILE *rf)
 

Protected Member Functions

void buildHierarchy (std::vector< uint32 > &tempTree, buildData &dat, BuildStats &stats)
 
void createNode (std::vector< uint32 > &tempTree, int nodeIndex, uint32 left, uint32 right) const
 
void subdivide (int left, int right, std::vector< uint32 > &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)
 

Protected Attributes

std::vector< uint32tree
 
std::vector< uint32objects
 
G3D::AABox bounds
 

Private Member Functions

void init_empty ()
 

Detailed Description

Bounding Interval Hierarchy Class. Building and Ray-Intersection functions based on BIH from Sunflow, a Java Raytracer, released under MIT/X11 License http://sunflow.sourceforge.net/ Copyright (c) 2003-2007 Christopher Kulla

Constructor & Destructor Documentation

BIH::BIH ( )
inline
82 { init_empty(); }
void init_empty()
Definition: BoundingIntervalHierarchy.h:73

Member Function Documentation

template<class BoundsFunc , class PrimArray >
void BIH::build ( const PrimArray &  primitives,
BoundsFunc &  getBounds,
uint32  leafSize = 3,
bool  printStats = false 
)
inline
85  {
86  if (primitives.size() == 0)
87  {
88  init_empty();
89  return;
90  }
91 
92  buildData dat;
93  dat.maxPrims = leafSize;
94  dat.numPrims = uint32(primitives.size());
95  dat.indices = new uint32[dat.numPrims];
96  dat.primBound = new G3D::AABox[dat.numPrims];
97  getBounds(primitives[0], bounds);
98  for (uint32 i=0; i<dat.numPrims; ++i)
99  {
100  dat.indices[i] = i;
101  getBounds(primitives[i], dat.primBound[i]);
102  bounds.merge(dat.primBound[i]);
103  }
104  std::vector<uint32> tempTree;
105  BuildStats stats;
106  buildHierarchy(tempTree, dat, stats);
107  if (printStats)
108  stats.printStats();
109 
110  objects.resize(dat.numPrims);
111  for (uint32 i=0; i<dat.numPrims; ++i)
112  objects[i] = dat.indices[i];
113  //nObjects = dat.numPrims;
114  tree = tempTree;
115  delete[] dat.primBound;
116  delete[] dat.indices;
117  }
void merge(const AABox &a)
Definition: AABox.h:106
void buildHierarchy(std::vector< uint32 > &tempTree, buildData &dat, BuildStats &stats)
Definition: BoundingIntervalHierarchy.cpp:27
void init_empty()
Definition: BoundingIntervalHierarchy.h:73
std::vector< uint32 > objects
Definition: BoundingIntervalHierarchy.h:342
G3D::AABox bounds
Definition: BoundingIntervalHierarchy.h:343
uint32_t uint32
Definition: Define.h:150
Definition: AABox.h:32
uint32_t uint32
Definition: g3dmath.h:168
std::vector< uint32 > tree
Definition: BoundingIntervalHierarchy.h:341

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void BIH::buildHierarchy ( std::vector< uint32 > &  tempTree,
buildData dat,
BuildStats stats 
)
protected
28 {
29  // create space for the first node
30  tempTree.push_back(uint32(3 << 30)); // dummy leaf
31  tempTree.insert(tempTree.end(), 2, 0);
32  //tempTree.add(0);
33 
34  // seed bbox
35  AABound gridBox = { bounds.low(), bounds.high() };
36  AABound nodeBox = gridBox;
37  // seed subdivide function
38  subdivide(0, dat.numPrims - 1, tempTree, dat, gridBox, nodeBox, 0, 1, stats);
39 }
Definition: BoundingIntervalHierarchy.h:58
const Point3 & low() const
Definition: AABox.h:136
G3D::AABox bounds
Definition: BoundingIntervalHierarchy.h:343
void subdivide(int left, int right, std::vector< uint32 > &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)
Definition: BoundingIntervalHierarchy.cpp:41
uint32_t uint32
Definition: g3dmath.h:168
const Point3 & high() const
Definition: AABox.h:141

+ Here is the call graph for this function:

void BIH::createNode ( std::vector< uint32 > &  tempTree,
int  nodeIndex,
uint32  left,
uint32  right 
) const
inlineprotected
391  {
392  // write leaf node
393  tempTree[nodeIndex + 0] = (3 << 30) | left;
394  tempTree[nodeIndex + 1] = right - left + 1;
395  }
bool left(const int *a, const int *b, const int *c)
Definition: RecastContour.cpp:487

+ Here is the caller graph for this function:

void BIH::init_empty ( )
inlineprivate
74  {
75  tree.clear();
76  objects.clear();
77  // create space for the first node
78  tree.push_back(3u << 30u); // dummy leaf
79  tree.insert(tree.end(), 2, 0);
80  }
std::vector< uint32 > objects
Definition: BoundingIntervalHierarchy.h:342
std::vector< uint32 > tree
Definition: BoundingIntervalHierarchy.h:341
template<typename IsectCallback >
void BIH::intersectPoint ( const G3D::Vector3 p,
IsectCallback &  intersectCallback 
) const
inline
261  {
262  if (!bounds.contains(p))
263  return;
264 
265  StackNode stack[MAX_STACK_SIZE];
266  int stackPos = 0;
267  int node = 0;
268 
269  while (true) {
270  while (true)
271  {
272  uint32 tn = tree[node];
273  uint32 axis = (tn & (3 << 30)) >> 30;
274  bool BVH2 = (tn & (1 << 29)) != 0;
275  int offset = tn & ~(7 << 29);
276  if (!BVH2)
277  {
278  if (axis < 3)
279  {
280  // "normal" interior node
281  float tl = intBitsToFloat(tree[node + 1]);
282  float tr = intBitsToFloat(tree[node + 2]);
283  // point is between clip zones
284  if (tl < p[axis] && tr > p[axis])
285  break;
286  int right = offset + 3;
287  node = right;
288  // point is in right node only
289  if (tl < p[axis]) {
290  continue;
291  }
292  node = offset; // left
293  // point is in left node only
294  if (tr > p[axis]) {
295  continue;
296  }
297  // point is in both nodes
298  // push back right node
299  stack[stackPos].node = right;
300  stackPos++;
301  continue;
302  }
303  else
304  {
305  // leaf - test some objects
306  int n = tree[node + 1];
307  while (n > 0) {
308  intersectCallback(p, objects[offset]); // !!!
309  --n;
310  ++offset;
311  }
312  break;
313  }
314  }
315  else // BVH2 node (empty space cut off left and right)
316  {
317  if (axis>2)
318  return; // should not happen
319  float tl = intBitsToFloat(tree[node + 1]);
320  float tr = intBitsToFloat(tree[node + 2]);
321  node = offset;
322  if (tl > p[axis] || tr < p[axis])
323  break;
324  continue;
325  }
326  } // traversal loop
327 
328  // stack is empty?
329  if (stackPos == 0)
330  return;
331  // move back up the stack
332  stackPos--;
333  node = stack[stackPos].node;
334  }
335  }
bool contains(const AABox &other) const
Definition: AABox.h:238
std::vector< uint32 > objects
Definition: BoundingIntervalHierarchy.h:342
static float intBitsToFloat(uint32 i)
Definition: BoundingIntervalHierarchy.h:47
G3D::AABox bounds
Definition: BoundingIntervalHierarchy.h:343
uint32_t uint32
Definition: Define.h:150
#define MAX_STACK_SIZE
Definition: BoundingIntervalHierarchy.h:34
std::vector< uint32 > tree
Definition: BoundingIntervalHierarchy.h:341

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<typename RayCallback >
void BIH::intersectRay ( const G3D::Ray r,
RayCallback &  intersectCallback,
float &  maxDist,
bool  stopAtFirst = false 
) const
inline
122  {
123  float intervalMin = -1.f;
124  float intervalMax = -1.f;
125  G3D::Vector3 org = r.origin();
126  G3D::Vector3 dir = r.direction();
127  G3D::Vector3 invDir;
128  for (int i=0; i<3; ++i)
129  {
130  invDir[i] = 1.f / dir[i];
131  if (G3D::fuzzyNe(dir[i], 0.0f))
132  {
133  float t1 = (bounds.low()[i] - org[i]) * invDir[i];
134  float t2 = (bounds.high()[i] - org[i]) * invDir[i];
135  if (t1 > t2)
136  std::swap(t1, t2);
137  if (t1 > intervalMin)
138  intervalMin = t1;
139  if (t2 < intervalMax || intervalMax < 0.f)
140  intervalMax = t2;
141  // intervalMax can only become smaller for other axis,
142  // and intervalMin only larger respectively, so stop early
143  if (intervalMax <= 0 || intervalMin >= maxDist)
144  return;
145  }
146  }
147 
148  if (intervalMin > intervalMax)
149  return;
150  intervalMin = std::max(intervalMin, 0.f);
151  intervalMax = std::min(intervalMax, maxDist);
152 
153  uint32 offsetFront[3];
154  uint32 offsetBack[3];
155  uint32 offsetFront3[3];
156  uint32 offsetBack3[3];
157  // compute custom offsets from direction sign bit
158 
159  for (int i=0; i<3; ++i)
160  {
161  offsetFront[i] = floatToRawIntBits(dir[i]) >> 31;
162  offsetBack[i] = offsetFront[i] ^ 1;
163  offsetFront3[i] = offsetFront[i] * 3;
164  offsetBack3[i] = offsetBack[i] * 3;
165 
166  // avoid always adding 1 during the inner loop
167  ++offsetFront[i];
168  ++offsetBack[i];
169  }
170 
171  StackNode stack[MAX_STACK_SIZE];
172  int stackPos = 0;
173  int node = 0;
174 
175  while (true) {
176  while (true)
177  {
178  uint32 tn = tree[node];
179  uint32 axis = (tn & (3 << 30)) >> 30;
180  bool BVH2 = (tn & (1 << 29)) != 0;
181  int offset = tn & ~(7 << 29);
182  if (!BVH2)
183  {
184  if (axis < 3)
185  {
186  // "normal" interior node
187  float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
188  float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
189  // ray passes between clip zones
190  if (tf < intervalMin && tb > intervalMax)
191  break;
192  int back = offset + offsetBack3[axis];
193  node = back;
194  // ray passes through far node only
195  if (tf < intervalMin) {
196  intervalMin = (tb >= intervalMin) ? tb : intervalMin;
197  continue;
198  }
199  node = offset + offsetFront3[axis]; // front
200  // ray passes through near node only
201  if (tb > intervalMax) {
202  intervalMax = (tf <= intervalMax) ? tf : intervalMax;
203  continue;
204  }
205  // ray passes through both nodes
206  // push back node
207  stack[stackPos].node = back;
208  stack[stackPos].tnear = (tb >= intervalMin) ? tb : intervalMin;
209  stack[stackPos].tfar = intervalMax;
210  stackPos++;
211  // update ray interval for front node
212  intervalMax = (tf <= intervalMax) ? tf : intervalMax;
213  continue;
214  }
215  else
216  {
217  // leaf - test some objects
218  int n = tree[node + 1];
219  while (n > 0) {
220  bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirst);
221  if (stopAtFirst && hit) return;
222  --n;
223  ++offset;
224  }
225  break;
226  }
227  }
228  else
229  {
230  if (axis>2)
231  return; // should not happen
232  float tf = (intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
233  float tb = (intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
234  node = offset;
235  intervalMin = (tf >= intervalMin) ? tf : intervalMin;
236  intervalMax = (tb <= intervalMax) ? tb : intervalMax;
237  if (intervalMin > intervalMax)
238  break;
239  continue;
240  }
241  } // traversal loop
242  do
243  {
244  // stack is empty?
245  if (stackPos == 0)
246  return;
247  // move back up the stack
248  stackPos--;
249  intervalMin = stack[stackPos].tnear;
250  if (maxDist < intervalMin)
251  continue;
252  node = stack[stackPos].node;
253  intervalMax = stack[stackPos].tfar;
254  break;
255  } while (true);
256  }
257  }
static uint32 floatToRawIntBits(float f)
Definition: BoundingIntervalHierarchy.h:36
bool fuzzyNe(double a, double b)
Definition: g3dmath.h:861
const Point3 & low() const
Definition: AABox.h:136
T max(const T &x, const T &y)
Definition: g3dmath.h:320
Definition: Vector3.h:58
std::vector< uint32 > objects
Definition: BoundingIntervalHierarchy.h:342
static float intBitsToFloat(uint32 i)
Definition: BoundingIntervalHierarchy.h:47
G3D::AABox bounds
Definition: BoundingIntervalHierarchy.h:343
T min(const T &x, const T &y)
Definition: g3dmath.h:305
uint32_t uint32
Definition: Define.h:150
const Point3 & origin() const
Definition: Ray.h:56
const Point3 & high() const
Definition: AABox.h:141
#define MAX_STACK_SIZE
Definition: BoundingIntervalHierarchy.h:34
const Vector3 & direction() const
Definition: Ray.h:61
std::vector< uint32 > tree
Definition: BoundingIntervalHierarchy.h:341

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

uint32 BIH::primCount ( ) const
inline
118 { return uint32(objects.size()); }
std::vector< uint32 > objects
Definition: BoundingIntervalHierarchy.h:342
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the caller graph for this function:

bool BIH::readFromFile ( FILE *  rf)
262 {
263  uint32 treeSize;
264  G3D::Vector3 lo, hi;
265  uint32 check=0, count=0;
266  check += fread(&lo, sizeof(float), 3, rf);
267  check += fread(&hi, sizeof(float), 3, rf);
268  bounds = G3D::AABox(lo, hi);
269  check += fread(&treeSize, sizeof(uint32), 1, rf);
270  tree.resize(treeSize);
271  check += fread(&tree[0], sizeof(uint32), treeSize, rf);
272  check += fread(&count, sizeof(uint32), 1, rf);
273  objects.resize(count); // = new uint32[nObjects];
274  check += fread(&objects[0], sizeof(uint32), count, rf);
275  return uint64(check) == uint64(3 + 3 + 1 + 1 + uint64(treeSize) + uint64(count));
276 }
uint64_t uint64
Definition: g3dmath.h:170
Definition: Vector3.h:58
std::vector< uint32 > objects
Definition: BoundingIntervalHierarchy.h:342
G3D::AABox bounds
Definition: BoundingIntervalHierarchy.h:343
uint32_t uint32
Definition: Define.h:150
Definition: AABox.h:32
T check(T value)
Definition: format.h:305
std::vector< uint32 > tree
Definition: BoundingIntervalHierarchy.h:341

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void BIH::subdivide ( int  left,
int  right,
std::vector< uint32 > &  tempTree,
buildData dat,
AABound gridBox,
AABound nodeBox,
int  nodeIndex,
int  depth,
BuildStats stats 
)
protected
42 {
43  if ((right - left + 1) <= dat.maxPrims || depth >= MAX_STACK_SIZE)
44  {
45  // write leaf node
46  stats.updateLeaf(depth, right - left + 1);
47  createNode(tempTree, nodeIndex, left, right);
48  return;
49  }
50  // calculate extents
51  int axis = -1, prevAxis, rightOrig;
52  float clipL = G3D::fnan(), clipR = G3D::fnan(), prevClip = G3D::fnan();
53  float split = G3D::fnan(), prevSplit;
54  bool wasLeft = true;
55  while (true)
56  {
57  prevAxis = axis;
58  prevSplit = split;
59  // perform quick consistency checks
60  G3D::Vector3 d( gridBox.hi - gridBox.lo );
61  if (d.x < 0 || d.y < 0 || d.z < 0)
62  throw std::logic_error("negative node extents");
63  for (int i = 0; i < 3; i++)
64  {
65  if (nodeBox.hi[i] < gridBox.lo[i] || nodeBox.lo[i] > gridBox.hi[i])
66  {
67  //UI.printError(Module.ACCEL, "Reached tree area in error - discarding node with: %d objects", right - left + 1);
68  throw std::logic_error("invalid node overlap");
69  }
70  }
71  // find longest axis
72  axis = d.primaryAxis();
73  split = 0.5f * (gridBox.lo[axis] + gridBox.hi[axis]);
74  // partition L/R subsets
75  clipL = -G3D::finf();
76  clipR = G3D::finf();
77  rightOrig = right; // save this for later
78  float nodeL = G3D::finf();
79  float nodeR = -G3D::finf();
80  for (int i = left; i <= right;)
81  {
82  int obj = dat.indices[i];
83  float minb = dat.primBound[obj].low()[axis];
84  float maxb = dat.primBound[obj].high()[axis];
85  float center = (minb + maxb) * 0.5f;
86  if (center <= split)
87  {
88  // stay left
89  i++;
90  if (clipL < maxb)
91  clipL = maxb;
92  }
93  else
94  {
95  // move to the right most
96  int t = dat.indices[i];
97  dat.indices[i] = dat.indices[right];
98  dat.indices[right] = t;
99  right--;
100  if (clipR > minb)
101  clipR = minb;
102  }
103  nodeL = std::min(nodeL, minb);
104  nodeR = std::max(nodeR, maxb);
105  }
106  // check for empty space
107  if (nodeL > nodeBox.lo[axis] && nodeR < nodeBox.hi[axis])
108  {
109  float nodeBoxW = nodeBox.hi[axis] - nodeBox.lo[axis];
110  float nodeNewW = nodeR - nodeL;
111  // node box is too big compare to space occupied by primitives?
112  if (1.3f * nodeNewW < nodeBoxW)
113  {
114  stats.updateBVH2();
115  int nextIndex = tempTree.size();
116  // allocate child
117  tempTree.push_back(0);
118  tempTree.push_back(0);
119  tempTree.push_back(0);
120  // write bvh2 clip node
121  stats.updateInner();
122  tempTree[nodeIndex + 0] = (axis << 30) | (1 << 29) | nextIndex;
123  tempTree[nodeIndex + 1] = floatToRawIntBits(nodeL);
124  tempTree[nodeIndex + 2] = floatToRawIntBits(nodeR);
125  // update nodebox and recurse
126  nodeBox.lo[axis] = nodeL;
127  nodeBox.hi[axis] = nodeR;
128  subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex, depth + 1, stats);
129  return;
130  }
131  }
132  // ensure we are making progress in the subdivision
133  if (right == rightOrig)
134  {
135  // all left
136  if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
137  // we are stuck here - create a leaf
138  stats.updateLeaf(depth, right - left + 1);
139  createNode(tempTree, nodeIndex, left, right);
140  return;
141  }
142  if (clipL <= split) {
143  // keep looping on left half
144  gridBox.hi[axis] = split;
145  prevClip = clipL;
146  wasLeft = true;
147  continue;
148  }
149  gridBox.hi[axis] = split;
150  prevClip = G3D::fnan();
151  }
152  else if (left > right)
153  {
154  // all right
155  if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
156  // we are stuck here - create a leaf
157  stats.updateLeaf(depth, right - left + 1);
158  createNode(tempTree, nodeIndex, left, right);
159  return;
160  }
161  right = rightOrig;
162  if (clipR >= split) {
163  // keep looping on right half
164  gridBox.lo[axis] = split;
165  prevClip = clipR;
166  wasLeft = false;
167  continue;
168  }
169  gridBox.lo[axis] = split;
170  prevClip = G3D::fnan();
171  }
172  else
173  {
174  // we are actually splitting stuff
175  if (prevAxis != -1 && !isnan(prevClip))
176  {
177  // second time through - lets create the previous split
178  // since it produced empty space
179  int nextIndex = tempTree.size();
180  // allocate child node
181  tempTree.push_back(0);
182  tempTree.push_back(0);
183  tempTree.push_back(0);
184  if (wasLeft) {
185  // create a node with a left child
186  // write leaf node
187  stats.updateInner();
188  tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
189  tempTree[nodeIndex + 1] = floatToRawIntBits(prevClip);
190  tempTree[nodeIndex + 2] = floatToRawIntBits(G3D::finf());
191  } else {
192  // create a node with a right child
193  // write leaf node
194  stats.updateInner();
195  tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3);
196  tempTree[nodeIndex + 1] = floatToRawIntBits(-G3D::finf());
197  tempTree[nodeIndex + 2] = floatToRawIntBits(prevClip);
198  }
199  // count stats for the unused leaf
200  depth++;
201  stats.updateLeaf(depth, 0);
202  // now we keep going as we are, with a new nodeIndex:
203  nodeIndex = nextIndex;
204  }
205  break;
206  }
207  }
208  // compute index of child nodes
209  int nextIndex = tempTree.size();
210  // allocate left node
211  int nl = right - left + 1;
212  int nr = rightOrig - (right + 1) + 1;
213  if (nl > 0) {
214  tempTree.push_back(0);
215  tempTree.push_back(0);
216  tempTree.push_back(0);
217  } else
218  nextIndex -= 3;
219  // allocate right node
220  if (nr > 0) {
221  tempTree.push_back(0);
222  tempTree.push_back(0);
223  tempTree.push_back(0);
224  }
225  // write leaf node
226  stats.updateInner();
227  tempTree[nodeIndex + 0] = (axis << 30) | nextIndex;
228  tempTree[nodeIndex + 1] = floatToRawIntBits(clipL);
229  tempTree[nodeIndex + 2] = floatToRawIntBits(clipR);
230  // prepare L/R child boxes
231  AABound gridBoxL(gridBox), gridBoxR(gridBox);
232  AABound nodeBoxL(nodeBox), nodeBoxR(nodeBox);
233  gridBoxL.hi[axis] = gridBoxR.lo[axis] = split;
234  nodeBoxL.hi[axis] = clipL;
235  nodeBoxR.lo[axis] = clipR;
236  // recurse
237  if (nl > 0)
238  subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
239  else
240  stats.updateLeaf(depth + 1, 0);
241  if (nr > 0)
242  subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
243  else
244  stats.updateLeaf(depth + 1, 0);
245 }
float finf()
Definition: g3dmath.cpp:71
G3D::Vector3 lo
Definition: BoundingIntervalHierarchy.h:60
float fnan()
Definition: g3dmath.cpp:82
Definition: BoundingIntervalHierarchy.h:58
#define isnan
Definition: BoundingIntervalHierarchy.cpp:24
static uint32 floatToRawIntBits(float f)
Definition: BoundingIntervalHierarchy.h:36
T max(const T &x, const T &y)
Definition: g3dmath.h:320
Definition: Vector3.h:58
T min(const T &x, const T &y)
Definition: g3dmath.h:305
G3D::Vector3 hi
Definition: BoundingIntervalHierarchy.h:60
bool left(const int *a, const int *b, const int *c)
Definition: RecastContour.cpp:487
void createNode(std::vector< uint32 > &tempTree, int nodeIndex, uint32 left, uint32 right) const
Definition: BoundingIntervalHierarchy.h:390
void subdivide(int left, int right, std::vector< uint32 > &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)
Definition: BoundingIntervalHierarchy.cpp:41
#define MAX_STACK_SIZE
Definition: BoundingIntervalHierarchy.h:34
bool fuzzyEq(double a, double b)
Definition: g3dmath.h:857

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool BIH::writeToFile ( FILE *  wf) const
248 {
249  uint32 treeSize = tree.size();
250  uint32 check=0, count;
251  check += fwrite(&bounds.low(), sizeof(float), 3, wf);
252  check += fwrite(&bounds.high(), sizeof(float), 3, wf);
253  check += fwrite(&treeSize, sizeof(uint32), 1, wf);
254  check += fwrite(&tree[0], sizeof(uint32), treeSize, wf);
255  count = objects.size();
256  check += fwrite(&count, sizeof(uint32), 1, wf);
257  check += fwrite(&objects[0], sizeof(uint32), count, wf);
258  return check == (3 + 3 + 2 + treeSize + count);
259 }
const Point3 & low() const
Definition: AABox.h:136
std::vector< uint32 > objects
Definition: BoundingIntervalHierarchy.h:342
G3D::AABox bounds
Definition: BoundingIntervalHierarchy.h:343
uint32_t uint32
Definition: Define.h:150
T check(T value)
Definition: format.h:305
const Point3 & high() const
Definition: AABox.h:141
std::vector< uint32 > tree
Definition: BoundingIntervalHierarchy.h:341

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

G3D::AABox BIH::bounds
protected
std::vector<uint32> BIH::objects
protected
std::vector<uint32> BIH::tree
protected

The documentation for this class was generated from the following files: