source: GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktb8b.cpp @ 2582

Revision 2582, 12.8 KB checked in by bittner, 17 years ago (diff)

Havran Ray Caster compiles and links, but still does not work

Line 
1// ===================================================================
2// $Id: $
3//
4// ktb.cpp
5//
6//     KDB - trees for ray tracing, special version for SCCG 2006
7//
8// REPLACEMENT_STRING
9//
10// Copyright by Vlastimil Havran, 2007 - email to "vhavran AT seznam.cz"
11// Initial coding by Vlasta Havran, 1998-2001.
12
13// GOLEM library
14#include "ktb8b.h"
15#include "Environment.h"
16
17// standard headers
18#include <algorithm>
19
20namespace GtpVisibilityPreprocessor {
21
22// default constructor
23CKTB8BNodeIterator::CKTB8BNodeIterator()
24{
25
26}
27 
28//-------------------------------------------------------------
29// class CKTB8BNodeIterator .. implementation
30
31// test all objects in the leaf for intersection with ray
32// and returns the pointer to closest one if exists
33// and passing through parameter returns in tmax
34int
35CKTB8BNodeIterator::TestFullLeaf(const SimpleRay &ray, const SKTBNode *p)
36{
37  ObjectContainer *list = GetObjList(p); 
38  if (!list) // no object
39    return 0;
40  ObjectContainer::iterator sc_end = list->end();
41
42  int intersected = 0;
43  // iterate the whole list and find out the nearest intersection
44  for (ObjectContainer::iterator sc = list->begin(); sc != sc_end; sc++) {
45    // if the intersection realy lies in the node       
46    if ((*sc)->CastSimpleRay(ray)) {
47      intersected = 1;
48    }
49  } // for all objects
50
51  return intersected;
52}
53
54int
55CKTB8BNodeIterator::TestFullLeaf(const SimpleRay &ray, const SKTBNode *p,
56                                 int indexRay)
57{
58  ObjectContainer *list = GetObjList(p); 
59  if (!list) // no object
60    return 0;
61  ObjectContainer::iterator sc_end = list->end();
62
63  float tclosest = Limits::Infinity;
64  int intersected = 0;
65  // indexRay += rayOffset;
66  // iterate the whole list and find out the nearest intersection
67  for (ObjectContainer::iterator sc = list->begin(); sc != sc_end; sc++) {
68    // if the intersection realy lies in the node       
69    if ((*sc)->CastSimpleRay(ray, indexRay)) {
70      // update tclosest !!!!!!!!!!!!!!!!!!!!!!!!!!!!
71      // tclosest = ray.
72      intersected = 1;
73    }
74  } // for all objects
75
76  return intersected;
77}
78
79 
80// test all objects in the leaf for intersection with ray
81// and find any if exist .. returns this object, otherwise 0
82int
83CKTB8BNodeIterator::HitAnyObj(const SimpleRay &ray, const SKTBNode *p)
84{
85  ObjectContainer *list = GetObjList(p); 
86  if (!list) // no object
87    return 0;
88  ObjectContainer::iterator sc_end = list->end();
89
90  float tclosest = Limits::Infinity;
91  int intersected = 0;
92  // iterate the whole list and find out the nearest intersection
93  for (ObjectContainer::iterator sc = list->begin(); sc != sc_end; sc++) {
94    Intersectable *is = (*sc);
95    // if the intersection realy lies in the node       
96    if (is->CastSimpleRay(ray)) {
97      // update tclosest !!!!!!!!!!!!!!!!!!!!!!!!!!!!
98      // tclosest = ray.
99      return 1; // intersected
100    }
101  } // for all objects
102
103  return 0;
104}
105
106const CKTB8BNodeAbstract::SKTBNode*
107CKTB8BNodeIterator::Locate(const Vector3 & /*position*/)
108{
109  cerr << "Locate vector - Not yet implemented" << endl;
110  return (CKTB8BNodeAbstract::SKTBNode*)0;
111}
112
113
114// ---------------------------------------------------------------------
115// Allocator for KTB tree
116
117// forget the content that is created by previous kd-tree construction
118// or just init for the first use.
119void
120CKTB8BAllocMan::InitForConstructor()
121{
122#ifdef _KTB_CONSTR_STATS
123  _stats_interiorCount = 0;
124  _stats_bboxCount = 0;
125  _stats_leafNodeCount = 0;
126  _stats_emptyLeftNodeCount = 0;
127  // Aggregate statistics
128  _sumLeafDepth = 0;
129  _sumFullLeafDepth = 0;
130  // The count of object references in leaves
131  _sumObjectRefCount = 0;
132  // The maximum number of object references in a leaf
133  _maxObjectRefInLeaf = 0;
134  // surface areas
135  _sumSurfaceAreaLeaves = 0.f;
136  _sumSurfaceAreaMULcntLeaves = 0.f;
137  _sumSurfaceAreaInteriorNodes = 0.f;
138#endif
139 
140  // This is the statistics
141  _currDepth = 0;
142  _maxDepth = -1;
143  InitPars();
144}
145
146// init the stack of auxiliary variables from min to max
147void
148CKTB8BAllocMan::InitAux(int /*min*/, int /*maxD*/, int maxItemsAtOnce)
149{
150  // The size of one entry
151  int sizeEntryV = sizeof(SKTBNode);
152  // The number of entries to be allocated at once in a block
153  // (=size of the block)
154  int numEntriesInBlock = 1024;
155  // the allignment
156  int allignEntrySizeV = sizeof(SKTBNode);
157  int allignBlockSizeV = 128;
158
159  // Create an allocator in DFS order
160  alloc2 = new CAllocContinuous(sizeEntryV, numEntriesInBlock,
161                                maxItemsAtOnce,
162                                allignEntrySizeV,
163                                allignBlockSizeV);
164  assert(alloc2);
165  // the first allocation is enabled by this command
166  alloc2->AllocNewBlock();
167  return;
168}
169
170// Read some basic parameters from the environment file
171void
172CKTB8BAllocMan::InitPars()
173{
174  Environment::GetSingleton()->GetIntValue("BSP.maxListLength",
175                                           maxListLength);
176  Environment::GetSingleton()->GetIntValue("BSP.maxDepthAllowed",
177                                           maxDepthAllowed);
178}
179
180void
181CKTB8BAllocMan::PostBuild()
182{
183  // Here it can be some postprocessing of the tree, such as branches
184  // collapsing for the same content of leaves etc.
185}
186
187void
188CKTB8BAllocMan::Remove()
189{
190  // Release the all memory by blocks, so all the interior nodes
191  // and leaves representations. This should be fast.
192  alloc2->ReleaseMemory();
193}
194
195
196// Create the representation of the interior node
197SKTBNodeT*
198CKTB8BAllocMan::AllocInteriorNode(int axis, float position,
199                                  int cntLeft, int cntRight)
200{
201#ifdef _DEBUG
202  nodeToLink = 0;
203#endif
204
205#ifdef _KTB_CONSTR_STATS
206  _stats_interiorCount++;
207#endif
208 
209  // Just to satisfy the compiler
210  cntLeft = cntLeft;
211  cntRight = cntRight;
212 
213  // Alloc a single node
214  SKTBNodeT *n = (SKTBNodeT*)(alloc2->New(1));
215  nodeToLink = n;
216  if (n == 0) {
217    // we have to insert a special node that links only
218    nodeToLink = (SKTBNodeT*)alloc2->NewLastEntry(1);
219    assert(nodeToLink);
220    nodeToLink->offset = CKTBAxes::EE_Link;
221    n = (SKTBNodeT*)(alloc2->NewEntryInNewBlock(1));
222    // This is the link
223    nodeToLink->linkedNode = n;   
224  } // if n
225
226  assert(n);
227  assert(nodeToLink);
228
229  // Set the interior node
230  assert((axis >=0) && (axis < 3));
231  n->offset = axis;
232  n->splitPlane = position;
233
234#ifdef _DEBUG_ALLOCATION 
235  cout << "AllocInterior node adr = " << (void*)n << endl;
236#endif // _DEBUG_ALLOCATION
237  // Return the setupped node, but do not forget to
238  // use in the parent node to use nodeToLink !!!!
239  return n;
240}
241
242// Create the representation of the interior node with box
243SKTBNodeT*
244CKTB8BAllocMan::AllocInteriorNodeWithBox(int axis, float position,
245                                         int cntLeft, int cntRight,
246                                         const SBBox &tsbox, SKTBNodeT* prevMinBoxNode,
247                                         int depthStore)
248{
249#ifdef _DEBUG
250  nodeToLink = 0;
251  if ( (position < tsbox.Min(axis)) ||
252    (position > tsbox.Max(axis)) ) {
253    cerr << "Something wrong with the tree axis = " << axis;
254    cerr << " Min(axis) = " << tsbox.Min(axis)
255          << " splitValue = " << position
256          << " Max(axis) = " << tsbox.Max(axis) << endl;
257    abort();;
258  } 
259#endif
260
261#ifdef _KTB_CONSTR_STATS
262  _stats_interiorCount++;
263  _stats_minbboxCount++;
264#endif
265 
266  // Just to satisfy the compiler
267  cntLeft = cntLeft;
268  cntRight = cntRight;
269
270#ifdef _SHORT_FORM_MINBOX 
271  // Alloc two nodes = 2*8 Bytes = 16 Bytes
272  SKTBNodeT *n = (SKTBNodeT*)(alloc2->New(2));
273  nodeToLink = n;
274  if (n == 0) {
275    // we have to insert a special node that links only
276    nodeToLink = (SKTBNodeT*)alloc2->NewLastEntry(1);
277    assert(nodeToLink);
278    nodeToLink->offset = CKTBAxes::EE_Link;
279    n = (SKTBNodeT*)(alloc2->NewEntryInNewBlock(2));
280    // This is the link
281    nodeToLink->linkedNode = n;   
282  } // if n
283
284  assert(n);
285  assert(nodeToLink);
286
287  // Set the interior node
288  assert((axis >=0) && (axis < 3));
289  n->offset = (int)CKTBAxes::EE_X_axisBox + axis;
290  n->splitPlane = position;
291
292  // Set the box
293  // and the address to the parent min box node
294  (n+1)->parentBoxNode = prevMinBoxNode;
295
296  // Here we simply allocate the box for the address
297  SBBox *badr = new SBBox;
298  assert(badr);
299  (n+1)->pointer = (unsigned char *)badr;
300
301  // Note that we cannot store the depth here !
302  depthStore = depthStore; // to satisfy the compiler
303#else // _SHORT_FORM_MINBOX
304  // Alloc two single nodes (16 Bytes) + box (24 Bytes) = 40 Bytes
305  SKTBNodeT *n = (SKTBNodeT*)(alloc2->New(5));
306  nodeToLink = n;
307  if (n == 0) {
308    // we have to insert a special node that links only
309    nodeToLink = (SKTBNodeT*)alloc2->NewLastEntry(1);
310    assert(nodeToLink);
311    nodeToLink->offset = CKTBAxes::EE_Link;
312    n = (SKTBNodeT*)(alloc2->NewEntryInNewBlock(5));
313    // This is the link
314    nodeToLink->linkedNode = n;   
315  } // if n
316
317  assert(n);
318  assert(nodeToLink);
319
320  // Set the interior node
321  assert((axis >=0) && (axis < 3));
322  n->offset = (int)CKTBAxes::EE_X_axisBox + axis;
323  n->splitPlane = position;
324
325  // Set the box itself
326  // and the address to the parent min box node
327  (n+1)->parentBoxNode = prevMinBoxNode;
328  // here we set the depth of the node (suited for debugging)
329  (n+1)->depth = depthStore;
330 
331  // This is not very nice, we use the address in already allocated
332  //item, but this saves memory of 4 Bytes, which allows allingment to 32 Bytes
333  //for this entry
334  SBBox *badr = (SBBox*)(((char*)n)+16); 
335#endif // _SHORT_FORM_MINBOX
336
337  // and copy the box content from the function parameters
338  *(badr) = tsbox;
339 
340#ifdef _DEBUG_ALLOCATION 
341  cout << "AllocInterior node adr = " << (void*)n << endl;
342#endif // _DEBUG_ALLOCATION
343  // Return the setupped node, but do not forget to
344  // use in the parent node to use nodeToLink !!!!
345  return n;
346}
347 
348// Set the pointers to children for the interior node
349void
350CKTB8BAllocMan::SetInteriorNodeLinks(SKTBNodeT *node,
351                                     SKTBNodeT *leftChild,
352                                     SKTBNodeT *rightChild)
353{
354  leftChild = leftChild; // to satisfy the compiler
355
356  // Check on correctness of DFS order
357  assert( (node+1 == leftChild) || (node+2 == leftChild) || (node+5 == leftChild) );
358
359#ifdef _DEBUG_ALLOCATION 
360  cout << "SetInteriorNode adr = " << (void*)node
361       << " right = " << (void*)rightChild << endl;
362#endif
363 
364#ifdef _DEBUG
365  // Check if last 3 bits of the address are really zero
366  // and hence they can be used for different purposes
367  if ( ( ((unsigned int)rightChild) & CKTBAxes::EE_Mask) != 0) {
368    // The bug in implementation of DFS order allocator or so
369    // This should never happen.
370    cerr << "cerr error, node is not 8Bytes aligned, it cannot be linked in DFS" << endl;
371    abort();;
372  }
373#endif
374
375  // Bitwise OR should work correctly
376  assert(node->offset <= CKTBAxes::EE_Z_axisBox);
377  //assert(node->offset >= 0);
378  //(unsigned long)node->offset |= (unsigned long)rightChild;
379  node->offset = node->offset | (unsigned int)rightChild;
380#ifdef _DEBUG
381  // Compute right child
382  SKTBNodeT *p = GetRight(node);
383  if (p != rightChild) {
384    cerr << "Problem with implementation of setting right child" << endl;
385    abort();;
386  }
387#endif
388
389  return;
390}
391
392// Create the representation of the leaf. Note that possibly there
393// can be special cases, such as 0, 1, 2, or 3 objects, or in general
394// N objects.
395SKTBNodeT*
396CKTB8BAllocMan::AllocLeaf(int cntObjects)
397{
398#ifdef _DEBUG
399  nodeToLink = 0;
400#endif
401
402#ifdef _KTB_CONSTR_STATS
403  _stats_leafNodeCount++;
404  _sumLeafDepth += _currDepth;
405  if (cntObjects) {
406    _sumFullLeafDepth += _currDepth;
407    // The count of object references in leaves
408    _sumObjectRefCount += cntObjects;
409    // The maximum number of object references in a leaf
410    if (cntObjects > _maxObjectRefInLeaf)
411      _maxObjectRefInLeaf = cntObjects;
412  }
413  else
414    _stats_emptyLeftNodeCount++;
415#endif
416 
417  // Alloc a single node
418  SKTBNodeT *n = (SKTBNodeT*)(alloc2->New(1));
419  nodeToLink = n;
420  if (n == 0) {
421    // we have to insert a special node that links only
422    n = nodeToLink = (SKTBNodeT*)alloc2->NewLastEntry(1);
423    assert(nodeToLink);
424    // Allocate a new block for the next allocation
425    alloc2->AllocNewBlock();
426  } // if n
427
428  n->offset = CKTBAxes::EE_Leaf;
429  n->objlist = 0;
430
431#ifdef _DEBUG_ALLOCATION 
432  cout << "AllocLeaf adr = " << (void*)n << endl;
433#endif
434 
435  // Return the node
436  return n;
437}
438
439// if active node is empty, then is replaced by full leaf with
440// the object list. In success returns 0, for failure returns 1.
441// The object list is used as it is .. it is not copied !!
442int
443CKTB8BAllocMan::SetFullLeaf(SKTBNodeT *node, const ObjectContainer *objlist)
444{
445  assert(node);
446  assert(IsLeaf_(node));
447
448#ifdef _DEBUG_ALLOCATION 
449  cout << "SetFullLeaf adr = " << (void*)node << endl;
450#endif
451 
452  if ( (objlist == NULL) ||
453       (objlist->size() == 0) ) {
454    node->objlist = 0;
455  }
456  else {
457    // Set the pointer to the list of objects
458    node->objlist = (ObjectContainer *) objlist;
459  }
460
461  return 0;
462}
463
464}
Note: See TracBrowser for help on using the repository browser.