source: GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktbftrav.cpp @ 2629

Revision 2629, 19.8 KB checked in by bittner, 16 years ago (diff)

commit after merge with vlastimil

Line 
1// ===================================================================
2// $Id: $
3//
4// ktbftrav.cpp
5//
6// class: CKTBTraversal
7//
8// REPLACEMENT_STRING
9//
10// Copyright by Vlastimil Havran, 2007 - email to "vhavran AT seznam.cz"
11// Initial coding by Vlasta Havran, February 2007 (copy from kdrtrav.cpp)
12
13// GOLEM headers
14#include "ktbconf.h"
15#include "ktbtrav.h"
16#include "Intersectable.h"
17
18namespace GtpVisibilityPreprocessor {
19
20#ifdef TRV00F
21
22// --------------------------------------------------------------
23// Shooting a single ray without SSE
24int
25CKTBTraversal::FindNearestI(const SimpleRay &ray)
26{
27#if 0
28  static int counter = 0;
29  counter++;
30  bool debug = false;
31  if (counter == 530) {
32    debug = true;
33    cout << "COUNTER = " << counter << endl;
34    cout << "DEBUG starts" << endl;   
35  }
36#endif
37 
38  // passing through parameters
39  float tmin, tmax;
40  SimpleRay::IntersectionRes[0].intersectable = 0;
41 
42  // test if the whole CKTB tree is missed by the input ray
43  if ( (!root) ||
44       (!bbox.ComputeMinMaxT(ray.mOrigin, ray.mDirection, &tmin, &tmax)) ||
45       (tmax < tmin) ||
46       (tmax <= 0.f) ) {
47    return 0; // no object can be intersected
48  }
49
50//#define _DEBUGKTB
51#ifdef _DEBUGKTB
52  int ib = 0;
53  int depth = 0;
54#endif
55 
56#ifdef __TRAVERSAL_STATISTICS
57  int allNodesTraversed = 0L;
58  int fullLeavesTraversed = 0L;
59  int emptyLeavesTraversed = 0L;
60#endif // __TRAVERSAL_STATISTICS
61
62  Vector3 invertedDir;
63  invertedDir.x = 1.0f / (ray.mDirection.x - 1e-25f);
64  invertedDir.y = 1.0f / (ray.mDirection.y - 1e-25f);
65  invertedDir.z = 1.0f / (ray.mDirection.z - 1e-25f);
66 
67  // start from the root node
68  if (tmin < 0.f)
69    tmin = 0.f;
70
71  int index = 1;
72  stack3[1].nodep = root;
73  stack3[1].tmax = tmax;
74  tmax = tmin;
75  SKTBNodeT * childNodes[2];
76  int RayDirs[3];
77  RayDirs[0] = ray.mDirection.x < 0.f ? 1 : 0;
78  RayDirs[1] = ray.mDirection.y < 0.f ? 1 : 0;
79  RayDirs[2] = ray.mDirection.z < 0.f ? 1 : 0;
80 
81  // we have to check the node
82  // current node is not the leaf, empty leaves are NULL pointers
83  while (index) {
84    register SKTBNodeT *currNode = stack3[index].nodep;
85    tmin = tmax;
86    tmax = stack3[index].tmax;
87#if 0
88    if (debug) {
89      cout << "node = " << (void*)currNode
90           << " tmin = " << tmin << " tmax = " << tmax
91           << endl;
92    }
93#endif
94
95CONTINUE_LINK:   
96
97    assert(tmin <= tmax);
98#ifdef __TRAVERSAL_STATISTICS
99    allNodesTraversed++;
100#endif // __TRAVERSAL_STATISTICS
101
102    register const int nodeType = GetNodeType(currNode);
103
104    // cout << " tmin = " << tmin << " tmax = " << tmax << " nodeType = " << (int)nodeType << endl;
105   
106    if (nodeType < CKTBAxes::EE_Leaf) {
107      float tval = (GetSplitValue(currNode) - ray.mOrigin[nodeType]);
108      tval *= invertedDir[nodeType];
109      SKTBNodeT *near, *far;
110      childNodes[0] = GetLeft(currNode);
111      childNodes[1] = GetRight(currNode);
112      int rayDir = RayDirs[nodeType];
113      near = childNodes[rayDir];
114      far = childNodes[rayDir ^ 0x1];
115     
116      stack3[index].nodep = far;
117      // stack3[index].tmax = tmax; // not necessary, this is already there !
118      // int c = tval < tmax ? 1 : 0;
119      index += tval < tmax ? 1 : 0;
120      stack3[index].nodep = near;
121      stack3[index].tmax = Min(tval, tmax);
122      tmax = tmin;
123      // int d = tval < tmin ? -1 : 0;
124      index += tval < tmin ? -1 : 0;
125    }
126    else {
127      if (nodeType == CKTBAxes::EE_Leaf) {
128        // test objects for intersection
129#ifdef _DEBUGKTB
130        cout << "Leaf " << endl;
131        depth++;
132#endif
133#ifdef _DEBUGKTB
134        DEBUG << "currNode = " << currNode << " entp.t = " << entp->t
135              << " extp.t = " << extp->t << endl;
136#endif
137        if (!IsEmptyLeaf_(currNode)) {
138#ifdef _DEBUGKTB
139          cout << "Full leaf at depth= " << depth << endl;
140#endif     
141
142#ifdef __TRAVERSAL_STATISTICS
143          fullLeavesTraversed++;
144#endif // __TRAVERSAL_STATISTICS
145          // test the objects in the full leaf against the ray
146         
147          SimpleRay::IntersectionRes[0].maxt =
148            stack3[index].tmax + Limits::Small;
149#if 0
150          // using subroutine
151          if (TestFullLeaf(ray, currNode))
152#else
153          // Avoiding function call by copying the code
154          const ObjectContainer * const list = GetObjList(currNode);
155          int intersected = 0;
156          // iterate the whole list and find out the nearest intersection
157          ObjectContainer::const_iterator sc_end = list->end();
158          for (ObjectContainer::const_iterator sc = list->begin(); sc != sc_end; sc++) {
159            // if the intersection realy lies in the node       
160            intersected += ((*sc)->CastSimpleRay(ray));
161          } // for all objects
162          if (intersected)
163#endif
164          {
165#ifdef _DEBUGKTB
166            cout << "Full leaf HIT " << endl;
167#endif 
168            SimpleRay::IntersectionRes[0].tdist =
169              SimpleRay::IntersectionRes[0].maxt;
170#ifdef __TRAVERSAL_STATISTICS
171            _allNodesTraversed += allNodesTraversed;
172            _fullLeavesTraversed += fullLeavesTraversed;
173            _emptyLeavesTraversed += emptyLeavesTraversed;
174#endif // __TRAVERSAL_STATISTICS
175           
176            // signed distance should be already set in TestFullLeaf
177            // the first object intersected was found   
178            return 1;
179          }
180        } // full leaf
181#ifdef __TRAVERSAL_STATISTICS
182        else {
183#ifdef _DEBUGKTB
184          cout << "Empty leaf at depth= " << depth << endl;
185#endif     
186          emptyLeavesTraversed++;
187        }
188#endif // __TRAVERSAL_STATISTICS
189
190#ifdef _DEBUGKTB
191        cout << "Pop the node" << endl;
192#endif     
193   
194        // pop farChild from the stack
195        // restore the current values
196        index--;
197        continue;
198      }
199      else {
200        assert(nodeType == CKTBAxes::EE_Link);
201#ifdef _DEBUGKTB
202        cout << "Link " << endl;
203#endif
204        // cout << "Link node was accessed" << endl;
205        currNode = GetLinkNode(currNode);
206        goto CONTINUE_LINK;
207      }
208    }
209  } // while current node is not the leaf
210
211#ifdef __TRAVERSAL_STATISTICS
212  _allNodesTraversed += allNodesTraversed;
213  _fullLeavesTraversed += fullLeavesTraversed;
214  _emptyLeavesTraversed += emptyLeavesTraversed;
215#endif // __TRAVERSAL_STATISTICS
216
217  // no objects found along the ray path
218  return 0;
219} // FindNearestI - single ray
220
221
222// Shooting a single ray without SSE with prespecified box of the scene, assuming
223// to be contained in the scene box!!!
224int
225CKTBTraversal::FindNearestI(const SimpleRay &oray, const AxisAlignedBox3 &localbox)
226{
227#if 0
228  static int counter = 0;
229  counter++;
230  bool debug = false;
231  if (counter == 530) {
232    debug = true;
233    cout << "COUNTER = " << counter << endl;
234    cout << "DEBUG starts" << endl;   
235  }
236#endif
237 
238  // passing through parameters
239  float tmin, tmax;
240  SimpleRay::IntersectionRes[0].intersectable = 0;
241  SimpleRay ray(oray.mOrigin, oray.mDirection, 0, 0.f, 0);
242 
243  // test if the whole CKTB tree is missed by the input ray
244  if ( (!root) ||
245       (!localbox.ComputeMinMaxT(ray.mOrigin, ray.mDirection, &tmin, &tmax)) ||
246       (tmax <= tmin) ||
247       (tmax <= 0.f) ) {
248    return 0; // no object can be intersected
249  }
250  float tminOffset = 0.f;
251
252//#define _DEBUGKTB
253#ifdef _DEBUGKTB
254  int ib = 0;
255  int depth = 0;
256#endif
257 
258#ifdef __TRAVERSAL_STATISTICS
259  int allNodesTraversed = 0L;
260  int fullLeavesTraversed = 0L;
261  int emptyLeavesTraversed = 0L;
262#endif // __TRAVERSAL_STATISTICS
263
264  Vector3 invertedDir;
265  invertedDir.x = 1.0f / (ray.mDirection.x - 1e-25f);
266  invertedDir.y = 1.0f / (ray.mDirection.y - 1e-25f);
267  invertedDir.z = 1.0f / (ray.mDirection.z - 1e-25f);
268 
269  // start from the root node
270  if (tmin < 0.f)
271    tmin = 0.f;
272  else {
273    // Here the origin of the ray is always zero - it starts
274    // at the box face!!
275    tminOffset = tmin;
276    tmin = 0.f;
277    tmax -= tminOffset;
278    ray.mOrigin += ray.mDirection * tminOffset;
279  }
280
281  int index = 1;
282  stack3[1].nodep = root;
283  stack3[1].tmax = tmax;
284  tmax = tmin;
285  SKTBNodeT * childNodes[2];
286  int RayDirs[3];
287  RayDirs[0] = ray.mDirection.x < 0.f ? 1 : 0;
288  RayDirs[1] = ray.mDirection.y < 0.f ? 1 : 0;
289  RayDirs[2] = ray.mDirection.z < 0.f ? 1 : 0;
290 
291  // we have to check the node
292  // current node is not the leaf, empty leaves are NULL pointers
293  while (index) {
294    register SKTBNodeT *currNode = stack3[index].nodep;
295    tmin = tmax;
296    tmax = stack3[index].tmax;
297#if 0
298    if (debug) {
299      cout << "node = " << (void*)currNode
300           << " tmin = " << tmin << " tmax = " << tmax
301           << endl;
302    }
303#endif
304       
305CONTINUE_LINK:
306    assert(tmin <= tmax);
307
308#ifdef __TRAVERSAL_STATISTICS
309    allNodesTraversed++;
310#endif // __TRAVERSAL_STATISTICS
311
312    register const int nodeType = GetNodeType(currNode);
313    if (nodeType < CKTBAxes::EE_Leaf) {
314      float tval = (GetSplitValue(currNode) - ray.mOrigin[nodeType]);
315      tval *= invertedDir[nodeType];
316      SKTBNodeT *near, *far;
317      childNodes[0] = GetLeft(currNode);
318      childNodes[1] = GetRight(currNode);
319      int rayDir = RayDirs[nodeType];
320      near = childNodes[rayDir];
321      far = childNodes[rayDir ^ 0x1];
322     
323      stack3[index].nodep = far;
324      // stack3[index].tmax = tmax; // not necessary, this is already there !
325      // int c = tval < tmax ? 1 : 0;
326      index += tval < tmax ? 1 : 0;
327      stack3[index].nodep = near;
328      stack3[index].tmax = Min(tval, tmax);
329      tmax = tmin;
330      // int d = tval < tmin ? -1 : 0;
331      index += tval < tmin ? -1 : 0;
332    }
333    else {
334      if (nodeType == CKTBAxes::EE_Leaf) {
335        // test objects for intersection
336#ifdef _DEBUGKTB
337        cout << "Leaf " << endl;
338        depth++;
339#endif
340#ifdef _DEBUGKTB
341        DEBUG << "currNode = " << currNode << " entp.t = " << entp->t
342              << " extp.t = " << extp->t << endl;
343#endif
344        if (!IsEmptyLeaf_(currNode)) {
345#ifdef _DEBUGKTB
346          cout << "Full leaf at depth= " << depth << endl;
347#endif     
348
349#ifdef __TRAVERSAL_STATISTICS
350          fullLeavesTraversed++;
351#endif // __TRAVERSAL_STATISTICS
352          // test the objects in the full leaf against the ray
353         
354          SimpleRay::IntersectionRes[0].maxt =
355            stack3[index].tmax + Limits::Small;
356#if 0
357          // using subroutine
358          if (TestFullLeaf(ray, currNode))
359#else
360          // Avoiding function call by copying the code
361          const ObjectContainer * const list = GetObjList(currNode);
362          int intersected = 0;
363          // iterate the whole list and find out the nearest intersection
364          ObjectContainer::const_iterator sc_end = list->end();
365          for (ObjectContainer::const_iterator sc = list->begin(); sc != sc_end; sc++) {
366            // if the intersection realy lies in the node       
367            intersected += ((*sc)->CastSimpleRay(ray));
368          } // for all objects
369          if (intersected)
370#endif
371          {
372#ifdef _DEBUGKTB
373            cout << "Full leaf HIT " << endl;
374#endif 
375            SimpleRay::IntersectionRes[0].tdist =
376              SimpleRay::IntersectionRes[0].maxt;
377             
378#ifdef __TRAVERSAL_STATISTICS
379            _allNodesTraversed += allNodesTraversed;
380            _fullLeavesTraversed += fullLeavesTraversed;
381            _emptyLeavesTraversed += emptyLeavesTraversed;
382#endif // __TRAVERSAL_STATISTICS
383
384            // We have to add the distance from the original ray origin
385            SimpleRay::IntersectionRes[0].tdist += tminOffset;
386            SimpleRay::IntersectionRes[0].maxt = SimpleRay::IntersectionRes[0].tdist;
387           
388            // signed distance should be already set in TestFullLeaf
389            // the first object intersected was found   
390            return 1;
391          }
392        } // full leaf
393#ifdef __TRAVERSAL_STATISTICS
394        else {
395#ifdef _DEBUGKTB
396          cout << "Empty leaf at depth= " << depth << endl;
397#endif     
398          emptyLeavesTraversed++;
399        }
400#endif // __TRAVERSAL_STATISTICS
401
402#ifdef _DEBUGKTB
403        cout << "Pop the node" << endl;
404#endif     
405   
406        // pop farChild from the stack
407        // restore the current values
408        index--;
409        continue;
410      }
411      else {
412        assert(nodeType == CKTBAxes::EE_Link);
413#ifdef _DEBUGKTB
414        cout << "Link " << endl;
415#endif
416        // cout << "Link node was accessed" << endl;
417        currNode = GetLinkNode(currNode);
418        goto CONTINUE_LINK;
419      }
420    }
421  } // while current node is not the leaf
422
423#ifdef __TRAVERSAL_STATISTICS
424  _allNodesTraversed += allNodesTraversed;
425  _fullLeavesTraversed += fullLeavesTraversed;
426  _emptyLeavesTraversed += emptyLeavesTraversed;
427#endif // __TRAVERSAL_STATISTICS
428
429  // no objects found along the ray path
430  return 0;
431} // FindNearestI - single ray
432
433
434// Reasonably fast - about 101,500 rays per second for single dir!
435// It allows fast switching context from one ray to the next ray so it is
436// virtually independent of memory latency !
437int
438CKTBTraversal::FindNearestI_16oneDirNoSSE(SimpleRayContainer &rays, int offset)
439{
440  // passing through parameters
441  int cntRays = 0;
442  if (!root)
443    return 0;
444
445  // The auxiliary variables to be precomputed
446  static float invertedDir[cntMaxRays * 4];
447  static float rayOrig[cntMaxRays * 4];
448  static int rayDirs[cntMaxRays * 4];
449  static int indexRay[cntMaxRays];
450  static int indexArray[cntMaxRays];
451  static int indexStack[cntMaxRays];
452  const int LOG2_MAX_HEIGHT = 5;
453  const int MAX_HEIGHT = 1 << LOG2_MAX_HEIGHT;
454  assert(MAX_HEIGHT == 32);
455  static struct SStackElem3 stackA[cntMaxRays * MAX_HEIGHT];
456  static float tmaxArray[cntMaxRays];
457  int cntHits = 0;
458 
459  float tmin, tmax;
460  for (int i = 0; i < cntMaxRays; i++) {
461    // Setting zero intersection as original result
462    SimpleRay::IntersectionRes[i+rayOffset].intersectable = 0;
463    // test if the whole CKTB tree is missed by the input ray
464    if ((!bbox.ComputeMinMaxT(rays[i+offset].mOrigin,
465                              rays[i+offset].mDirection,
466                              &tmin, &tmax)) ||
467        (tmax <= tmin) ||
468        (tmax <= 0.f) ) {
469    }
470    else {
471      int indexR = (cntRays << 2);
472      rayOrig[indexR + 0] = rays[i+offset].mOrigin.x;
473      rayOrig[indexR + 1] = rays[i+offset].mOrigin.y;
474      rayOrig[indexR + 2] = rays[i+offset].mOrigin.z;
475      //rayOrig[indexR + 3] = 0.f;
476      invertedDir[indexR + 0] = 1.0f / (rays[i+offset].mDirection.x - 1e-25f);
477      invertedDir[indexR + 1] = 1.0f / (rays[i+offset].mDirection.y - 1e-25f);
478      invertedDir[indexR + 2] = 1.0f / (rays[i+offset].mDirection.z - 1e-25f);
479      //invertedDir[indexR + 2] = 0.f;
480      rayDirs[indexR + 0] = rays[i+offset].mDirection.x < 0.f ? 1 : 0;
481      rayDirs[indexR + 1] = rays[i+offset].mDirection.y < 0.f ? 1 : 0;
482      rayDirs[indexR + 2] = rays[i+offset].mDirection.z < 0.f ? 1 : 0;
483      //rayDirs[indexR + 3] = 0;
484      indexRay[cntRays] = i; // the index to the ray
485      indexArray[cntRays] = cntRays; // the index to the array
486      int indexS = (cntRays << LOG2_MAX_HEIGHT) + 1;
487      indexStack[cntRays] = indexS; // the index in the stack
488      stackA[indexS].nodep = root; // we start from the root
489      stackA[indexS].tmax = tmax; // maximum distance
490      if (tmin < 0.f) tmin = 0.f;
491      tmaxArray[cntRays] = tmin;
492      cntRays++;
493    }
494  }
495
496//#define _DEBUGKTB
497#ifdef _DEBUGKTB
498  int ib = 0;
499  int depth = 0;
500#endif
501 
502#ifdef __TRAVERSAL_STATISTICS
503  int allNodesTraversed = 0L;
504  int fullLeavesTraversed = 0L;
505  int emptyLeavesTraversed = 0L;
506#endif // __TRAVERSAL_STATISTICS
507 
508  SKTBNodeT * childNodes[2];
509
510#define PREF_DEFAULT _MM_HINT_T0
511 
512  // we have to check the node
513  // current node is not the leaf, empty leaves are NULL pointers
514  while (cntRays) {
515    // we assume that all the nodes are interior nodes
516    for (int i = 0; i < cntRays; i++) {
517      // which indices to array should be used
518      int indexA = indexArray[i];
519      float tmin = tmaxArray[indexA];
520
521      // the stack indexing is here
522      int indexSA = indexStack[indexA];
523      SKTBNodeT *currNode = stackA[indexSA].nodep;
524     
525#if 0
526      if (debug) {
527        cout << "node = " << (void*)currNode
528             << " tmin = " << tmin << " tmax = " << tmax
529             << endl;
530      }
531#endif
532
533#if 0
534      if (tmin > tmax) {
535        cout << "PROBLEM tmin = " << tmin << " tmax = " << tmax;
536        cout << endl;
537      }
538#endif     
539   
540#ifdef __TRAVERSAL_STATISTICS
541      allNodesTraversed++;
542#endif // __TRAVERSAL_STATISTICS
543      const unsigned int nodeType = (GetNodeType(currNode)) & 0x7;
544      if (nodeType < CKTBAxes::EE_Leaf) {
545        int indexRayOD = (indexA << 2) + nodeType;
546        float tval = (GetSplitValue(currNode) - rayOrig[indexRayOD])
547          * invertedDir[indexRayOD];
548        SKTBNodeT *near, *far;
549        childNodes[0] = GetLeft(currNode);
550        childNodes[1] = GetRight(currNode);
551        int rayDir = rayDirs[indexRayOD];
552        near = childNodes[rayDir];
553        far = childNodes[rayDir ^ 0x1];
554       
555        stackA[indexSA].nodep = far; // store far node
556        //stackA[indexSA].tmax = tmax; // with correct dist - the same as before
557        float tmax = tmaxArray[indexA] = stackA[indexSA].tmax;
558        int c = tval < tmax ? 1 : 0;
559        indexSA += c;
560        stackA[indexSA].nodep = near; // store near node
561        stackA[indexSA].tmax = Min(tval, tmax); // with correct dist
562        int d = tval < tmin ? 1 : 0;
563        indexSA -= d;
564        // This is prefetching - so the next time we have it
565        // in the cache !
566        GPREFETCH(stackA[indexSA].nodep, PREF_DEFAULT);
567        // store tmax and index to the stack
568        indexStack[indexA] = indexSA;
569        tmaxArray[indexA] = tmin;       
570      }
571      else {
572        if (nodeType == CKTBAxes::EE_Leaf) {
573          // test objects for intersection
574#ifdef _DEBUGKTB
575          cout << "Leaf " << endl;
576          depth++;
577#endif
578#ifdef _DEBUGKTB
579          DEBUG << "currNode = " << currNode << " entp.t = " << entp->t
580                << " extp.t = " << extp->t << endl;
581#endif
582          float tmax = tmaxArray[indexA] = stackA[indexSA].tmax;
583          if (!IsEmptyLeaf_(currNode)) {
584#ifdef _DEBUGKTB
585            cout << "Full leaf at depth= " << depth << endl;
586#endif     
587
588#ifdef __TRAVERSAL_STATISTICS
589            fullLeavesTraversed++;
590#endif // __TRAVERSAL_STATISTICS
591          // test the objects in the full leaf against the ray
592         
593            // which ray is processed
594            int indexR = indexRay[indexA];
595            SimpleRay::IntersectionRes[indexR + rayOffset].maxt =
596              tmax + Limits::Small;
597            if (TestFullLeaf(rays[indexR+offset], currNode, indexR)) {
598              // copy the result to tdist
599              SimpleRay::IntersectionRes[indexR + rayOffset].tdist =
600                SimpleRay::IntersectionRes[indexR + rayOffset].maxt;
601
602              // we remove the ray from the calculation
603              indexArray[i] = indexArray[cntRays-1];
604              cntRays--; // we decrease the number of rays
605              cntHits++;
606#ifdef _DEBUGKTB
607              cout << "Full leaf HIT " << endl;
608#endif
609             
610#ifdef __TRAVERSAL_STATISTICS
611              _allNodesTraversed += allNodesTraversed;
612              _fullLeavesTraversed += fullLeavesTraversed;
613              _emptyLeavesTraversed += emptyLeavesTraversed;
614#endif // __TRAVERSAL_STATISTICS           
615           
616              // signed distance should be already set in TestFullLeaf
617              // the first object intersected was found
618              continue;
619            }
620          } // full leaf
621#ifdef __TRAVERSAL_STATISTICS
622          else {
623#ifdef _DEBUGKTB
624            cout << "Empty leaf at depth= " << depth << endl;
625#endif     
626            emptyLeavesTraversed++;
627          }
628#endif // __TRAVERSAL_STATISTICS
629
630#ifdef _DEBUGKTB
631          cout << "Pop the node" << endl;
632#endif     
633   
634          // pop farChild from the stack
635          // restore the current values
636          --indexSA;
637          // This is bits 0,1,2,3,4,5 - the stack depth = 32 !
638          if ( (indexSA & 0x1f) == 0) {
639            // we remove the ray from the calculation
640            indexArray[i] = indexArray[cntRays-1];
641            cntRays--; // we decrease the number of rays
642          }
643          else {
644            indexStack[indexA] = indexSA;
645            // we prefetch the data to be accessible
646            // the next time
647            GPREFETCH(stackA[indexSA].nodep, PREF_DEFAULT);
648          }
649          continue;
650        }
651        else {
652          assert(nodeType == CKTBAxes::EE_Link);
653#ifdef _DEBUGKTB
654          cout << "Link " << endl;
655#endif
656          stackA[indexSA].nodep = GetLinkNode(currNode);
657          GPREFETCH(stackA[indexSA].nodep, PREF_DEFAULT);
658          // cout << "Link node was accessed" << endl;
659          continue;
660        }
661      } // empty leaf or link
662    } // for all active rays
663  } // while cntRays
664
665#ifdef __TRAVERSAL_STATISTICS
666  _allNodesTraversed += allNodesTraversed;
667  _fullLeavesTraversed += fullLeavesTraversed;
668  _emptyLeavesTraversed += emptyLeavesTraversed;
669#endif // __TRAVERSAL_STATISTICS
670
671  // no objects found along the ray path
672  return cntHits;
673}
674
675#endif //  TRV00F
676
677} // namespace
678
Note: See TracBrowser for help on using the repository browser.