source: GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktbtrav.h @ 2582

Revision 2582, 14.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// ktbtrav.h
5//      Traversal class for CKTB structures
6//
7// Class: CKTBTraversal
8//
9// REPLACEMENT_STRING
10//
11// Copyright by Vlastimil Havran, 2007 - email to "vhavran AT seznam.cz"
12// Initial coding by Vlasta Havran, 2006
13
14#ifndef __KTBTRAV_H__
15#define __KTBTRAV_H__
16
17// GOLEM headers
18#include "configh.h"
19#include "ktbconf.h"
20#include "ktb.h"
21#include "ktb8b.h"
22#include "raypack.h"
23// From the framework of Jiri Bittner et al. GTP
24#include "SimpleRay.h"
25
26
27#ifdef __SSE__
28#include <xmmintrin.h>
29#endif
30
31namespace GtpVisibilityPreprocessor {
32
33class RayPacket2x2;
34 
35//#define TRV000
36//#define TRV001
37//#define TRV002
38//#define TRV003
39//#define TRV004
40//#define TRV005
41//#define TRV006
42//#define TRV007
43#define TRV00F
44
45// forward declarations
46class SKTBNode;
47
48// This is debugging of traversal for a new traversal variant
49//#define _DEBUGKTB
50
51// This is debugging of traversal storing depth at the stack
52//#define _KTBEXTSTACK
53 
54// VERSION1 - the version, where we prepare a sequence of boxes
55//            which never overlap (file ktbmtrav.cpp)
56// VERSION2 - the sequence of boxes can overlap and we solve which
57//            boxes to traverse online during the traversal (file ktbm2trv.cpp)
58// VERSION3 - the stackless algorithm based on interval tracking
59//            keeping entry and exit point (file ktbm3trv.cpp)
60// VERSION4 - the stack-based algorithm rewritten from ktbm3trv.cpp
61//            by adding the stack (file ktbm4trv.cpp)
62// VERSION5 - another stackless algorithm based on a single point and
63//            virtual box tracking (file ktbm5trv.cpp)
64// VERSION6 - simple sequential traversal algorithm without stack (TA_A)
65//            published originally already in year 1985 by Kaplan
66//            (file ktbm6trv.cpp)
67
68// //#define _KTBTRAV_VERSION0
69//#define _KTBTRAV_VERSION1
70//#define _KTBTRAV_VERSION2
71//#define _KTBTRAV_VERSION3
72//#define _KTBTRAV_VERSION4
73#define _KTBTRAV_VERSION5
74//#define _KTBTRAV_VERSION6
75
76// We cull away the nodes to be visited if they would be the same
77// as the next box in the sequence of nodes with boxes
78#define _CULL_IN_INTERIOR_NODES
79
80// If this macro is defined, then we extract the sequence of boxes to
81// the output buffer when visiting a leaf. When this macro is disabled,
82// we make test upon visiting a box node, which can be faster, as the
83// number of box nodes is smaller than the number of leaves visited
84#define EXTRACTSEQENENCEINLEAVES
85
86// This is special development debug
87#define _DEBUG_SAMELEAF
88
89// Pseudo visualization
90#define VIS_TRAVERSEDNODED
91
92// If this macro is defined, we use increment of
93// the signed distance to avoid visiting the same node again
94// by multiplication and addition
95// Otherwise (macro commented) we use a special function for that
96// based on IEEE754 representation of floating-point
97//#define INCTMIN
98
99// These are constants to increase signed distance when exiting leaf
100#define onePlusEps 1.000008f
101#define epsAdd 0.000008f
102
103//#define onePlusEps 1.00005f
104//#define epsAdd 0.0001f
105//const float onePlusEps = 1.0001f;
106//const float epsAdd = 0.0001f;
107//const float onePlusEps = 1.00008f;
108//const float epsAdd = 0.00005f;       
109//const float onePlusEps = 1.000008f;
110//const float epsAdd = 0.000008f;             
111//const float onePlusEps = 1.0000008f;
112//const float epsAdd = 0.00001f;       
113
114// Here are the macros to avoid traversing the same leaf again
115#define _DEBUGULPS
116#define INCULPS 1
117
118#ifndef _KTB8Bytes
119// 12 Bytes representation
120#undef  SKTBNodeT
121#define SKTBNodeT CKTBNodeAbstract::SKTBNode
122#else
123// 8 Bytes representation
124#undef  SKTBNodeT
125#define SKTBNodeT CKTB8BNodeAbstract::SKTBNode
126#endif
127
128// 12 Bytes representation
129class CKTBNodeIteratorPredecessor:
130#ifndef _KTB8Bytes
131  public CKTBNodeIterator
132#else
133  public CKTB8BNodeIterator
134#endif
135{
136public:
137  virtual int FindNearestI(const SimpleRay &ray) { return 0; }
138  void SetOffset(int offset) { rayOffset = offset; }
139  virtual int FindNearestI_16oneDir(SimpleRayContainer &rays) { return 0; }
140  virtual int FindNearestI_16oneDir(SimpleRayContainer &rays, int offset)
141  { return 0; }
142  virtual int FindNearestI_16twoDir(SimpleRayContainer &rays) { return 0; }
143
144  // the number of nested kd-trees at most
145  enum { MAX_NESTING = 2};
146 
147  // The same operations for packets of rays, if implemented by
148  // a particular ASDS, otherwise it is emulated by decomposition
149  // of a packet to individual rays and traced individually.
150  virtual void FindNearestI(RayPacket2x2 &raypack) { }
151  virtual void FindNearestI(RayPacket2x2 &raypack, Vector3 &boxmin, Vector3 &boxmax) { }
152
153  virtual void PrintStatsTR(ostream &) { }
154  virtual void DynamicStatsReset() { }
155};
156
157// ---------------------------------------------------------------------------
158// Note on the usage:
159// Allow only one macro from the tree: _KTBTRAV_JANSEN86, _KTBTRAV_JGT98
160// and  _KTBTRAV_OPTIMIZED86
161
162// macro for using algorithm for traversal CKTB trees as stated by Jansen86,
163// Arvo88, and Kelving/Sung92 in Gems III.
164//#define _KTBTRAV_JANSEN86
165
166// Faster and robust algorithm is used, published in JGT 98
167// by Havran+Bittner+Kopal+Zara. It is fastest at the moment, measured in year 2005/6
168#define _KTBTRAV_JGT98
169
170// Modified algorithm from Jansen86 (Arvo88, Kelving/Sung92), optimized for
171// modern processors.
172//#define _KTBTRAV_OPTIMIZED86
173
174// ------------------------------------------------------------
175#undef _COMPUTE_INVERTED_DIR_KTB
176// This avoids the division when computed signed distance by precomputation
177// of the inverse of ray.dir for all three components
178#define _COMPUTE_INVERTED_DIR_KTB
179
180// Check if the only traversal algorithm was used.
181#ifdef _KTBTRAV_JANSEN86
182#if (defined(_KTBTRAV_JGT98) || defined(_KTBTRAV_OPTIMIZED86))
183#error "Allow only one of macros  _KTBTRAV_OPTIMIZED86, _KTBTRAV_JGT98, _KTBTRAV_OPTIMIZED86"
184#endif
185#endif
186//-------------------------
187#ifdef _KTBTRAV_JGT98
188#if (defined(_KTBTRAV_JANSEN86) || defined(_KTBTRAV_OPTIMIZED86))
189#error "Allow only one of macros  _KTBTRAV_OPTIMIZED86, _KTBTRAV_JGT98, _KTBTRAV_OPTIMIZED86"
190#endif
191#endif
192//-------------------------
193#ifdef _KTBTRAV_OPTIMIZED86
194#if (defined(_KTBTRAV_JANSEN86) || defined(_KTBTRAV_JGT98))
195#error "Allow only one of macros  _KTBTRAV_OPTIMIZED86, _KTBTRAV_JGT98, _KTBTRAV_OPTIMIZED86"
196#endif
197#endif
198
199// -------------------------------------------------------------------
200// robust statistically optimized algorithm for CKTB ray-traversal
201// version 025
202// This version appeared in JGT(Journal of Graphics Tools, Vol. 2, No.4,
203// 1997, pp.15-23. with title:
204// "FAST Robust KD-Tree Traversal Algorithm for Ray Tracing"
205
206class CKTBTraversal:
207  public CKTBNodeIteratorPredecessor
208{
209public:
210  // maximal height of the CKTB tree for nesting
211  enum { MAX_TRAVERSAL_HEIGHT = (MAX_HEIGHT * MAX_NESTING) };
212
213protected:
214  // the stack element for CKTB tree traversal
215  struct SStackElem {
216    SKTBNodeT *nodep;  // pointer to the node
217    // Vector3 point;  // entry/exit point
218    float    x,y,z;  // entry/exit point
219    float    t;      // signed distance of the point
220    SStackElem *prev;
221    SKTBNodeT *lastBoxNode; // here is the alingment
222#ifdef _KTBEXTSTACK
223    int       dummy; // storing the depth here
224#endif   
225  };
226
227  // the stack element for CKTB tree traversal
228  struct SStackElem2 {
229    SKTBNodeT *nodep;  // pointer to the node
230    int      dummy;
231    float    tmin;      // entry signed distance
232    float    tmax;      // exit signed distance
233  };
234  struct SStackElem3 {
235    SKTBNodeT *nodep;  // pointer to the node
236    float    tmax;     // exit signed distance
237  };
238
239  struct SStackElem4 {
240    SKTBNodeT *nodep;  // pointer to the node
241    int      mask;     // mask
242    int      pad[2];   // alignment to 16 bytes
243    union { float tmin4[4];
244#ifdef __SSE__
245      __m128 tmin_4;
246#endif
247    };
248    union { float tmax4[4];
249#ifdef __SSE__
250      __m128 tmax_4;
251#endif
252    };
253  };
254
255 
256  // the stack of elems - declared as static not to allocate it every time
257  static struct SStackElem stack[MAX_TRAVERSAL_HEIGHT];
258  static struct SStackElem2 stack2[MAX_TRAVERSAL_HEIGHT];
259  static struct SStackElem3 stack3[MAX_TRAVERSAL_HEIGHT];
260  static struct SStackElem4 stack4[MAX_TRAVERSAL_HEIGHT];
261
262#define cntMaxRays 16
263  static struct CKTBTraversal::SStackElem3 stackA[cntMaxRays * MAX_HEIGHT];
264
265  // the axis aligned box for CKTB tree space
266  AxisAlignedBox3 bbox;
267  // root node of the CKTB tree
268  SKTBNodeT *root;
269  // the small epsilon that is computed from the size of the whole box
270  float epsilon;
271
272  // sets the stack pointers that are used for the traversal.
273  void GetStackPointers(struct SStackElem *&entryPointer,
274                        struct SStackElem *&exitPointer);
275  void GetStartStackPointer(struct SStackElem *&exitPointer);
276 
277  // this function should be called when exiting from the traversal function
278  // to keep the track on the traversalDepth (of kd-trees, when they are nested).
279  void RestoreStackPointers();
280
281  // the depth of traversal when kd-trees are nested. The global (the highest
282  // level) kd-tree is at the depth 0.
283  static int traversalDepth;
284
285#ifdef __TRAVERSAL_STATISTICS
286  long unsigned int _allNodesTraversed;
287  long unsigned int _fullLeavesTraversed;
288  long unsigned int _emptyLeavesTraversed;
289#endif
290
291public:
292  // default constructor
293  CKTBTraversal();
294
295  // destructor
296  virtual ~CKTBTraversal() {}
297
298  // sets the bbox and the root node for this traversal class
299  virtual void Setup(const AxisAlignedBox3 &box, SKTBNodeT *Nroot)
300    { bbox = box; root = Nroot; epsilon=(float)(1e-6*Magnitude(bbox.Size())); }
301
302  // potentionally, sets the list of unbounded objects if required
303  virtual void Setup2(CObjectList *) { // int count = unboundeds->ListCount();
304  }
305
306  virtual int FindNearestI(const SimpleRay &ray);
307  virtual int FindNearestI(const SimpleRay &ray, const AxisAlignedBox3 &localbox);
308
309  virtual int FindNearestI_16oneDir(SimpleRayContainer &rays) {
310    return FindNearestI_16oneDir(rays, 0);
311  }
312  // $$JB correction
313  virtual int FindNearestI_16oneDir(SimpleRayContainer &rays, int offset) {
314        return 0;
315  }
316  int PrecomputeData(SimpleRayContainer &rays);
317  void ReverseRay(const int indexA);
318  virtual int FindNearestI_16twoDir(SimpleRayContainer &rays);
319
320#ifdef __SSE__
321  // The same operations for packets of rays, if implemented by
322  // a particular ASDS, otherwise it is emulated by decomposition
323  // of a packet to individual rays and traced individually.
324  virtual void FindNearestI(RayPacket2x2 &raypack);
325  virtual void FindNearestI(RayPacket2x2 &raypack, Vector3 &boxmin, Vector3 &boxmax);
326#endif // __SSE__
327
328  virtual void PrintStatsTR(ostream &) { }
329
330  void AssignIDs(SKTBNodeT *node = NULL);
331
332  // this resets the nesting to start from the zero depth (root)
333  virtual void ResetTraversalDepth() { traversalDepth = 0;}
334
335  // Here we find the node (preferably minbox node) containing
336  // the point
337  virtual const SKTBNode* Locate(const Vector3 &position);
338};
339
340#if 0
341// The version taking into account min boxes sparsely distributed in
342// the kd-tree.
343class CKTBMinBoxesTraversal:
344  public CKTBNodeIteratorPredecessor
345{
346protected:
347  // the stack element for CKTB tree traversal
348  struct SStackElem {
349    SKTBNodeT *nodep;  // pointer to the node
350    // Vector3 point;  // entry/exit point
351    float    x,y,z;  // entry/exit point
352    float    t;      // signed distance of the point
353    SStackElem *prev;
354    SKTBNodeT *lastBoxNode; // here is the alingment
355//#ifdef _KTBEXTSTACK
356    int       dummy; // storing the depth here
357//#endif   
358  };
359
360  // maximal height of the CKTB tree for nesting
361  enum { MAX_TRAVERSAL_HEIGHT = (MAX_HEIGHT * MAX_NESTING) };
362 
363  // the stack of elems - declared as static not to allocate it every time
364  static struct SStackElem stack[MAX_TRAVERSAL_HEIGHT];
365
366  // the axis aligned box for CKTB tree space
367  AxisAlignedBox3 bbox;
368  // root node of the CKTB tree
369  SKTBNodeT *root;
370  // the small epsilon that is computed from the size of the whole box
371  float epsilon;
372  // size of the write buffer
373  int size1D;
374
375  // sets the stack pointers that are used for the traversal.
376  void GetStackPointers(struct SStackElem *&entryPointer,
377                        struct SStackElem *&exitPointer);
378  void GetStartStackPointer(struct SStackElem *&exitPointer);
379 
380  // this function should be called when exiting from the traversal function
381  // to keep the track on the traversalDepth (of kd-trees, when they are nested).
382  void RestoreStackPointers();
383
384  // the depth of traversal when kd-trees are nested. The global (the highest
385  // level) kd-tree is at the depth 0.
386  static int traversalDepth;
387
388#ifdef __TRAVERSAL_STATISTICS
389  long unsigned int _allNodesTraversed;
390  long unsigned int _fullLeavesTraversed;
391  long unsigned int _emptyLeavesTraversed;
392#endif
393 
394public:
395  // default constructor
396  CKTBMinBoxesTraversal(int size1Dv);
397
398  // destructor
399  virtual ~CKTBMinBoxesTraversal();
400
401  // sets the bbox and the root node for this traversal class
402  virtual void Setup(const AxisAlignedBox3 &box, SKTBNodeT *Nroot)
403    { bbox = box; root = Nroot; epsilon=(float)(1e-6*Magnitude(bbox.Size())); }
404
405  // potentionally, sets the list of unbounded objects if required
406  virtual void Setup2(CObjectList *) { // int count = unboundeds->ListCount();
407  }
408
409  virtual int FindNearestI(SimpleRay &ray);
410
411#ifdef __SSE__
412  // The same operations for packets of rays, if implemented by
413  // a particular ASDS, otherwise it is emulated by decomposition
414  // of a packet to individual rays and traced individually.
415  virtual void FindNearestI(RayPacket2x2 &raypack);
416  virtual void FindNearestI(RayPacket2x2 &raypack, Vector3 &boxmin, Vector3 &boxmax);
417#endif // __SSE__
418
419  virtual void DynamicStatsReset();
420 
421  virtual void PrintStatsTR(ostream &);
422
423  void AssignIDs(SKTBNodeT *node = NULL);
424
425  // this resets the nesting to start from the zero depth (root)
426  virtual void ResetTraversalDepth() { traversalDepth = 0;}
427
428#ifdef __TRAVERSAL_STATISTICS
429  unsigned long int statsMB_UpTraversals;
430  unsigned long int statsMB_DownTraversals;
431  unsigned long int statsMB_cntRays;
432  unsigned long int statsMB_cntRaysHB;
433  unsigned long int statsMB_UseTraversals;
434  unsigned long int statsMB_UseValidTraversals;
435  unsigned long int statsMB_allNodesTraversed;
436  unsigned long int statsMB_fullLeavesTraversed;
437  unsigned long int statsMB_emptyLeavesTraversed;
438  unsigned long int bugTheSameLeaf;
439  unsigned long int statsMB_writtenBoxes;
440  unsigned long int statsMB_readBoxes;
441  unsigned long int statsMB_cntWrittenBoxSequenceEvent;
442  unsigned long int statsMB_cntReadBoxSequenceEvent;
443#endif
444
445  // Here we find the node (preferably minbox node) containing
446  // the point
447  virtual const SKTBNode* Locate(const Vector3 &position);
448};
449#endif
450 
451} // namespace
452
453#endif // __KTBTRAV_H__
454
Note: See TracBrowser for help on using the repository browser.