Ignore:
Timestamp:
01/14/08 15:54:15 (17 years ago)
Author:
bittner
Message:

havran ray caster update

Location:
GTP/trunk/Lib/Vis/Preprocessing/src
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/Lib/Vis/Preprocessing/src/HavranRayCaster.cpp

    r2588 r2592  
    66 
    77 
    8 #include "HavranRayCaster.h" 
    98#include "VssRay.h" 
    109#include "KdTree.h" 
     
    1312 
    1413#ifdef USE_HAVRAN_RAYCASTER 
     14#include "ktbconf.h" 
    1515#include "timer.h" 
    1616#include "ktball.h" 
    1717#include "ktb.h" 
     18#ifdef _USE_HAVRAN_SSE 
     19 
    1820#include "raypack.h" 
     21#endif // _USE_HAVRAN_SSE 
    1922#endif // USE_HAVRAN_RAYCASTER 
     23#include "HavranRayCaster.h" 
    2024 
    2125#define DEBUG_RAYCAST 0 
    2226 
     27// This macro should be undefined when testing ray tracing 
     28// by casting rays from file or using camera 
     29#define _PROCESS_RAY 
     30 
    2331namespace GtpVisibilityPreprocessor { 
    2432 
    2533 
    2634#ifdef USE_HAVRAN_RAYCASTER  
     35#ifdef _USE_HAVRAN_SSE 
     36   
    2737// static rays 
    2838RayPacket2x2 
    2939HavranRayCaster::raypack; 
     40#endif // _USE_HAVRAN_SSE 
    3041#endif // USE_HAVRAN_RAYCASTER 
    3142   
     
    6576} 
    6677 
    67  
     78bool 
     79HavranRayCaster::ExportBinTree(const string &filename) 
     80{ 
     81  return mKtbtree->ExportBinTree(filename); 
     82} 
     83 
     84bool 
     85HavranRayCaster::ImportBinTree(const string &filename, ObjectContainer &objects) 
     86{ 
     87  return mKtbtree->ImportBinTree(filename, objects); 
     88} 
     89 
     90   
    6891// Using packet of 4 rays supposing that these are coherent 
    6992// We give a box to which each ray is clipped to before the 
    7093// ray shooting is computed ! 
    7194void HavranRayCaster::CastRaysPacket4(Vector3 &boxmax, 
    72                                                                           Vector3 &boxmin, 
    73                                                                           Vector3 origin4[], 
    74                                                                           Vector3 direction4[], 
    75                                                                           int     result4[], 
    76                                                                           float   dist4[]) 
    77 { 
     95                                      Vector3 &boxmin, 
     96                                      Vector3 origin4[], 
     97                                      Vector3 direction4[], 
     98                                      int     result4[], 
     99                                      float   dist4[]) 
     100{ 
     101#ifdef _USE_HAVRAN_SSE   
    78102#ifdef USE_HAVRAN_RAYCASTER  
    79103  for (int i = 0; i < 4; i++) { 
     
    92116    // this object 
    93117    Intersectable* intersectable; 
    94     if ( (intersectable = raypack.GetObject(i)) ) 
    95           // $$JB this is very hacky - > should be replaced with fetching the index of the triangle 
    96           result4[i] = (int)intersectable; 
     118    if ( (intersectable = raypack.GetObject(i)) ) { 
     119      // $$JB this is very hacky - > should be replaced with fetching the index of the triangle 
     120      result4[i] = intersectable->mId; 
     121      dist4[i] = raypack.GetT(i); 
     122    } 
    97123  } 
    98124   
    99125  return; 
    100 #endif 
    101 } 
     126#endif // USE_HAVRAN_RAYCASTER  
     127#else // _USE_HAVRAN_SSE 
     128  // Compute the result ray by ray 
     129  SimpleRay sray; 
     130  for (int i = 0; i < 4; i++) { 
     131    sray.mOrigin = origin4[i]; 
     132    sray.mDirection = direction4[i]; 
     133    mKtbtree->FindNearestI(sray, boxmin, boxmax); 
     134    if (SimpleRay::IntersectionRes[0].intersectable) { 
     135      // This is object ID - is this the triangle index ??? 
     136      result4[i] = SimpleRay::IntersectionRes[0].intersectable->mId; 
     137      dist4[i] = SimpleRay::IntersectionRes[0].tdist; 
     138    } 
     139    else { 
     140      result4[i] = -1; // no intersection 
     141    } 
     142  } // for i; 
     143   
     144#endif // _USE_HAVRAN_SSE   
     145} 
     146 
    102147 
    103148int HavranRayCaster::CastRay(const SimpleRay &simpleRay, 
     
    124169   
    125170  // ray.mFlags &= ~Ray::CULL_BACKFACES; 
    126  
    127   if (mKtbtree->FindNearestI(simpleRay))  { 
     171  bool result; 
     172  if ((result = mKtbtree->FindNearestI(simpleRay)))  { 
    128173    hitA.mObject = SimpleRay::IntersectionRes[0].intersectable; 
    129174    float tdist = SimpleRay::IntersectionRes[0].tdist; 
     
    151196  } 
    152197 
     198#ifdef _PROCESS_RAY   
    153199  // This code is also in IntelRayCaster.cpp 
    154200  return ProcessRay( 
     
    161207                    pruneInvalidRays 
    162208                    ); 
    163 #else // USE_HAVRAN_RAYCASTER  
     209#else // _PROCESS_RAY 
     210  return result; 
     211#endif // _PROCESS_RAY   
     212 
     213#else 
    164214  return 0; 
    165 #endif 
     215#endif // USE_HAVRAN_RAYCASTER    
    166216} 
    167217 
     
    190240 
    191241#if 0 
    192   SimpleRayContainer::const_iterator sit = rays.begin() + offset; 
    193   SimpleRayContainer::const_iterator sit_end = sit + 16; 
    194    
     242  // This is shooting ray by ray 
     243  SimpleRayContainer::const_iterator sit, sit_end = rays.end(); 
     244 
    195245  // no acceleration for ray bundles implemented right now 
    196246  for (sit = rays.begin(); sit != sit_end; ++ sit)  
     
    199249  } 
    200250#else 
     251  // Use special algorithm for 16 rays at once 
    201252  if (castDoubleRays) { 
    202 #if 0 
     253 
     254#if 0 // ------------------------------------------------ 
    203255    // Special routine to cast double sided rays 
    204256    mKtbtree->SetOffset(0); 
     257#ifdef _USE_HAVRAN_SSE   
    205258    mKtbtree->FindNearestI_16twoDir(rays); 
    206259#else 
     260    mKtbtree->FindNearestI_16twoDirNoSSE(rays);     
     261#endif 
     262#else // ------------------------------------------------- 
    207263    // Here we decompose shooting into two phases 
    208 #if 1     
    209     // Here we shoot first forward rays and then backward ones 
    210     mKtbtree->SetOffset(0); 
    211     mKtbtree->FindNearestI_16oneDir(rays, offset); 
    212     SimpleRayContainer::iterator sit = rays.begin() + offset;  
    213     SimpleRayContainer::const_iterator sit_end = rays.begin() + offset + 16; 
    214     for (; sit != sit_end; ++ sit)  
    215     { 
    216       (*sit).mDirection = - (*sit).mDirection; 
    217     } 
    218     // We store the results at different place 
    219     mKtbtree->SetOffset(16); 
    220     mKtbtree->FindNearestI_16oneDir(rays, offset); 
    221     sit = rays.begin() + offset;  
    222     for ( ; sit != sit_end; ++ sit)  
    223     { 
    224       (*sit).mDirection = - (*sit).mDirection; 
    225     } 
    226 #else 
     264 
    227265    // Here we shoot first backward rays and forward ones 
    228266    SimpleRayContainer::iterator sit = rays.begin() + offset;  
     
    232270      (*sit).mDirection = - (*sit).mDirection; 
    233271    } 
    234     // backward rays to be shot 
     272    // backward rays to be shot - saving with offset 16 
     273#ifdef _USE_HAVRAN_SSE   
     274    mKtbtree->SetOffset(0); 
     275    mKtbtree->FindNearestI_16oneDir(rays, offset, 16); 
     276#else 
    235277    mKtbtree->SetOffset(16); 
    236     mKtbtree->FindNearestI_16oneDir(rays, offset); 
     278    mKtbtree->FindNearestI_16oneDirNoSSE(rays, offset); 
     279#endif // _USE_HAVRAN_SSE 
    237280    sit = rays.begin() + offset;  
    238281    for ( ; sit != sit_end; ++ sit)  
     
    241284    } 
    242285    // forward rays to be shot 
     286#ifdef _USE_HAVRAN_SSE 
    243287    mKtbtree->SetOffset(0); 
    244     mKtbtree->FindNearestI_16oneDir(rays, offset); 
    245 #endif     
    246 #endif     
    247   } 
     288    mKtbtree->FindNearestI_16oneDir(rays, offset, 0); 
     289#else 
     290    mKtbtree->SetOffset(0); 
     291    mKtbtree->FindNearestI_16oneDirNoSSE(rays, offset); 
     292#endif // _USE_HAVRAN_SSE   
     293#endif // ------------------------------------------------ 
     294  } // cast double rays 
    248295  else { 
     296    // ONLY single rays 
    249297    // Shoot all 16 rays  at the same time using a special algorithm 
    250298    mKtbtree->SetOffset(0); 
    251     mKtbtree->FindNearestI_16oneDir(rays, offset);     
    252   } 
    253 #endif 
    254  
     299#ifdef _USE_HAVRAN_SSE   
     300    mKtbtree->FindNearestI_16oneDir(rays, offset, 0);     
     301#else 
     302    mKtbtree->FindNearestI_16oneDirNoSSE(rays, offset);     
     303#endif // _USE_HAVRAN_SSE   
     304  } 
     305#endif 
     306   
    255307   
    256308  for (int i=0, k=offset; i < 16; i++, k++)  
     
    282334    { 
    283335      Intersectable *intersect = 
    284                 SimpleRay::IntersectionRes[i+16].intersectable; 
     336        SimpleRay::IntersectionRes[i+16].intersectable; 
    285337 
    286338      if (intersect) 
    287339      {  
    288                 hitB.mObject = intersect; 
    289                 hitB.mNormal = intersect->GetNormal(0); 
    290                 // $$ JB : i -> i+16 
    291                 float tdist = SimpleRay::IntersectionRes[i+16].tdist; 
    292                 hitB.mPoint = rays[k].Extrap(-tdist); 
     340        hitB.mObject = intersect; 
     341        hitB.mNormal = intersect->GetNormal(0);; 
     342        float tdist = SimpleRay::IntersectionRes[16+i].tdist; 
     343        hitB.mPoint = rays[k].Extrap(-tdist); 
    293344      } 
    294345    } 
     
    298349#endif 
    299350 
    300 #if 1 
     351#ifdef _PROCESS_RAY   
    301352    ProcessRay(rays[k], 
    302                            hitA, 
    303                            hitB, 
    304                            vssRays, 
    305                            sbox, 
    306                            castDoubleRays, 
    307                            pruneInvalidRays 
    308                            ); 
     353               hitA, 
     354               hitB, 
     355               vssRays, 
     356               sbox, 
     357               castDoubleRays, 
     358               pruneInvalidRays 
     359               ); 
    309360#endif 
    310361  } // for 
     
    340391  for (i=0; i < packets; i++) { 
    341392    int offset = i * 16; 
    342     mKtbtree->FindNearestI_16oneDir(rays, offset); 
     393    mKtbtree->FindNearestI_16oneDir(rays, offset, 0); 
    343394    // ??? What to do with the results ? These are 
    344395    // not used at the moment also in IntelRayCaster.cpp 
     
    372423  cout<<1e-3*2*rays.size()/TimeDiff(time, GetTime())<<" Mrays/sec"<<endl; 
    373424#endif 
    374    
     425 
     426  // Cast only by 16 rays at once 
    375427  for (int i=0; i < buckets; i++, offset+=16) { 
    376428    CastRays16(rays, offset, vssRays, sbox, 
     
    381433  } 
    382434 
     435  // Cast the rest of the rays 
    383436  for (; offset < (int)rays.size(); offset++) 
    384437    CastRay(rays[offset], vssRays, sbox, castDoubleRay, pruneInvalidRays); 
    385 } 
    386  
    387 #if 0 
     438 
     439  return; 
     440} 
     441 
     442#ifdef _USE_HAVRAN_SSE 
    388443// BUG1 41579  196948 1064111 
    389444// BUG2 254    1672   10869 
     
    392447void 
    393448HavranRayCaster::CastRaysPacket2x2(RayPacket2x2 &raysPack, 
    394                                                                    bool castDoubleRay, 
    395                                                                    const bool pruneInvalidRays) 
    396 { 
    397 #ifdef USE_HAVRAN_RAYCASTER  
     449                                   bool castDoubleRay, 
     450                                   const bool pruneInvalidRays) 
     451{ 
     452#ifdef USE_HAVRAN_RAYCASTER  
     453#ifdef _USE_HAVRAN_SSE 
    398454 
    399455  if (castDoubleRay) { 
     
    443499 
    444500  return; 
     501#endif // _USE_HAVRAN_SSE 
    445502#endif // USE_HAVRAN_RAYCASTER  
    446503} 
    447 #endif 
     504#endif // _USE_HAVRAN_SSE 
    448505 
    449506 
  • GTP/trunk/Lib/Vis/Preprocessing/src/HavranRayCaster.h

    r2582 r2592  
    55#include "Containers.h" 
    66#include <string> 
    7 #include "havran/raypack.h" 
    8  
     7#include "ktbconf.h" 
     8#include "raypack.h" 
    99 
    1010namespace GtpVisibilityPreprocessor { 
     
    1515class KdTree; 
    1616class Ray; 
    17 class RayPacket2x2; 
    1817class SimpleRayContainer; 
    1918class AxisAlignedBox3; 
     
    3837   
    3938  int Type() const { return HAVRAN_RAYCASTER; } 
    40  
    41   // Using packet of 4 rays supposing that these are coherent 
    42   // We give a box to which each ray is clipped to before the 
    43   // ray shooting is computed ! 
    44   virtual void CastRaysPacket4(Vector3 &minBox, 
    45                                Vector3 &maxBox, 
    46                                Vector3 origin4[], 
    47                                Vector3 direction4[], 
    48                                int     result4[], 
    49                                float   dist4[]); 
    5039   
    5140  virtual int CastRay( 
     
    8271                        const bool castDoubleRay, 
    8372                        const bool pruneInvalidRays = true); 
     73 
     74  // Using packet of 4 rays supposing that these are coherent 
     75  // We give a box to which each ray is clipped to before the 
     76  // ray shooting is computed ! 
     77  virtual void CastRaysPacket4(Vector3 &minBox, 
     78                               Vector3 &maxBox, 
     79                               Vector3 origin4[], 
     80                               Vector3 direction4[], 
     81                               int     result4[], 
     82                               float   dist4[]); 
     83 
     84#ifdef _USE_HAVRAN_SSE   
     85  // Just for testing concept 
     86  virtual void CastRaysPacket2x2(RayPacket2x2 &raysPack, 
     87                                 bool castDoubleRay, 
     88                                 const bool pruneInvalidRays = true); 
     89#endif   
     90 
     91  bool ExportBinTree(const string &filename); 
     92  bool ImportBinTree(const string &filename, ObjectContainer &objects); 
     93   
    8494protected: 
    8595  CKTB *mKtbtree; 
  • GTP/trunk/Lib/Vis/Preprocessing/src/Makefile

    r2589 r2592  
    11############################################################################# 
    22# Makefile for building: preprocessor 
    3 # Generated by qmake (2.00a) (Qt 4.1.2) on: ?t 10. I 13:25:38 2008 
     3# Generated by qmake (2.00a) (Qt 4.1.2) on: po 14. I 15:10:11 2008 
    44# Project:  preprocessor.pro 
    55# Template: app 
     
    6363        $(MAKE) -f $(MAKEFILE).Debug uninstall 
    6464 
    65 Makefile: preprocessor.pro  C:/Qt/4.1.2/mkspecs/win32-msvc2005\qmake.conf C:/Qt/4.1.2/mkspecs/qconfig.pri \ 
     65Makefile: preprocessor.pro  C:/Qt/4.1.2/mkspecs/win32-msvc.net\qmake.conf C:/Qt/4.1.2/mkspecs/qconfig.pri \ 
    6666                C:\Qt\4.1.2\mkspecs\features\qt_config.prf \ 
    6767                C:\Qt\4.1.2\mkspecs\features\exclusive_builds.prf \ 
  • GTP/trunk/Lib/Vis/Preprocessing/src/Mutation.cpp

    r2590 r2592  
    9494 
    9595                Intersectable *oldObject = mRays[vssRays[i]->mGeneratorId].mRay->mTerminationObject; 
    96                  
     96                // the ray generated a contribution although it hits the same object 
     97                // mark this using a counter 
    9798                if (oldObject == newObject) 
    9899                  dummyCMutations++; 
     
    106107                mRays.push_back(RayEntry(newRay)); 
    107108          } else { 
    108                 // unref the old ray 
     109                // unref the old ray and add the new ray into the mutation buffer 
    109110                *mRays[mBufferStart].mRay = *vssRays[i]; 
    110111                mRays[mBufferStart].mMutations = 0; 
     
    117118          } 
    118119        } else { 
     120          // the ray did not generate any contribution 
    119121          if (vssRays[i]->mDistribution == MUTATION_BASED_DISTRIBUTION && 
    120122                  vssRays[i]->mGeneratorId != -1 
    121123                  ) { 
    122124                // check whether not to store a new backward mutation candidate 
     125                // this happens if the new ray is occluded significantly closer than 
     126                // the generator ray 
    123127                VssRay *oldRay = mRays[vssRays[i]->mGeneratorId].mRay; 
    124128                VssRay *newRay = vssRays[i]; 
    125129 
    126  
    127130                Intersectable *oldObject = oldRay->mTerminationObject; 
    128                  
    129  
     131 
     132                // only allow one reverse mutation per generator ray 
    130133                if (!mRays[newRay->mGeneratorId].HasReverseMutation()) { 
    131134                  if (DotProd(oldRay->GetDir(), newRay->GetDir()) > 0.0f) { 
     
    149152                Intersectable *newObject = vssRays[i]->mTerminationObject; 
    150153 
    151  
    152154                if (oldObject == newObject) 
    153155                  dummyNcMutations++; 
     
    163165        cout<<"Dummy NC mutations ratio:"<<100.0f*dummyNcMutations/(float)mutationRays<<"%"<<endl; 
    164166        cout<<"Dummy C mutations ratio:"<<100.0f*dummyCMutations/(float)mutationRays<<"%"<<endl; 
    165         cout<<"Reverse candidates:"<<reverseCandidates<<endl; 
     167        cout<<"Reverse candidates:"<<100.0f*reverseCandidates/(float)mutationRays<<endl; 
    166168  } 
    167169   
    168170  float pContributingRays = contributingRays/(float)vssRays.size(); 
    169171   
    170   cout<<"Percentage of contributing rays:"<<pContributingRays<<endl; 
     172  cout<<"Ratio of contributing rays:"<<pContributingRays<<endl; 
    171173   
    172174  if (mUseUnsuccCountImportance) { 
     
    233235                                                                                                 ) 
    234236{ 
    235 #if 0 
    236   Vector3 v; 
    237   if (d.DrivingAxis() == 0) 
    238         v = Vector3(0, r[0]-0.5f, r[1]-0.5f); 
    239   else 
    240         if (d.DrivingAxis() == 1) 
    241           v = Vector3(r[0]-0.5f, 0, r[1]-0.5f); 
    242         else 
    243           v = Vector3(r[0]-0.5f, r[1]-0.5f, 0); 
    244   return v*(2*radius); 
    245 #endif 
    246237#if 0 
    247238  return (U*(r[0] - 0.5f) + V*(r[1] - 0.5f))*(2*radius); 
     
    339330   
    340331  AxisAlignedBox3 box = occluder->GetBox(); 
     332  // consider slightly larger neighborhood of the occluder 
     333  // in search for unocclude reverse ray 
    341334  box.Scale(2.0f); 
    342335   
     
    430423  } 
    431424 
     425  return true; 
    432426#else 
    433427  cerr << "warning: reverse mutation not supported!" << endl; 
    434 #endif 
    435    
    436   return true; 
     428  return false; 
     429#endif 
     430   
    437431   
    438432  // now the origin and termination is swapped compred to the generator ray 
     
    510504 
    511505#else 
    512         cerr << "warning: shiluette mutation not supported" << endl; 
    513         return Vector3(0, 0, 0); 
     506  //cerr << "warning: shiluette mutation not supported" << endl; 
     507  return Vector3(0, 0, 0); 
    514508#endif 
    515509   
     
    523517  if (mRays.size() == 0) { 
    524518        float rr[5]; 
    525         // use direction based distribution 
     519        // use direction based distribution until we have some mutation candidates 
    526520        Vector3 origin, direction; 
    527521 
     
    532526                                                                                                  Vector3(rr[0], rr[1], rr[2])); 
    533527         
    534  
     528         
    535529        direction = UniformRandomVector(rr[3], rr[4]); 
    536530         
     
    538532        sray = SimpleRay(origin, direction, MUTATION_BASED_DISTRIBUTION, pdf); 
    539533        sray.mGeneratorId = -1; 
    540  
     534         
    541535        return true; 
    542   }  
     536  } 
    543537 
    544538  int index; 
     
    552546        if ( 
    553547                mRays[index].GetSamplingFactor() >= mRays[mLastIndex].GetSamplingFactor()) { 
    554           // make another round 
     548          // make another round to equalize the oversampling factor 
    555549 
    556550          //      cout<<"R2"<<endl; 
     
    666660   
    667661  if (mUseSilhouetteSamples && a < mSilhouetteProb) { 
    668          
    669662        termination += ComputeSilhouetteTerminationMutation(*ray, 
    670663                                                                                                                origin, 
     
    692685   
    693686  // shift the origin a little bit 
     687#if 1 
    694688  origin += direction*0.5f; 
     689#else 
     690  // $$JB - 14.1. 2008 increase shift to test HavranRayCaster 
     691  origin = 0.5f*(origin + termination); 
     692#endif 
    695693   
    696694  direction.Normalize(); 
     
    718716    mRays[index].mMutations++; 
    719717        mRays[index].mUnsuccessfulMutations++; 
    720  
    721718        return true; 
    722719  } 
  • GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp

    r2590 r2592  
    12301230        if ( 
    12311231            rays.size() > 10000) 
    1232         { 
     1232          { 
    12331233 
    12341234          mRayCaster->SortRays(rays); 
    1235           //    cout<<"Rays sorted in "<<TimeDiff(t1, GetTime())<<" ms."<<endl; 
     1235          cout<<"Rays sorted in "<<TimeDiff(t1, GetTime())<<" ms."<<endl; 
    12361236        } 
    12371237 
  • GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp

    r2583 r2592  
    178178  //const int batchsize = 16384; 
    179179  const int batchsize = 8192; 
     180  // const int batchsize = 1024; 
    180181  //const int batchsize = 128; 
    181182 
  • GTP/trunk/Lib/Vis/Preprocessing/src/default.env

    r2588 r2592  
    5353        useGlDebugger false 
    5454# 0 = INTERNAL  1 = MLRT 2 = HAVRAN 
    55         rayCastMethod 1 
     55        rayCastMethod 2 
    5656         
    5757#       type sampling 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/configh.h

    r2582 r2592  
    5959 
    6060#ifdef _MSC_VER 
     61#define __SSE__ 
    6162// disable some Microsoft Visual Compiler warnings if necessary 
    6263#pragma warning( disable:4305 ) 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktb.cpp

    r2582 r2592  
    6161  float tclosest = Limits::Infinity; 
    6262  int intersected = 0; 
     63  // rayIndex += rayOffset; 
    6364  // iterate the whole list and find out the nearest intersection 
    6465  for (ObjectContainer::iterator sc = list->begin(); sc != sc_end; sc++) { 
     
    352353} 
    353354 
     355// Set the pointers to children for the interior node 
     356void 
     357CKTBAllocMan::SetInteriorNodeLeft(SKTBNodeT *node, 
     358                                  SKTBNodeT *leftChild) 
     359{ 
     360  leftChild = leftChild; // to satisfy the compiler 
     361 
     362  // Check on correctness of DFS order 
     363  assert( (node+1 == leftChild) || (node+2 == leftChild) || (node+4 == leftChild) ); 
     364} 
     365 
     366// Set the pointers to children for the interior node 
     367void 
     368CKTBAllocMan::SetInteriorNodeRight(SKTBNodeT *node, 
     369                                   SKTBNodeT *rightChild) 
     370{ 
     371  node->right = rightChild; 
     372} 
     373 
     374   
    354375// Create the representation of the leaf. Note that possibly there 
    355376// can be special cases, such as 0, 1, 2, or 3 objects, or in general 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktb.h

    r2582 r2592  
    156156#endif 
    157157   
    158   // init the stack of auxiliary variables from min to max 
    159   virtual void InitAux(int min, int max, int maxItemsAtOnce); 
    160  
    161158  // the direction of traversal through CKTB tree 
    162159  enum EDirection { LEFT = 0, RIGHT = 1, NOWHERE = 2 }; 
     
    180177  virtual ~CKTBAllocMan() { } 
    181178 
     179  // init the stack of auxiliary variables from min to max 
     180  virtual void InitAux(int min, int max, int maxItemsAtOnce); 
     181   
    182182  // forget the content that is created by previous kd-tree construction 
    183183  // or just init for the first use. 
     
    224224  void SetInteriorNodeLinks(SKTBNodeT *node, 
    225225                            SKTBNodeT *leftChild, 
     226                            SKTBNodeT *rightChild); 
     227  void SetInteriorNodeLeft(SKTBNodeT *node, 
     228                           SKTBNodeT *leftChild); 
     229  void SetInteriorNodeRight(SKTBNodeT *node, 
    226230                            SKTBNodeT *rightChild); 
    227231 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktb8b.cpp

    r2582 r2592  
    6363  float tclosest = Limits::Infinity; 
    6464  int intersected = 0; 
    65   // indexRay += rayOffset; 
     65  indexRay += rayOffset; 
    6666  // iterate the whole list and find out the nearest intersection 
    6767  for (ObjectContainer::iterator sc = list->begin(); sc != sc_end; sc++) { 
     
    7676  return intersected; 
    7777} 
    78  
    7978   
    8079// test all objects in the leaf for intersection with ray 
     
    244243CKTB8BAllocMan::AllocInteriorNodeWithBox(int axis, float position, 
    245244                                         int cntLeft, int cntRight, 
    246                                          const SBBox &tsbox, SKTBNodeT* prevMinBoxNode, 
     245                                         const SBBox &tsbox, 
     246                                         SKTBNodeT* prevMinBoxNode, 
    247247                                         int depthStore) 
    248248{ 
     
    354354  leftChild = leftChild; // to satisfy the compiler 
    355355 
     356#if 1 
     357  if (! ((node+1 == leftChild) || (node+2 == leftChild) || 
     358         (node+5 == leftChild))) { 
     359 
     360    cout << "Problem with left node linking " << endl; 
     361  } 
     362 
     363#endif       
    356364  // Check on correctness of DFS order 
    357365  assert( (node+1 == leftChild) || (node+2 == leftChild) || (node+5 == leftChild) ); 
     
    390398} 
    391399 
     400// Set the pointers to children for the interior node 
     401void 
     402CKTB8BAllocMan::SetInteriorNodeLeft(SKTBNodeT *node, 
     403                                    SKTBNodeT *leftChild) 
     404{ 
     405  leftChild = leftChild; // to satisfy the compiler 
     406 
     407#if 1 
     408  if (! ((node+1 == leftChild) || (node+2 == leftChild) || 
     409         (node+5 == leftChild))) { 
     410 
     411    cout << "Problem with left node linking " << endl; 
     412    abort(); 
     413  } 
     414 
     415#endif       
     416  // Check on correctness of DFS order 
     417  assert( (node+1 == leftChild) || (node+2 == leftChild) || (node+5 == leftChild) ); 
     418 
     419  // Nothing to do - left link is linked automatically 
     420  return; 
     421} 
     422 
     423// Set the pointers to children for the interior node 
     424void 
     425CKTB8BAllocMan::SetInteriorNodeRight(SKTBNodeT *node, 
     426                                     SKTBNodeT *rightChild) 
     427{ 
     428  assert(node->offset <= CKTBAxes::EE_Z_axisBox); 
     429  //assert(node->offset >= 0); 
     430  //(unsigned long)node->offset |= (unsigned long)rightChild; 
     431  node->offset = node->offset | (unsigned int)rightChild; 
     432#ifdef _DEBUG 
     433  // Compute right child 
     434  SKTBNodeT *p = GetRight(node); 
     435  if (p != rightChild) { 
     436    cerr << "Problem with implementation of setting right child" << endl; 
     437    abort();; 
     438  }  
     439#endif 
     440 
     441  return; 
     442} 
     443 
     444   
    392445// Create the representation of the leaf. Note that possibly there 
    393446// can be special cases, such as 0, 1, 2, or 3 objects, or in general 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktb8b.h

    r2582 r2592  
    161161#endif 
    162162   
    163   // init the stack of auxiliary variables from min to max 
    164   void InitAux(int min, int max, int maxItemsAtOnce); 
    165  
    166163  // the direction of traversal through CKTB tree 
    167164  enum EDirection { LEFT = 0, RIGHT = 1, NOWHERE = 2 }; 
     
    185182  ~CKTB8BAllocMan() { } 
    186183 
     184  // init the stack of auxiliary variables from min to max 
     185  void InitAux(int min, int max, int maxItemsAtOnce); 
     186   
    187187  // forget the content that is created by previous kd-tree construction 
    188188  // or just init for the first use. 
     
    232232  void SetInteriorNodeLinks(SKTBNodeT *node, 
    233233                            SKTBNodeT *leftChild, 
     234                            SKTBNodeT *rightChild); 
     235 
     236  void SetInteriorNodeLeft(SKTBNodeT *node, 
     237                           SKTBNodeT *leftChild); 
     238  void SetInteriorNodeRight(SKTBNodeT *node, 
    234239                            SKTBNodeT *rightChild); 
    235240 
     
    275280  void DecDepth() {_currDepth--;} 
    276281 
     282   
    277283  // -------------------------------------------------------------- 
    278284  // Statistics 
     
    300306  float _sumSurfaceAreaInteriorNodes; 
    301307#endif 
    302  
     308   
    303309  // General statistics on the depth of current node 
    304310  // the depth of the currently accessed node during building up 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktbai.cpp

    r2582 r2592  
    12211221  if (objlist.size() == 0) 
    12221222    return 0; // nothing 
    1223   cerr<<"hh44"<<endl; 
     1223  // cerr<<"hh44"<<endl; 
    12241224  // initialize the whole box of the kd-tree and sort 
    12251225  // the boundary entries 
    12261226  SInputData *d = Init(&objlist, box); 
    12271227 
    1228   cerr<<"hh45"<<endl; 
     1228  //cerr<<"hh45"<<endl; 
    12291229 
    12301230  // copy verbose to be used consistenly further on 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktball.cpp

    r2582 r2592  
    2222#include <fstream> 
    2323#include <iomanip> 
     24#include <stack> 
    2425 
    2526namespace GtpVisibilityPreprocessor { 
     
    9697  const int size1D = 150; 
    9798 
    98   cerr<<"th1"<<endl; 
     99  // cerr<<"th1"<<endl; 
    99100  // $$JB tmp 
    100101  size2D = 1; 
    101   cerr<<"size2d="<<size2D<<endl; 
     102  // cerr<<"size2d="<<size2D<<endl; 
    102103  // initial index 
    103104  index2D = 0; 
    104105  AllocBuffer(size2D, size1D); 
    105   cerr<<"th2"<<endl; 
     106  //  cerr<<"th2"<<endl; 
    106107 
    107108#if 0   
     
    117118  } 
    118119#else 
    119   cerr<<"th3"<<endl; 
     120  // cerr<<"th3"<<endl; 
    120121 
    121122  traversalClass = new CKTBTraversal;  
     
    308309#endif // _DEBUG 
    309310 
    310   cerr<<"hh2"<<endl; 
     311  // cerr<<"hh2"<<endl; 
    311312  // possibly remove the old building class 
    312313  // and allocate the class for CKTB building up 
     
    315316  buildClass = AllocBuildClass(); 
    316317 
    317   cerr<<"hh3"<<endl; 
     318  // cerr<<"hh3"<<endl; 
    318319 
    319320  // and for traversal 
    320321  AllocTraversalClass(); 
    321   cerr<<"hh4"<<endl; 
     322  // cerr<<"hh4"<<endl; 
    322323 
    323324  if (boxToBoundObjects) { 
     
    330331    bbox.Include(*boxToInclude);   
    331332 
    332   cerr<<"hh5"<<endl; 
     333  // cerr<<"hh5"<<endl; 
    333334 
    334335  // build up the CKTB tree and make setup for traversal 
    335336  SKTBNodeT *rootNode = 
    336337    buildClass->BuildUp(objlist, bbox, verbose); 
    337   cerr<<"hh6"<<endl; 
     338  // cerr<<"hh6"<<endl; 
    338339 
    339340  traversalClass->Setup(bbox, rootNode); 
    340   cerr<<"hh7"<<endl; 
     341  // cerr<<"hh7"<<endl; 
    341342 
    342343#ifdef _DEBUG 
     
    400401} 
    401402 
     403int 
     404CKTB::FindNearestI(const SimpleRay &ray, Vector3 &boxmin, Vector3 &boxmax) 
     405{ 
     406  const AxisAlignedBox3 localbox(boxmin, boxmax); 
     407  return traversalClass->FindNearestI(ray, localbox);       
     408} 
     409 
     410   
     411#ifdef _USE_HAVRAN_SSE   
     412 
    402413#ifdef __SSE__ 
    403414// -------------------------------------------------------------- 
     
    420431 
    421432#endif // __SSE__ 
     433 
     434#endif // _USE_HAVRAN_SSE   
     435 
    422436   
    423437void 
     
    752766SKTBNodeT* 
    753767CKTB::ImportBinLeaf(IN_STREAM &stream,  
    754                     SKTBNodeT *parent, 
     768                    SKTBNodeT **nodeToLink, 
    755769                    const ObjectContainer &objects) 
    756770{ 
     
    764778    // since for  
    765779    SKTBNodeT* leaf = buildClass->AllocLeaf(0); 
     780    *nodeToLink = buildClass->nodeToLink; 
    766781    return leaf; 
    767782  } 
     
    769784  MeshInstance dummyInst(NULL); 
    770785  SKTBNodeT* leaf = buildClass->AllocLeaf(size); 
     786  *nodeToLink = buildClass->nodeToLink; 
    771787 
    772788  ObjectContainer *newobjlist = new ObjectContainer; 
     
    809825 
    810826SKTBNodeT * 
    811 CKTB::ImportBinInterior(IN_STREAM  &stream, SKTBNodeT *parent) 
     827CKTB::ImportBinInterior(IN_STREAM  &stream, SKTBNodeT **nodeToLink) 
    812828{ 
    813829  int axis; 
     
    819835  SKTBNodeT *interiorNode = 
    820836    buildClass->AllocInteriorNode(axis, pos, 0, 0); 
     837  *nodeToLink = buildClass->nodeToLink; 
    821838         
    822839  return interiorNode; 
     
    830847  if (!stream.is_open()) return false; 
    831848 
    832   // DEBUG << "CKTB::GatherStats called" << endl; 
    833   struct EDir { 
    834     SKTBNodeT *node; 
    835     int depth; 
    836     AxisAlignedBox3 bbox; 
    837   }; 
    838   EDir stack[CKTBTraversal::MAX_TRAVERSAL_HEIGHT]; 
    839   int stackTop = 0; // pointer to the stack 
    840   stack[stackTop].node = 0; 
    841   stack[stackTop].depth = 0; 
    842   stack[stackTop].bbox = bbox; 
    843   int tmpdir; 
     849  int startMark = 0xf0f0; 
     850  stream.write(reinterpret_cast<char *>(&startMark), sizeof(int));   
    844851   
    845852  // export binary version of mesh 
    846   queue<SKTBNodeT *> tStack; 
    847   // start from the root node 
    848   SKTBNodeT *currNode = buildClass->GetRootNode(); 
    849  
    850   // copy the box over the scene objects 
    851   AxisAlignedBox3 bwbox = this->bbox; 
    852   int currDepth = 0;   
    853  
    854   // traverse through whole CKTB tree 
    855   do { 
    856     CKTBAxes::Axes nodeType = buildClass->GetNodeType(currNode); 
    857     if (nodeType == CKTBAxes::EE_Link) { 
    858       // just relink 
    859       currNode = buildClass->GetLinkNode(currNode); 
    860       // cout << "Link node was accessed" << endl; 
    861       continue;  
     853  std::stack<SKTBNodeT *> tStack; 
     854  tStack.push(buildClass->GetRootNode()); 
     855  int cntSaves = 0, cntSavesLeaf = 0, cntSavesIN = 0; 
     856 
     857  while(!tStack.empty()) 
     858  { 
     859    SKTBNodeT *node = tStack.top(); 
     860    tStack.pop();     
     861 
     862    int nodeType = buildClass->GetNodeType(node); 
     863     
     864    if (nodeType == CKTBAxes::EE_Link) 
     865    { 
     866      tStack.push(buildClass->GetLinkNode(node)); 
    862867    } 
    863        
    864     if ( (nodeType == CKTBAxes::EE_X_axis)|| 
    865          (nodeType == CKTBAxes::EE_Y_axis)|| 
    866          (nodeType == CKTBAxes::EE_Z_axis)|| 
    867          (nodeType == CKTBAxes::EE_X_axisBox)|| 
    868          (nodeType == CKTBAxes::EE_Y_axisBox)|| 
    869          (nodeType == CKTBAxes::EE_Z_axisBox) 
    870        ) { 
    871        
    872       // push onto the stack 
    873       AxisAlignedBox3 rightBox = bwbox; 
    874       float value = currNode->splitPlane; 
    875       switch(nodeType) { 
    876         case CKTBAxes:: EE_X_axisBox: { 
    877           rightBox.SetMin(0, value); 
    878           bwbox.SetMax(0, value); 
    879           break;           
    880         } 
    881         case CKTBAxes:: EE_X_axis: { 
    882           rightBox.SetMin(0, value); 
    883           bwbox.SetMax(0, value); 
    884           break;           
    885         } 
    886         case CKTBAxes:: EE_Y_axisBox: { 
    887           rightBox.SetMin(0, value); 
    888           bwbox.SetMax(0, value); 
    889           break;           
    890         } 
    891         case CKTBAxes:: EE_Y_axis: { 
    892           rightBox.SetMin(1, value); 
    893           bwbox.SetMax(1, value); 
    894           break;           
    895         } 
    896         case CKTBAxes:: EE_Z_axisBox: { 
    897           rightBox.SetMin(0, value); 
    898           bwbox.SetMax(0, value); 
    899           break;           
    900         } 
    901         case CKTBAxes:: EE_Z_axis: { 
    902           rightBox.SetMin(2, value); 
    903           bwbox.SetMax(2, value); 
    904           break;           
    905         } 
    906       } // switch 
    907  
    908       // Exporting interior node 
    909       ExportBinInterior(stream, currNode); 
    910        
    911       stack[stackTop].node = buildClass->GetRight(currNode); 
    912       stack[stackTop].depth = currDepth + 1; 
    913       stack[stackTop].bbox = rightBox; 
    914       stackTop++; 
    915       // where to go 
    916       if ( (nodeType == CKTBAxes:: EE_X_axisBox)|| 
    917            (nodeType == CKTBAxes:: EE_Y_axisBox)|| 
    918            (nodeType == CKTBAxes:: EE_Z_axisBox) ) 
    919         currNode = buildClass->GetLeftMinBox(currNode); 
     868    else 
     869    if (nodeType == CKTBAxes::EE_Leaf) 
     870    { 
     871      //Debug << "l"; 
     872      ExportBinLeaf(stream, node); 
     873      cntSavesLeaf++; cntSaves++;       
     874    } 
     875    else 
     876    { // interior node 
     877      //Debug << "i"; 
     878      ExportBinInterior(stream, node); 
     879      cntSavesIN++; cntSaves++;       
     880 
     881      tStack.push(buildClass->GetRight(node)); 
     882      if (nodeType >= CKTBAxes::EE_X_axisBox) 
     883        tStack.push(buildClass->GetLeftLong(node)); 
    920884      else 
    921         currNode = buildClass->GetLeft(currNode); 
    922       // the box was already set 
    923       currDepth++; 
    924        
    925       continue; 
    926     } // interior nodes 
    927  
    928     assert(nodeType == CKTBAxes::EE_Leaf); 
    929        
    930     while ( (nodeType == CKTBAxes::EE_Leaf) && currDepth) { 
    931       ObjectContainer *olist = buildClass->GetObjList(currNode); 
    932       // Exporting leaf node 
    933       ExportBinLeaf(stream, static_cast<SKTBNodeT *>(currNode)); 
    934          
    935       // traverse up the tree 
    936       stackTop--; 
    937       if (stackTop < 0) 
    938         goto FINISH; 
    939       // pop the node from the stack 
    940       currNode = stack[stackTop].node; 
    941       currDepth = stack[stackTop].depth; 
    942       bwbox = stack[stackTop].bbox; 
    943        
    944       nodeType = buildClass->GetNodeType(currNode); 
    945          
    946     } // while is a leaf 
    947   } 
    948   while (stackTop >= 0); 
    949  
    950 FINISH: 
    951   // close the stream 
     885        tStack.push(buildClass->GetLeft(node)); 
     886    } 
     887  } // while 
     888 
     889  int endMark = 0xf0ff; 
     890  stream.write(reinterpret_cast<char *>(&endMark), sizeof(int));   
     891 
     892  cout << "Writes " << cntSaves << " cntLeafs " 
     893       << cntSavesLeaf << " cntIN " << cntSavesIN << endl; 
     894   
    952895  stream.close(); 
    953    
    954   return true; 
    955 } 
    956  
    957 #if 0 
    958 KdNode *KdTree::ImportNextNode(IN_STREAM &stream,  
    959                                KdInterior *parent, 
    960                                const ObjectContainer &objects) 
    961 { 
    962         int nodeType; 
    963         stream.read(reinterpret_cast<char *>(&nodeType), sizeof(int)); 
    964  
    965         if (nodeType == TYPE_LEAF) 
    966                 return ImportBinLeaf(stream, static_cast<KdInterior *>(parent), objects); 
    967  
    968         if (nodeType == TYPE_INTERIOR) 
    969                 return ImportBinInterior(stream, static_cast<KdInterior *>(parent)); 
    970  
    971         Debug << "error! loading failed!" << endl; 
    972         return NULL; 
    973 } 
    974  
    975  
    976 bool KdTree::ImportBinTree(const string &filename, ObjectContainer &objects) 
    977 { 
    978   // export binary version of mesh 
    979   queue<TraversalData> tStack; 
     896  return true; // saved 
     897} 
     898 
     899 
     900SKTBNodeT * 
     901CKTB::ImportNextNode(IN_STREAM &stream,  
     902                     SKTBNodeT **nodeToLink, 
     903                     const ObjectContainer &objects) 
     904{ 
     905  int nodeType; 
     906  stream.read(reinterpret_cast<char *>(&nodeType), sizeof(int)); 
     907 
     908  if (nodeType == TYPE_LEAF) 
     909    return ImportBinLeaf(stream, nodeToLink, objects); 
     910 
     911  if (nodeType == TYPE_INTERIOR) 
     912    return ImportBinInterior(stream, nodeToLink); 
     913 
     914  Debug << "error! loading failed!" << endl; 
     915  return NULL; 
     916} 
     917 
     918 
     919// creates the ASDS according to the file description 
     920bool 
     921CKTB::ImportBinTree(const string &filename, ObjectContainer &objects) 
     922{ 
     923  // open the stream in text mode 
    980924  IN_STREAM stream(filename.c_str(), IN_BIN_MODE); 
    981    
    982   if (!stream.is_open()) return false; 
    983    
    984   // sort objects by their id 
     925 
     926  if (!stream.is_open()) { 
     927    cerr << "Kd-tree description file (.kbt) cannot be opened for reading\n"; 
     928    return true; // error 
     929  } 
     930 
     931  int mark; 
     932  stream.read(reinterpret_cast<char *>(&mark), sizeof(int)); 
     933  if (mark != 0xf0f0) { 
     934    cout << "Something wrong with the tree - heading" << endl; 
     935    abort(); 
     936  } 
     937   
     938  // sort objects by their id to allow list creation in kd-tree leaves 
    985939  //    if (!is_sorted(objects.begin(), objects.end(), ilt)) 
    986940  sort(objects.begin(), objects.end(), ilt); 
    987941   
    988   mBox.Initialize(); 
    989   ObjectContainer::const_iterator oit, oit_end = objects.end(); 
    990    
    991   /////////////////////////// 
    992   //-- compute bounding box of object space 
    993    
    994   for (oit = objects.begin(); oit != oit_end; ++ oit) 
    995   { 
    996     const AxisAlignedBox3 box = (*oit)->GetBox(); 
    997     mBox.Include(box); 
    998   } 
    999    
    1000   // hack: we make a new root 
    1001   DEL_PTR(mRoot); 
    1002    
    1003   mRoot = ImportNextNode(stream, NULL, objects); 
    1004    
    1005   tStack.push(TraversalData(mRoot, mBox, 0)); 
    1006   mStat.Reset(); 
    1007   mStat.nodes = 1; 
    1008    
     942  // remove all the data in the current data structure 
     943  CKTBAllocManPredecessor *bc = GetBuildClass(); 
     944  if (!bc) 
     945    bc = buildClass = AllocBuildClass(); 
     946  else 
     947    bc->Remove(); 
     948 
     949  // How many items can be allocated at once 
     950  int maxItemsAtOnce = 1; 
     951  if (makeMinBoxes) { 
     952#ifdef _KTB8Bytes     
     953    // We need to allocate for boxes the memory in a row 
     954    maxItemsAtOnce = 5; // 8x5=40 = 16+24; 
     955#else 
     956    maxItemsAtOnce = 4; // 12x4=48 = 24+24; 
     957#endif // _KTB8Bytes 
     958  } 
     959   
     960  bc->InitAux(0, CKTBNodeAbstract::MAX_HEIGHT - 1, maxItemsAtOnce);   
     961 
     962  // Compute the box from all objects 
     963  bbox.Initialize(); 
     964  for (ObjectContainer::iterator sc = objects.begin(); 
     965       sc != objects.end(); sc++) { 
     966    AxisAlignedBox3 abox = (*sc)->GetBox(); 
     967    bbox.Include(abox); 
     968  } // for 
     969    
     970  // initialize the root node 
     971  SKTBNodeT *node; 
     972 
     973  bc->root = ImportNextNode(stream, &node, objects); 
     974  assert(bc->root == node); 
     975 
     976  std::stack<STraversalData> tStack; 
     977  tStack.push(STraversalData(bc->root, 1, 0)); 
     978  tStack.push(STraversalData(bc->root, 0, 0)); 
     979  int depth, lastDepth; 
     980   
     981  //int cntReads = 1, cntReadsLeaf = 0, cntReadsIN = 1; 
    1009982  while(!tStack.empty()) 
    1010   { 
    1011     TraversalData tData = tStack.front(); 
     983  {     
     984    STraversalData tData = tStack.top(); 
    1012985    tStack.pop(); 
    1013986     
    1014     KdNode *node = tData.mNode; 
     987    node = tData.mNode; 
     988    lastDepth = depth = tData.depth; 
     989    //int nodeType = bc->GetNodeType(node); 
     990    //cout << "nodeType = " << nodeType << " adr = " << (void*)node << endl; 
     991 
     992    SKTBNodeT *childNodeLink = 0; 
     993    SKTBNodeT *childNode = ImportNextNode(stream, &childNodeLink, objects); 
     994    //    cout << "childNode = " << (void*)childNode 
     995    // << " linkNode = " << (void*)childNodeLink << endl; 
     996 
     997    if (tData.dir) 
     998      bc->SetInteriorNodeRight(node, childNodeLink); 
     999    else 
     1000      bc->SetInteriorNodeLeft(node, childNodeLink); 
    10151001     
    1016     if (!node->IsLeaf()) 
     1002    //cntReads++; 
     1003    if (!bc->IsLeaf_(childNode)) 
    10171004    { 
    1018       mStat.nodes += 2; 
    1019        
    1020       //Debug << "i" ; 
    1021       KdInterior *interior = static_cast<KdInterior *>(node); 
    1022       interior->mBox = tData.mBox; 
    1023        
    1024       KdNode *front = ImportNextNode(stream, interior, objects); 
    1025       KdNode *back = ImportNextNode(stream, interior, objects); 
    1026        
    1027       interior->SetupChildLinks(back, front); 
    1028        
    1029       ++ mStat.splits[interior->mAxis]; 
    1030        
    1031       // compute new bounding box 
    1032       AxisAlignedBox3 frontBox, backBox; 
    1033        
    1034       tData.mBox.Split(interior->mAxis,  
    1035                        interior->mPosition,  
    1036                        frontBox,  
    1037                        backBox); 
    1038        
    1039       tStack.push(TraversalData(front, frontBox, tData.mDepth + 1));                     
    1040       tStack.push(TraversalData(back, backBox, tData.mDepth + 1)); 
     1005      //cntReadsIN++; 
     1006      tStack.push(STraversalData(childNode, 1, depth+1)); 
     1007      tStack.push(STraversalData(childNode, 0, depth+1)); 
    10411008    } 
    1042     else 
    1043     { 
    1044       EvaluateLeafStats(tData); 
    1045       //cout << "l"; 
    1046     } 
    1047   } 
    1048  
    1049   float area = GetBox().SurfaceArea()*mKdPvsArea; 
    1050    
    1051   SetPvsTerminationNodes(area); 
    1052    
    1053   Debug << mStat << endl; 
    1054    
    1055   return true; 
    1056 } 
    1057 #endif 
    1058  
     1009    //else { 
     1010    //  cntReadsLeaf++; 
     1011    //  //cout << "leaf" << endl; 
     1012    // } 
     1013  } // while 
     1014 
     1015  //cout << "Last depth = " << lastDepth << endl; 
     1016  //cout << "Reads " << cntReads << " cntLeafs " 
     1017  //   << cntReadsLeaf << " cntIN " << cntReadsIN << endl; 
     1018   
     1019  stream.read(reinterpret_cast<char *>(&mark), sizeof(int)); 
     1020  if (mark != 0xf0ff) { 
     1021    cout << "Something wrong with the kd-tree in the file" 
     1022         << endl; 
     1023    abort(); 
     1024  } 
     1025   
     1026  if (!traversalClass) 
     1027    AllocTraversalClass(); 
     1028     
     1029  // Make setup for traversal 
     1030  traversalClass->Setup(bbox, bc->GetRootNode()); 
     1031  // Handles unbounded objects in traversal class 
     1032  // traversalClass->Setup2(0); 
     1033   
     1034  stream.close(); 
     1035 
     1036  // now the tree is surely well constructed 
     1037  builtUp = true;   
     1038 
     1039  return false; // OK 
     1040} 
    10591041 
    10601042void 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktball.h

    r2582 r2592  
    174174   
    175175  int FindNearestI(const SimpleRay &ray); 
     176  int FindNearestI(const SimpleRay &ray, Vector3 &boxmin, Vector3 &boxmax); 
    176177  void SetOffset(int offset) { traversalClass->SetOffset(offset); } 
    177   int FindNearestI_16oneDir(SimpleRayContainer &rays) { 
    178     return traversalClass->FindNearestI_16oneDir(rays); 
    179   } 
    180   int FindNearestI_16oneDir(SimpleRayContainer &rays, int offset) { 
    181     return traversalClass->FindNearestI_16oneDir(rays, offset); 
     178  int FindNearestI_16oneDir(SimpleRayContainer &rays, int offset, int copyOffset) { 
     179    return traversalClass->FindNearestI_16oneDir(rays, offset, copyOffset); 
     180  } 
     181  int FindNearestI_16oneDirNoSSE(SimpleRayContainer &rays, int offset) { 
     182    return traversalClass->FindNearestI_16oneDirNoSSE(rays, offset); 
    182183  } 
    183184  int FindNearestI_16twoDir(SimpleRayContainer &rays) { 
     
    186187   
    187188#ifdef __SSE__ 
     189#ifdef _USE_HAVRAN_SSE   
    188190  // The same operations for packets of rays, if implemented by 
    189191  // a particular ASDS, otherwise it is emulated by decomposition 
     
    191193  void FindNearestI(RayPacket2x2 &raypack); 
    192194  void FindNearestI(RayPacket2x2 &raypack, Vector3 &boxmin, Vector3 &boxmax); 
     195#endif 
    193196#else 
    194197  void FindNearestI(RayPacket2x2 &raypack) { } 
     
    199202  void ExportBinLeaf(OUT_STREAM &stream, SKTBNodeT *leaf); 
    200203  SKTBNodeT* ImportBinLeaf(IN_STREAM &stream,  
    201                            SKTBNodeT *parent, 
     204                           SKTBNodeT **nodeToLink, 
    202205                           const ObjectContainer &objects); 
     206 
    203207  void ExportBinInterior(OUT_STREAM &stream, SKTBNodeT *interior); 
    204   SKTBNodeT* ImportBinInterior(IN_STREAM  &stream, 
    205                                SKTBNodeT *parent);   
     208  SKTBNodeT *ImportBinInterior(IN_STREAM  &stream, 
     209                               SKTBNodeT **nodeToLink);   
     210 
     211  SKTBNodeT * ImportNextNode(IN_STREAM &stream,  
     212                             SKTBNodeT **nodeToLink, 
     213                             const ObjectContainer &objects); 
     214 
    206215  bool ExportBinTree(const string &filename); 
     216  bool ImportBinTree(const string &filename, ObjectContainer &objects); 
     217 
    207218   
    208219protected:   
     
    211222  int sizeBuffer, size1D; 
    212223  void AllocBuffer(int size2D, int size1Dv); 
     224 
     225  struct STraversalData 
     226  {   
     227    SKTBNodeT *mNode; 
     228    int        dir; 
     229    int        depth; 
     230    STraversalData() {} 
     231 
     232    STraversalData(SKTBNodeT *n): mNode(n) 
     233    { } 
     234     
     235    STraversalData(SKTBNodeT *n, int ndir, int ndepth): 
     236      mNode(n), dir(ndir), depth(ndepth) { } 
     237  }; 
    213238}; 
    214239 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktbconf.h

    r2582 r2592  
    2222#include <xmmintrin.h> 
    2323#endif 
     24 
     25// If we support the use of SSE instructions for ray shooting 
     26#define _USE_HAVRAN_SSE 
    2427 
    2528namespace GtpVisibilityPreprocessor { 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktbftrav.cpp

    r2583 r2592  
    2020#ifdef TRV00F 
    2121 
    22 #if 0 
    23 // the depth of traversal when kd-trees are nested. The global (the highest 
    24 // level) kd-tree is at the depth 0. 
    25 int 
    26 CKTBTraversal::traversalDepth = 0; 
    27  
    28 // sets the stack pointers that are used for the traversal. 
    29 void 
    30 CKTBTraversal::GetStackPointers(struct SStackElem *&entryPointer, 
    31                                 struct SStackElem *&exitPointer) 
    32 { 
    33   assert(traversalDepth < MAX_NESTING); 
    34    
    35   int index = traversalDepth * MAX_HEIGHT; 
    36   entryPointer = &(stack[index]); 
    37   exitPointer = &(stack[index + 1]); 
    38  
    39   traversalDepth++;   
    40   return; 
    41 } 
    42  
    43 // sets the stack pointers that are used for the traversal. 
    44 void 
    45 CKTBTraversal::RestoreStackPointers() 
    46 { 
    47   assert(traversalDepth >= 0); 
    48   traversalDepth--;   
    49   return; 
    50 } 
    51  
    52  
    53 // default constructor 
    54 CKTBTraversal::CKTBTraversal() 
    55 { 
    56   bbox = AxisAlignedBox3(Vector3(MAXFLOAT), 
    57                          Vector3(-MAXFLOAT)); 
    58   root = 0; 
    59   epsilon = 0; 
    60  
    61 #ifdef __TRAVERSAL_STATISTICS 
    62   _allNodesTraversed = 0L; 
    63   _fullLeavesTraversed = 0L; 
    64   _emptyLeavesTraversed = 0L; 
    65 #endif 
    66 } 
    67    
    68 // Here we find the node (preferably minbox node) containing 
    69 // the point 
    70 const SKTBNodeT* 
    71 CKTBTraversal::Locate(const Vector3 &position) 
    72 { 
    73   const SKTBNodeT *current, *next = root; 
    74   const SKTBNodeT *returnNode = 0; 
    75  
    76   do { 
    77     current = next; 
    78     switch (GetNodeType(current)) { 
    79       // ------------------------------------------------- 
    80       case CKTBAxes::EE_X_axis: { 
    81         if (position[CKTBAxes::EE_X_axis] < current->splitPlane) 
    82           next =  GetLeft(current); 
    83         else 
    84           next = GetRight(current); 
    85         break; 
    86       } 
    87       case CKTBAxes::EE_Y_axis: { 
    88         if (position[CKTBAxes::EE_Y_axis] < current->splitPlane) 
    89           next =  GetLeft(current); 
    90         else 
    91           next = GetRight(current); 
    92         break; 
    93       } 
    94       case CKTBAxes::EE_Z_axis: { 
    95         if (position[CKTBAxes::EE_Z_axis] < current->splitPlane) 
    96           next =  GetLeft(current); 
    97         else 
    98           next = GetRight(current); 
    99         break; 
    100       } 
    101       case CKTBAxes::EE_X_axisBox: { 
    102         if (position[CKTBAxes::EE_X_axis] < current->splitPlane) 
    103           next =  GetLeft(current); 
    104         else 
    105           next = GetRight(current); 
    106         returnNode = current; 
    107         break; 
    108       } 
    109       case CKTBAxes::EE_Y_axisBox: { 
    110         if (position[CKTBAxes::EE_Y_axis] < current->splitPlane) 
    111           next =  GetLeft(current); 
    112         else 
    113           next = GetRight(current); 
    114         returnNode = current; 
    115         break; 
    116       } 
    117       case CKTBAxes::EE_Z_axisBox: { 
    118         if (position[CKTBAxes::EE_Z_axis] < current->splitPlane) 
    119           next =  GetLeft(current); 
    120         else 
    121           next = GetRight(current); 
    122         returnNode = current; 
    123         break; 
    124       } 
    125       case CKTBAxes::EE_Leaf: { 
    126         next = 0; // finishing 
    127         break; 
    128       } 
    129       case CKTBAxes::EE_Link:{ 
    130         next = GetLinkNode(current); 
    131         // cout << "Link node was accessed" << endl; 
    132         break; 
    133       } 
    134     } // switch 
    135   } 
    136   while (next != NULL); 
    137  
    138   if (returnNode) 
    139     return returnNode; 
    140  
    141   // return the last (leaf node) visited on the path 
    142   return current; 
    143 } 
    144 #endif 
    145    
    146    
    147 #if 1 
     22// -------------------------------------------------------------- 
     23// Shooting a single ray without SSE 
    14824int 
    14925CKTBTraversal::FindNearestI(const SimpleRay &ray) 
     
    16238  // passing through parameters 
    16339  float tmin, tmax; 
     40  SimpleRay::IntersectionRes[0].intersectable = 0; 
    16441   
    16542  // test if the whole CKTB tree is missed by the input ray 
    16643  if ( (!root) || 
    16744       (!bbox.ComputeMinMaxT(ray.mOrigin, ray.mDirection, &tmin, &tmax)) || 
    168        (tmax <= tmin) || 
     45       (tmax < tmin) || 
    16946       (tmax <= 0.f) ) { 
    170     SimpleRay::IntersectionRes[0].intersectable = 0; 
    17147    return 0; // no object can be intersected 
    17248  } 
     
    18561 
    18662  Vector3 invertedDir; 
    187   invertedDir.x = 1.0f / ray.mDirection.x; 
    188   invertedDir.y = 1.0f / ray.mDirection.y; 
    189   invertedDir.z = 1.0f / ray.mDirection.z; 
     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); 
    19066   
    19167  // start from the root node 
     
    21692    } 
    21793#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; 
    218105     
    219     assert(tmin <= tmax); 
    220      
    221 #ifdef __TRAVERSAL_STATISTICS 
    222     allNodesTraversed++; 
    223 #endif // __TRAVERSAL_STATISTICS 
    224     register const int nodeType = GetNodeType(currNode); 
    225          
    226106    if (nodeType < CKTBAxes::EE_Leaf) { 
    227107      float tval = (GetSplitValue(currNode) - ray.mOrigin[nodeType]); 
     
    265145          // test the objects in the full leaf against the ray 
    266146           
    267           SimpleRay::IntersectionRes[0].maxt = stack3[index].tmax; 
     147          SimpleRay::IntersectionRes[0].maxt = 
     148            stack3[index].tmax + Limits::Small; 
    268149#if 0 
    269150          // using subroutine 
     
    320201        cout << "Link " << endl; 
    321202#endif 
    322         stack3[index].nodep = GetLinkNode(currNode); 
    323203        // cout << "Link node was accessed" << endl; 
    324         continue; 
     204        currNode = GetLinkNode(currNode); 
     205        goto CONTINUE_LINK; 
    325206      } 
    326207    } 
     
    336217  return 0; 
    337218} // FindNearestI - single ray 
    338 #endif 
    339  
    340 #if 1 
     219 
     220 
     221// Shooting a single ray without SSE with prespecified box of the scene, assuming 
     222// to be contained in the scene box!!! 
    341223int 
    342224CKTBTraversal::FindNearestI(const SimpleRay &ray, const AxisAlignedBox3 &localbox) 
     
    355237  // passing through parameters 
    356238  float tmin, tmax; 
     239  SimpleRay::IntersectionRes[0].intersectable = 0; 
    357240   
    358241  // test if the whole CKTB tree is missed by the input ray 
     
    361244       (tmax <= tmin) || 
    362245       (tmax <= 0.f) ) { 
    363     SimpleRay::IntersectionRes[0].intersectable = 0; 
    364246    return 0; // no object can be intersected 
    365247  } 
     
    378260 
    379261  Vector3 invertedDir; 
    380   invertedDir.x = 1.0f / ray.mDirection.x; 
    381   invertedDir.y = 1.0f / ray.mDirection.y; 
    382   invertedDir.z = 1.0f / ray.mDirection.z; 
     262  invertedDir.x = 1.0f / (ray.mDirection.x - 1e-25f); 
     263  invertedDir.y = 1.0f / (ray.mDirection.y - 1e-25f); 
     264  invertedDir.z = 1.0f / (ray.mDirection.z - 1e-25f); 
    383265   
    384266  // start from the root node 
     
    409291    } 
    410292#endif 
    411      
     293         
     294CONTINUE_LINK: 
    412295    assert(tmin <= tmax); 
    413      
     296 
    414297#ifdef __TRAVERSAL_STATISTICS 
    415298    allNodesTraversed++; 
    416299#endif // __TRAVERSAL_STATISTICS 
     300 
    417301    register const int nodeType = GetNodeType(currNode); 
    418302    if (nodeType < CKTBAxes::EE_Leaf) { 
     
    457341          // test the objects in the full leaf against the ray 
    458342           
    459           SimpleRay::IntersectionRes[0].maxt = stack3[index].tmax; 
     343          SimpleRay::IntersectionRes[0].maxt = 
     344            stack3[index].tmax + Limits::Small; 
    460345#if 0 
    461346          // using subroutine 
     
    512397        cout << "Link " << endl; 
    513398#endif 
    514         stack3[index].nodep = GetLinkNode(currNode); 
    515399        // cout << "Link node was accessed" << endl; 
    516         continue; 
     400        currNode = GetLinkNode(currNode); 
     401        goto CONTINUE_LINK; 
    517402      } 
    518403    } 
     
    528413  return 0; 
    529414} // FindNearestI - single ray 
    530 #endif 
    531    
    532  
    533 // --------------------------------------------------------------------------- 
    534 // This is an attempt using SSE instructions - not successfull 31/12/2007 
    535 #if 0 
    536 int 
    537 CKTBTraversal::FindNearestI(const SimpleRay &ray) 
    538 { 
    539 #if 0 
    540   static int counter = 0; 
    541   counter++; 
    542   bool debug = false; 
    543   if (counter == 530) { 
    544     debug = true; 
    545     cout << "COUNTER = " << counter << endl; 
    546     cout << "DEBUG starts" << endl;     
    547   } 
    548 #endif 
    549    
    550   // passing through parameters 
    551   float tmin, tmax; 
    552    
    553   // test if the whole CKTB tree is missed by the input ray 
    554   if ( (!root) || 
    555        (!bbox.ComputeMinMaxT(ray.mOrigin, ray.mDirection, &tmin, &tmax)) || 
    556        (tmax <= tmin) || 
    557        (tmax <= 0.f) ) { 
    558     SimpleRay::IntersectionRes[0].intersectable = 0; 
    559     return 0; // no object can be intersected 
    560   } 
    561  
    562 //#define _DEBUGKTB 
    563 #ifdef _DEBUGKTB 
    564   int ib = 0; 
    565   int depth = 0;  
    566 #endif 
    567    
    568 #ifdef __TRAVERSAL_STATISTICS 
    569   int allNodesTraversed = 0L; 
    570   int fullLeavesTraversed = 0L; 
    571   int emptyLeavesTraversed = 0L; 
    572 #endif // __TRAVERSAL_STATISTICS 
    573  
    574   Vector3 invertedDir; 
    575   invertedDir.x = 1.0f / ray.mDirection.x; 
    576   invertedDir.y = 1.0f / ray.mDirection.y; 
    577   invertedDir.z = 1.0f / ray.mDirection.z; 
    578    
    579   // start from the root node 
    580   if (tmin < 0.f) 
    581     tmin = 0.f; 
    582  
    583   int index = 1; 
    584   stack3[1].nodep = root; 
    585   stack3[1].tmax = tmax; 
    586   tmax = tmin; 
    587   SKTBNodeT * childNodes[2]; 
    588   int RayDirs[3]; 
    589   RayDirs[0] = ray.mDirection.x < 0.f ? 1 : 0; 
    590   RayDirs[1] = ray.mDirection.y < 0.f ? 1 : 0; 
    591   RayDirs[2] = ray.mDirection.z < 0.f ? 1 : 0; 
    592    
    593   // we have to check the node 
    594   // current node is not the leaf, empty leaves are NULL pointers 
    595   while (index) { 
    596     SKTBNodeT *currNode = stack3[index].nodep; 
    597     tmin = tmax; 
    598     tmax = stack3[index].tmax; 
    599 #if 0 
    600     if (debug) { 
    601       cout << "node = " << (void*)currNode 
    602            << " tmin = " << tmin << " tmax = " << tmax 
    603            << endl; 
    604     } 
    605 #endif 
    606      
    607     assert(tmin <= tmax); 
    608      
    609 #ifdef __TRAVERSAL_STATISTICS 
    610     allNodesTraversed++; 
    611 #endif // __TRAVERSAL_STATISTICS 
    612     const unsigned int nodeType = GetNodeType(currNode); 
    613     if (nodeType < CKTBAxes::EE_Leaf) { 
    614       float tval = (GetSplitValue(currNode) - ray.mOrigin[nodeType]); 
    615       tval *= invertedDir[nodeType]; 
    616       SKTBNodeT *near, *far; 
    617       childNodes[0] = GetLeft(currNode); 
    618       childNodes[1] = GetRight(currNode); 
    619       int rayDir = RayDirs[nodeType]; 
    620       near = childNodes[rayDir]; 
    621       far = childNodes[rayDir ^ 0x1]; 
    622       // This code is slower than above !!!!! 
    623       stack3[index].nodep = far; 
    624       // stack3[index].tmax = tmax; // this is already there, not necessary! 
    625       __m128 tsim = _mm_set_ss(tval); 
    626       // index += tval < tmax ? 1 : 0; 
    627       __m128 tother = _mm_set_ss(tmax); 
    628       index += _mm_ucomilt_ss(tsim, tother); 
    629       stack3[index].nodep = near; 
    630       // stack3[index].tmax = Min(tval, tmax); 
    631       _mm_store_ss(&(stack3[index].tmax), _mm_min_ps(tsim, tother)); 
    632       tmax = tmin; 
    633       // index += tval < tmin ? -1 : 0; 
    634       __m128 tother2 = _mm_set_ss(tmin); 
    635       index -= _mm_ucomilt_ss(tsim, tother2); 
    636     } 
    637     else { 
    638       if (nodeType == CKTBAxes::EE_Leaf) { 
    639         // test objects for intersection 
    640 #ifdef _DEBUGKTB 
    641         cout << "Leaf " << endl; 
    642         depth++; 
    643 #endif 
    644 #ifdef _DEBUGKTB 
    645         DEBUG << "currNode = " << currNode << " entp.t = " << entp->t 
    646               << " extp.t = " << extp->t << endl; 
    647 #endif 
    648         if (!IsEmptyLeaf_(currNode)) { 
    649 #ifdef _DEBUGKTB 
    650           cout << "Full leaf at depth= " << depth << endl;  
    651 #endif       
    652  
    653 #ifdef __TRAVERSAL_STATISTICS 
    654           fullLeavesTraversed++; 
    655 #endif // __TRAVERSAL_STATISTICS 
    656           // test the objects in the full leaf against the ray 
    657            
    658           SimpleRay::IntersectionRes[0].maxt = stack3[index].tmax; 
    659           if (TestFullLeaf(ray, currNode)) { 
    660 #ifdef _DEBUGKTB 
    661             cout << "Full leaf HIT " << endl;  
    662 #endif   
    663                
    664 #ifdef __TRAVERSAL_STATISTICS 
    665             _allNodesTraversed += allNodesTraversed; 
    666             _fullLeavesTraversed += fullLeavesTraversed; 
    667             _emptyLeavesTraversed += emptyLeavesTraversed; 
    668 #endif // __TRAVERSAL_STATISTICS 
    669              
    670             // signed distance should be already set in TestFullLeaf 
    671             // the first object intersected was found    
    672             return 1; 
    673           } 
    674         } // full leaf 
    675 #ifdef __TRAVERSAL_STATISTICS 
    676         else { 
    677 #ifdef _DEBUGKTB 
    678           cout << "Empty leaf at depth= " << depth << endl;  
    679 #endif       
    680           emptyLeavesTraversed++; 
    681         } 
    682 #endif // __TRAVERSAL_STATISTICS 
    683  
    684 #ifdef _DEBUGKTB 
    685         cout << "Pop the node" << endl; 
    686 #endif       
    687      
    688         // pop farChild from the stack 
    689         // restore the current values 
    690         index--; 
    691         continue; 
    692       } 
    693       else { 
    694         assert(nodeType == CKTBAxes::EE_Link); 
    695 #ifdef _DEBUGKTB 
    696         cout << "Link " << endl; 
    697 #endif 
    698         stack3[index].nodep = GetLinkNode(currNode); 
    699         // cout << "Link node was accessed" << endl; 
    700         continue; 
    701       } 
    702     } 
    703   } // while current node is not the leaf 
    704  
    705 #ifdef __TRAVERSAL_STATISTICS 
    706   _allNodesTraversed += allNodesTraversed; 
    707   _fullLeavesTraversed += fullLeavesTraversed; 
    708   _emptyLeavesTraversed += emptyLeavesTraversed; 
    709 #endif // __TRAVERSAL_STATISTICS 
    710  
    711   // no objects found along the ray path 
    712   return 0; 
    713 } // FindNearestI - single ray 
    714 #endif 
    715  
    716 #if 0 
     415 
     416 
    717417// Reasonably fast - about 101,500 rays per second for single dir! 
    718 // It allows fast switching context from one ray to the next ray so it it 
     418// It allows fast switching context from one ray to the next ray so it is 
    719419// virtually independent of memory latency ! 
    720420int 
    721 CKTBTraversal::FindNearestI_16oneDir(SimpleRayContainer &rays, int offset) 
     421CKTBTraversal::FindNearestI_16oneDirNoSSE(SimpleRayContainer &rays, int offset) 
    722422{ 
    723423  // passing through parameters 
     
    742442  float tmin, tmax; 
    743443  for (int i = 0; i < cntMaxRays; i++) { 
    744   // test if the whole CKTB tree is missed by the input ray 
     444    // Setting zero intersection as original result 
     445    SimpleRay::IntersectionRes[i+rayOffset].intersectable = 0; 
     446    // test if the whole CKTB tree is missed by the input ray 
    745447    if ((!bbox.ComputeMinMaxT(rays[i+offset].mOrigin, 
    746448                              rays[i+offset].mDirection, 
     
    748450        (tmax <= tmin) || 
    749451        (tmax <= 0.f) ) { 
    750       SimpleRay::IntersectionRes[i].intersectable = 0; 
    751452    } 
    752453    else { 
     
    756457      rayOrig[indexR + 2] = rays[i+offset].mOrigin.z; 
    757458      //rayOrig[indexR + 3] = 0.f; 
    758       invertedDir[indexR + 0] = 1.0f / (rays[i+offset].mDirection.x); 
    759       invertedDir[indexR + 1] = 1.0f / (rays[i+offset].mDirection.y); 
    760       invertedDir[indexR + 2] = 1.0f / (rays[i+offset].mDirection.z); 
     459      invertedDir[indexR + 0] = 1.0f / (rays[i+offset].mDirection.x - 1e-25f); 
     460      invertedDir[indexR + 1] = 1.0f / (rays[i+offset].mDirection.y - 1e-25f); 
     461      invertedDir[indexR + 2] = 1.0f / (rays[i+offset].mDirection.z - 1e-25f); 
    761462      //invertedDir[indexR + 2] = 0.f; 
    762463      rayDirs[indexR + 0] = rays[i+offset].mDirection.x < 0.f ? 1 : 0; 
     
    819520      } 
    820521#endif       
    821       assert(tmin <= tmax); 
    822522     
    823523#ifdef __TRAVERSAL_STATISTICS 
     
    876576            // which ray is processed 
    877577            int indexR = indexRay[indexA]; 
    878             SimpleRay::IntersectionRes[indexR].maxt = tmax; 
     578            SimpleRay::IntersectionRes[indexR + rayOffset].maxt = 
     579              tmax + Limits::Small; 
    879580            if (TestFullLeaf(rays[indexR+offset], currNode, indexR)) { 
    880581 
     
    934635#endif 
    935636          stackA[indexSA].nodep = GetLinkNode(currNode); 
     637          GPREFETCH(stackA[indexSA].nodep, PREF_DEFAULT); 
    936638          // cout << "Link node was accessed" << endl; 
    937639          continue; 
     
    950652  return cntHits; 
    951653} 
    952 #endif 
    953  
    954 #ifdef __SSE__ 
    955  
    956 #if 1 
    957 // Even faster - about 125,500 rays per second for single dir and 164 rps 
    958 // for double dir ! 
    959 int 
    960 CKTBTraversal::FindNearestI_16oneDir(SimpleRayContainer &rays, int offset) 
    961 { 
    962   static RayPacket2x2 raypack; 
    963   struct SResultI { 
    964     Intersectable *intersectable; 
    965     float          tdist;     
    966   }; 
    967   static SResultI results[16]; 
    968      
    969   for (int i = 0; i < 4; i++) { 
    970     int k = i * 4 + offset; 
    971     for (int j = 0; j < 4; j++, k++) { 
    972       raypack.SetLoc(j, rays[k].mOrigin); 
    973       raypack.SetDir(j, rays[k].mDirection);       
    974     } 
    975     // Here either use ray packet traversal or 
    976     // casting individual rays 
    977     FindNearestI(raypack); 
    978     k = i * 4; 
    979     for (int j = 0; j < 4; j++, k++) { 
    980       results[k].intersectable = raypack.GetObject(j); 
    981       results[k].tdist = raypack.GetT(j); 
    982     } // for j 
    983   } // for i 
    984  
    985   // Copy the results to the output array 
    986   for (int i = 0; i < 16; i++) { 
    987     SimpleRay::IntersectionRes[i].intersectable = 
    988       results[i].intersectable; 
    989     SimpleRay::IntersectionRes[i].tdist = 
    990       results[i].tdist; 
    991   } // for i 
    992   return 0; 
    993 } 
    994 #endif 
    995    
    996 #if 0 
    997 // This code works well 1/1/2008 - 11:00 
    998 // The same operations for packets of rays for the same signs, 
    999 // otherwise it is emulated by decomposition 
    1000 // of a packet to individual rays and traced individually. 
    1001 void 
    1002 CKTBTraversal::FindNearestI(RayPacket2x2 &rp) 
    1003 { 
    1004   int m1 = _mm_movemask_ps(rp.dx4); 
    1005   if ((m1 == 0)||(m1 == 15)) { 
    1006   m1 = _mm_movemask_ps(rp.dy4); 
    1007   if ((m1 == 0)||(m1 == 15)) { 
    1008   m1 = _mm_movemask_ps(rp.dz4); 
    1009   if ((m1 == 0)||(m1 == 15)) { 
    1010     rp.Init(); 
    1011     // all the signs for 4 rays are the same, use 
    1012     // ray packet traversal 
    1013     // Compute min and max distances 
    1014     GALIGN16 union { float tmin4[4]; __m128 tmin_4; }; 
    1015     GALIGN16 union { float tmax4[4]; __m128 tmax_4; }; 
    1016     SimpleRay sray[4]; 
    1017     int maxIntersections = 4; 
    1018     GALIGN16 union { int inters[4]; __m128 inters_4; }; 
    1019     inters[0] = inters[1] = inters[2] = inters[3] = 1; 
    1020     unsigned int inters32 = 0xf; 
    1021     for (int i = 0; i < 4; i++) { 
    1022       bbox.ComputeMinMaxT(rp.GetLoc(i), rp.GetDir(i), &(tmin4[i]), &(tmax4[i])); 
    1023       if ( (tmin4[i] >= tmax4[i]) || 
    1024            (tmax4[i] < 0.f) ) { 
    1025         inters[i] = 0; // finished 
    1026         inters32 &= ~(1 << i); // bit zero when ray is invalid 
    1027         maxIntersections--; 
    1028       }       
    1029       if (tmin4[i] < 0.f) 
    1030         tmin4[i] = 0.f; 
    1031       sray[i].mOrigin = rp.GetLoc(i); 
    1032       sray[i].mDirection = rp.GetDir(i); 
    1033     } // for i 
    1034     if (maxIntersections == 0) 
    1035       return; 
    1036  
    1037     SKTBNodeT * childNodes[2]; 
    1038     int RayDirs[3]; 
    1039     RayDirs[0] = (rp.dx[0] > 0.f) ? 1 : 0; 
    1040     RayDirs[1] = (rp.dy[0] > 0.f) ? 1 : 0; 
    1041     RayDirs[2] = (rp.dz[0] > 0.f) ? 1 : 0; 
    1042     //int activeMask=_mm_movemask_ps(_mm_cmplt_ps( tmin_4, tmax_4 ))&inters32; 
    1043     int activeMask = inters32; 
    1044     int indexStack = 0; 
    1045     SKTBNodeT *currNode = root; 
    1046     unsigned int k = GetNodeType(currNode); 
    1047     for (;;) {       
    1048       while (k < CKTBAxes::EE_Leaf) { 
    1049         // the 3 operations below can be brought down to 3 simple float 
    1050         // calculations by precomputing min/max of the inverse dir 
    1051         const __m128 node_split = _mm_set_ps1(GetSplitValue(currNode)); 
    1052         const __m128 t4 = 
    1053           _mm_mul_ps(_mm_sub_ps(node_split, rp.orig[k]), rp.idir[k]); 
    1054         childNodes[0] = GetLeft(currNode); 
    1055         childNodes[1] = GetRight(currNode); 
    1056         int rayDir = RayDirs[k]; 
    1057         SKTBNodeT *far = childNodes[rayDir]; 
    1058         if (!(_mm_movemask_ps(_mm_cmpgt_ps(t4, tmin_4)) & activeMask)) 
    1059         { 
    1060           currNode = far; 
    1061           k = GetNodeType(currNode); 
    1062           continue; 
    1063         } 
    1064         currNode = childNodes[rayDir ^ 0x1]; // this is near node 
    1065         k = GetNodeType(currNode);       
    1066         if (! (_mm_movemask_ps(_mm_cmplt_ps( t4, tmax_4)) & activeMask)) 
    1067           continue; 
    1068  
    1069         // pop far node to the stack 
    1070         stack4[indexStack].nodep = far; 
    1071         stack4[indexStack].tmax_4 = tmax_4; 
    1072         stack4[indexStack].tmin_4 = _mm_max_ps(t4, tmin_4); 
    1073         // stack4[indexStack].mask = activeMask; 
    1074         indexStack++; 
    1075          
    1076         tmax_4 = _mm_min_ps(t4, tmax_4);  
    1077         activeMask &= _mm_movemask_ps(_mm_cmplt_ps( tmin_4, tmax_4 )); 
    1078       } // while this is an interior node 
    1079  
    1080       // either a leaf or a link 
    1081       if (k == CKTBAxes::EE_Leaf) { 
    1082         // test objects for intersection 
    1083         if (!IsEmptyLeaf_(currNode)) { 
    1084           // cout << "Full leaf" << endl; 
    1085            
    1086           // test the objects in the full leaf against the ray     
    1087           for (int i = 0; i < 4; i++) { 
    1088             if (inters[i] ) { 
    1089               // no intersection so far ! 
    1090               SimpleRay::IntersectionRes[i].maxt = tmax4[i]; 
    1091               // Test only rays that were not finished 
    1092               if (TestFullLeaf(sray[i], currNode, i)) { 
    1093                 // intersection for this ray found 
    1094                 inters[i] = 0; 
    1095                 inters32 &= ~(1 << i); 
    1096                 rp.SetT(i, SimpleRay::IntersectionRes[0].maxt); 
    1097                 rp.SetObject(i, SimpleRay::IntersectionRes[0].intersectable);            
    1098                 // signed distance should be already set in TestFullLeaf 
    1099                 // the first object intersected was found 
    1100                 if (--maxIntersections == 0) 
    1101                   return; 
    1102               } 
    1103             } // if this ray did not hit the triangle so far 
    1104           } // for all 4 rays 
    1105         } // full leaf 
    1106         // pop farChild from the stack 
    1107         // restore the current values 
    1108         // update the minimum distance since we traverse to the next one 
    1109  
    1110         if (indexStack == 0) 
    1111           return; 
    1112         indexStack--; 
    1113         currNode = stack4[indexStack].nodep; 
    1114         k = GetNodeType(currNode); 
    1115         tmin_4 = stack4[indexStack].tmin_4; 
    1116         tmax_4 = stack4[indexStack].tmax_4; 
    1117         activeMask = _mm_movemask_ps(_mm_cmple_ps( tmin_4, tmax_4 )) & inters32; 
    1118         continue; 
    1119       } 
    1120       // cout << "Link node was accessed" << endl; 
    1121       assert(k == CKTBAxes::EE_Link); 
    1122       currNode = GetLinkNode(currNode); 
    1123       k = GetNodeType(currNode); 
    1124     } // for 
    1125     return; 
    1126   }}} 
    1127  
    1128   // Trace ray by ray 
    1129   SimpleRay ray; 
    1130   for (int i = 0; i < 4; i++) { 
    1131     ray.mOrigin = rp.GetLoc(i); 
    1132     ray.mDirection = rp.GetDir(i); 
    1133     FindNearestI(ray); 
    1134     rp.SetObject(i, SimpleRay::IntersectionRes[0].intersectable); 
    1135     rp.SetT(i, SimpleRay::IntersectionRes[0].tdist); 
    1136     // SimpleRay::IntersectionRes[0].intersectable->GetNormal(0); 
    1137   } // for 
    1138 } 
    1139 #endif 
    1140  
    1141  
    1142 #if 1 
    1143 // This code also works well 1/1/2008 - 14:00 
    1144 // Using mask of 128-bits width - the code works as well, only a bit 
    1145 // faster than the code above 
    1146 void 
    1147 CKTBTraversal::FindNearestI(RayPacket2x2 &rp) 
    1148 { 
    1149   int m1 = _mm_movemask_ps(rp.dx4); 
    1150   if ((m1 == 0)||(m1 == 15)) { 
    1151   m1 = _mm_movemask_ps(rp.dy4); 
    1152   if ((m1 == 0)||(m1 == 15)) { 
    1153   m1 = _mm_movemask_ps(rp.dz4); 
    1154   if ((m1 == 0)||(m1 == 15)) { 
    1155     rp.Init(); 
    1156     // all the signs for 4 rays are the same, use 
    1157     // ray packet traversal 
    1158     // Compute min and max distances 
    1159     GALIGN16 union { float tmin4[4]; __m128 tmin_4; }; 
    1160     GALIGN16 union { float tmax4[4]; __m128 tmax_4; }; 
    1161     GALIGN16 union { float activeMask[4]; __m128 activeMask_4; }; 
    1162     GALIGN16 union { float liveMask[4]; __m128 liveMask_4; }; 
    1163     liveMask[0] = liveMask[1] = liveMask[2] = liveMask[3] = 0xffffffff; 
    1164  
    1165     GALIGN16 SimpleRay sray[4]; 
    1166     int maxIntersections = 4; 
    1167     // unsigned int inters32 = 0xf; 
    1168     for (int i = 0; i < 4; i++) { 
    1169       rp.SetObject(i, 0); 
    1170       bbox.ComputeMinMaxT(rp.GetLoc(i), rp.GetDir(i), &(tmin4[i]), &(tmax4[i])); 
    1171       if ( (tmin4[i] >= tmax4[i]) || 
    1172            (tmax4[i] < 0.f) ) { 
    1173         liveMask[i] = 0; // finished 
    1174         // inters32 &= ~(1 << i); // bit zero when ray is invalid 
    1175         maxIntersections--; 
    1176       } 
    1177       if (tmin4[i] < 0.f) 
    1178         tmin4[i] = 0.f; 
    1179       sray[i].mOrigin = rp.GetLoc(i); 
    1180       sray[i].mDirection = rp.GetDir(i); 
    1181     } // for i 
    1182     if (maxIntersections == 0) 
    1183       return; 
    1184  
    1185     // This is the mask 128 bits witdth 
    1186     //activeMask_4 = 
    1187     //  _mm_and_ps(_mm_cmple_ps(tmin_4, tmax_4), 
    1188     //           _mm_cmplt_ps(tmax_4, _mm_setzero_ps())); 
    1189     activeMask_4 = liveMask_4; 
    1190  
    1191     SKTBNodeT * childNodes[2]; 
    1192     int RayDirs[4]; 
    1193     RayDirs[0] = (rp.dx[0] > 0.f) ? 1 : 0; 
    1194     RayDirs[1] = (rp.dy[0] > 0.f) ? 1 : 0; 
    1195     RayDirs[2] = (rp.dz[0] > 0.f) ? 1 : 0; 
    1196     int indexStack = 0; 
    1197     SKTBNodeT *currNode = root; 
    1198     unsigned int k = GetNodeType(currNode); 
    1199     for (;;) { 
    1200       // traverse until we find a leaf 
    1201       while (k < CKTBAxes::EE_Leaf) { 
    1202         // the 3 operations below can be brought down to 3 simple float 
    1203         // calculations by precomputing min/max of the inverse dir 
    1204         // const __m128 node_split = ; 
    1205         const __m128 t4 = 
    1206           _mm_mul_ps(_mm_sub_ps(_mm_set_ps1(GetSplitValue(currNode)), 
    1207                                 rp.orig[k]), rp.idir[k]); 
    1208         childNodes[0] = GetLeft(currNode); 
    1209         childNodes[1] = GetRight(currNode); 
    1210         int rayDir = RayDirs[k]; 
    1211         SKTBNodeT *far = childNodes[rayDir]; 
    1212         if (_mm_movemask_ps(_mm_and_ps(_mm_cmpge_ps(t4, tmin_4), 
    1213                                        activeMask_4))) {           
    1214           currNode = far; 
    1215           k = GetNodeType(currNode); 
    1216           continue; 
    1217         } 
    1218  
    1219         currNode = childNodes[rayDir ^ 0x1]; // this is near node 
    1220         k = GetNodeType(currNode);       
    1221         if (_mm_movemask_ps(_mm_and_ps(_mm_cmple_ps(t4, tmax_4), 
    1222                                        activeMask_4))) 
    1223           continue; 
    1224  
    1225         // pop far node to the stack 
    1226         stack4[indexStack].nodep = far; 
    1227         stack4[indexStack].tmax_4 = tmax_4; 
    1228  
    1229 // Uncomenting this macro is unsafe! 
    1230 // Not convinced if for packet of 4 rays we can say that since when 
    1231 // one ray is different than the others, it could bring to wrong state 
    1232 // It is surely true for one ray when tmin < t < tmax, but for a packet 
    1233 // of rays this condition can be true only for a single ray 
    1234 //   tmin4 = max(t4, tmin4) = min(t4, tmax4) 
    1235 //#define _NOT_STORE_MINT 
    1236  
    1237 #ifdef _NOT_STORE_MINT   
    1238 #else 
    1239         // store mint onto the stack 
    1240         stack4[indexStack].tmin_4 = _mm_max_ps(t4, tmin_4); 
    1241 #endif   
    1242         // stack4[indexStack].mask = activeMask; 
    1243         indexStack++; 
    1244          
    1245         tmax_4 = _mm_min_ps(t4, tmax_4);  
    1246         activeMask_4 = _mm_cmplt_ps( tmin_4, tmax_4 ); 
    1247       } // while this is an interior node 
    1248  
    1249       // either a leaf or a link 
    1250       if (k == CKTBAxes::EE_Leaf) { 
    1251         // test objects for intersection 
    1252         if (!IsEmptyLeaf_(currNode)) { 
    1253           // cout << "Full leaf" << endl; 
    1254            
    1255           // test the objects in the full leaf against the ray     
    1256           for (int i = 0; i < 4; i++) { 
    1257             if (liveMask[i] ) { 
    1258               // no intersection so far ! 
    1259               SimpleRay::IntersectionRes[i].maxt = tmax4[i]; 
    1260 #if 0 
    1261               // Using subroutine 
    1262               // Test only rays that were not finished 
    1263               if (TestFullLeaf(sray[i], currNode, i)) 
    1264 #else 
    1265               // avoiding one call 
    1266               const ObjectContainer * const list = GetObjList(currNode);  
    1267               int intersected = 0; 
    1268               // iterate the whole list and find out the nearest intersection 
    1269               ObjectContainer::const_iterator sc_end = list->end(); 
    1270               for (ObjectContainer::const_iterator sc = list->begin(); sc != sc_end; sc++) { 
    1271                 // if the intersection realy lies in the node         
    1272                 intersected |= ((*sc)->CastSimpleRay(sray[i], i)); 
    1273               } // for all objects 
    1274               if (intersected) 
    1275 #endif 
    1276               { 
    1277                 rp.SetT(i, SimpleRay::IntersectionRes[0].maxt); 
    1278                 rp.SetObject(i, SimpleRay::IntersectionRes[0].intersectable); 
    1279                 // signed distance should be already set in TestFullLeaf 
    1280                 // the first object intersected was found 
    1281                 if (--maxIntersections == 0) 
    1282                   return; 
    1283                 // inters32 &= ~(1 << i); 
    1284                 liveMask[i] = 0; 
    1285               } 
    1286             } // if this ray did not hit the triangle so far 
    1287           } // for all 4 rays 
    1288         } // full leaf 
    1289  
    1290         // pop farChild from the stack 
    1291         // restore the current values 
    1292         // update the minimum distance since we traverse to the next one 
    1293         do { 
    1294           if (indexStack == 0) 
    1295             return; 
    1296           indexStack--; 
    1297           currNode = stack4[indexStack].nodep; 
    1298           k = GetNodeType(currNode); 
    1299 #ifdef _NOT_STORE_MINT 
    1300           // this is an attempt ! 
    1301           tmin_4 = tmax_4; 
    1302 #else 
    1303           // This surrely works 
    1304           tmin_4 = stack4[indexStack].tmin_4; 
    1305 #endif     
    1306           tmax_4 = stack4[indexStack].tmax_4; 
    1307           activeMask_4 = _mm_and_ps(_mm_cmple_ps( tmin_4, tmax_4 ), liveMask_4); 
    1308         } 
    1309         while (_mm_movemask_ps(activeMask_4) == 0); 
    1310       } 
    1311       else { 
    1312         // cout << "Link node was accessed" << endl; 
    1313         assert(k == CKTBAxes::EE_Link); 
    1314         currNode = GetLinkNode(currNode); 
    1315         k = GetNodeType(currNode); 
    1316       } 
    1317     } // for(;;) 
    1318     return; 
    1319   }}} 
    1320  
    1321   // Trace ray by ray 
    1322   SimpleRay ray; 
    1323   for (int i = 0; i < 4; i++) { 
    1324     ray.mOrigin = rp.GetLoc(i); 
    1325     ray.mDirection = rp.GetDir(i); 
    1326     FindNearestI(ray); 
    1327     rp.SetObject(i, SimpleRay::IntersectionRes[0].intersectable); 
    1328     rp.SetT(i, SimpleRay::IntersectionRes[0].tdist); 
    1329     // SimpleRay::IntersectionRes[0].intersectable->GetNormal(0); 
    1330   } // for 
    1331 } 
    1332 #endif 
    1333  
    1334 #if 1 
    1335 // This code also works well 1/1/2008 - 14:00 
    1336 // Using mask of 128-bits width - the code works as well, only a bit 
    1337 // faster than the code above 
    1338 void 
    1339 CKTBTraversal::FindNearestI(RayPacket2x2 &rp, Vector3 &boxmin, Vector3 &boxmax) 
    1340 { 
    1341  
    1342   static AxisAlignedBox3 localbox; 
    1343   localbox.SetMin(boxmin); 
    1344   localbox.SetMax(boxmax); 
    1345  
    1346 #define USE_SIMPLE_VERSION 1 
    1347  
    1348 #if !USE_SIMPLE_VERSION 
    1349   int m1 = _mm_movemask_ps(rp.dx4); 
    1350   if ((m1 == 0)||(m1 == 15)) { 
    1351   m1 = _mm_movemask_ps(rp.dy4); 
    1352   if ((m1 == 0)||(m1 == 15)) { 
    1353   m1 = _mm_movemask_ps(rp.dz4); 
    1354   if ((m1 == 0)||(m1 == 15)) { 
    1355     rp.Init(); 
    1356      
    1357     // all the signs for 4 rays are the same, use 
    1358     // ray packet traversal 
    1359     // Compute min and max distances 
    1360     GALIGN16 union { float tmin4[4]; __m128 tmin_4; }; 
    1361     GALIGN16 union { float tmax4[4]; __m128 tmax_4; }; 
    1362     GALIGN16 union { float activeMask[4]; __m128 activeMask_4; }; 
    1363     GALIGN16 union { float liveMask[4]; __m128 liveMask_4; }; 
    1364     liveMask[0] = liveMask[1] = liveMask[2] = liveMask[3] = 0xffffffff; 
    1365  
    1366     GALIGN16 SimpleRay sray[4]; 
    1367     int maxIntersections = 4; 
    1368     // unsigned int inters32 = 0xf; 
    1369     for (int i = 0; i < 4; i++) { 
    1370       rp.SetObject(i, 0); 
    1371       localbox.ComputeMinMaxT(rp.GetLoc(i), rp.GetDir(i), &(tmin4[i]), &(tmax4[i])); 
    1372       if ( (tmin4[i] >= tmax4[i]) || 
    1373            (tmax4[i] < 0.f) ) { 
    1374         liveMask[i] = 0; // finished 
    1375         // inters32 &= ~(1 << i); // bit zero when ray is invalid 
    1376         maxIntersections--; 
    1377       } 
    1378       if (tmin4[i] < 0.f) 
    1379         tmin4[i] = 0.f; 
    1380       sray[i].mOrigin = rp.GetLoc(i); 
    1381       sray[i].mDirection = rp.GetDir(i); 
    1382     } // for i 
    1383     if (maxIntersections == 0) 
    1384       return; 
    1385  
    1386     // This is the mask 128 bits witdth 
    1387     //activeMask_4 = 
    1388     //  _mm_and_ps(_mm_cmple_ps(tmin_4, tmax_4), 
    1389     //           _mm_cmplt_ps(tmax_4, _mm_setzero_ps())); 
    1390     activeMask_4 = liveMask_4; 
    1391  
    1392     SKTBNodeT * childNodes[2]; 
    1393     int RayDirs[4]; 
    1394     RayDirs[0] = (rp.dx[0] > 0.f) ? 1 : 0; 
    1395     RayDirs[1] = (rp.dy[0] > 0.f) ? 1 : 0; 
    1396     RayDirs[2] = (rp.dz[0] > 0.f) ? 1 : 0; 
    1397     int indexStack = 0; 
    1398     SKTBNodeT *currNode = root; 
    1399     unsigned int k = GetNodeType(currNode); 
    1400     for (;;) { 
    1401       // traverse until we find a leaf 
    1402       while (k < CKTBAxes::EE_Leaf) { 
    1403         // the 3 operations below can be brought down to 3 simple float 
    1404         // calculations by precomputing min/max of the inverse dir 
    1405         // const __m128 node_split = ; 
    1406         const __m128 t4 = 
    1407           _mm_mul_ps(_mm_sub_ps(_mm_set_ps1(GetSplitValue(currNode)), 
    1408                                 rp.orig[k]), rp.idir[k]); 
    1409         childNodes[0] = GetLeft(currNode); 
    1410         childNodes[1] = GetRight(currNode); 
    1411         int rayDir = RayDirs[k]; 
    1412         SKTBNodeT *far = childNodes[rayDir]; 
    1413         if (_mm_movemask_ps(_mm_and_ps(_mm_cmpge_ps(t4, tmin_4), 
    1414                                        activeMask_4))) {           
    1415           currNode = far; 
    1416           k = GetNodeType(currNode); 
    1417           continue; 
    1418         } 
    1419  
    1420         currNode = childNodes[rayDir ^ 0x1]; // this is near node 
    1421         k = GetNodeType(currNode);       
    1422         if (_mm_movemask_ps(_mm_and_ps(_mm_cmple_ps(t4, tmax_4), 
    1423                                        activeMask_4))) 
    1424           continue; 
    1425  
    1426         // pop far node to the stack 
    1427         stack4[indexStack].nodep = far; 
    1428         stack4[indexStack].tmax_4 = tmax_4; 
    1429  
    1430 // Uncomenting this macro is unsafe! 
    1431 // Not convinced if for packet of 4 rays we can say that since when 
    1432 // one ray is different than the others, it could bring to wrong state 
    1433 // It is surely true for one ray when tmin < t < tmax, but for a packet 
    1434 // of rays this condition can be true only for a single ray 
    1435 //   tmin4 = max(t4, tmin4) = min(t4, tmax4) 
    1436 //#define _NOT_STORE_MINT 
    1437  
    1438 #ifdef _NOT_STORE_MINT   
    1439 #else 
    1440         // store mint onto the stack 
    1441         stack4[indexStack].tmin_4 = _mm_max_ps(t4, tmin_4); 
    1442 #endif   
    1443         // stack4[indexStack].mask = activeMask; 
    1444         indexStack++; 
    1445          
    1446         tmax_4 = _mm_min_ps(t4, tmax_4);  
    1447         activeMask_4 = _mm_cmplt_ps( tmin_4, tmax_4 ); 
    1448       } // while this is an interior node 
    1449  
    1450       // either a leaf or a link 
    1451       if (k == CKTBAxes::EE_Leaf) { 
    1452         // test objects for intersection 
    1453         if (!IsEmptyLeaf_(currNode)) { 
    1454           // cout << "Full leaf" << endl; 
    1455            
    1456           // test the objects in the full leaf against the ray     
    1457           for (int i = 0; i < 4; i++) { 
    1458             if (liveMask[i] ) { 
    1459               // no intersection so far ! 
    1460               SimpleRay::IntersectionRes[i].maxt = tmax4[i]; 
    1461 #if 0 
    1462               // Using subroutine 
    1463               // Test only rays that were not finished 
    1464               if (TestFullLeaf(sray[i], currNode, i)) 
    1465 #else 
    1466               // avoiding one call 
    1467               const ObjectContainer * const list = GetObjList(currNode);  
    1468               int intersected = 0; 
    1469               // iterate the whole list and find out the nearest intersection 
    1470               ObjectContainer::const_iterator sc_end = list->end(); 
    1471               for (ObjectContainer::const_iterator sc = list->begin(); sc != sc_end; sc++) { 
    1472                 // if the intersection realy lies in the node         
    1473                 intersected |= ((*sc)->CastSimpleRay(sray[i], i)); 
    1474               } // for all objects 
    1475               if (intersected) 
    1476 #endif 
    1477               { 
    1478                 rp.SetT(i, SimpleRay::IntersectionRes[0].maxt); 
    1479                 rp.SetObject(i, SimpleRay::IntersectionRes[0].intersectable); 
    1480                 // signed distance should be already set in TestFullLeaf 
    1481                 // the first object intersected was found 
    1482                 if (--maxIntersections == 0) 
    1483                   return; 
    1484                 // inters32 &= ~(1 << i); 
    1485                 liveMask[i] = 0; 
    1486               } 
    1487             } // if this ray did not hit the triangle so far 
    1488           } // for all 4 rays 
    1489         } // full leaf 
    1490  
    1491         // pop farChild from the stack 
    1492         // restore the current values 
    1493         // update the minimum distance since we traverse to the next one 
    1494         do { 
    1495           if (indexStack == 0) 
    1496             return; 
    1497           indexStack--; 
    1498           currNode = stack4[indexStack].nodep; 
    1499           k = GetNodeType(currNode); 
    1500 #ifdef _NOT_STORE_MINT 
    1501           // this is an attempt ! 
    1502           tmin_4 = tmax_4; 
    1503 #else 
    1504           // This surrely works 
    1505           tmin_4 = stack4[indexStack].tmin_4; 
    1506 #endif     
    1507           tmax_4 = stack4[indexStack].tmax_4; 
    1508           activeMask_4 = _mm_and_ps(_mm_cmple_ps( tmin_4, tmax_4 ), liveMask_4); 
    1509         } 
    1510         while (_mm_movemask_ps(activeMask_4) == 0); 
    1511       } 
    1512       else { 
    1513         // cout << "Link node was accessed" << endl; 
    1514         assert(k == CKTBAxes::EE_Link); 
    1515         currNode = GetLinkNode(currNode); 
    1516         k = GetNodeType(currNode); 
    1517       } 
    1518     } // for(;;) 
    1519     return; 
    1520   }}} 
    1521 #endif 
    1522   // Trace ray by ray 
    1523   SimpleRay ray; 
    1524   for (int i = 0; i < 4; i++) { 
    1525     ray.mOrigin = rp.GetLoc(i); 
    1526     ray.mDirection = rp.GetDir(i); 
    1527     FindNearestI(ray, localbox); 
    1528     rp.SetObject(i, SimpleRay::IntersectionRes[0].intersectable); 
    1529     rp.SetT(i, SimpleRay::IntersectionRes[0].tdist); 
    1530     // SimpleRay::IntersectionRes[0].intersectable->GetNormal(0); 
    1531   } // for 
    1532 } 
    1533 #endif 
    1534  
    1535 #endif // __SSE__ 
    1536654 
    1537655#endif //  TRV00F 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/ktbtrav.h

    r2583 r2592  
    3030 
    3131namespace GtpVisibilityPreprocessor { 
    32  
    33 class RayPacket2x2; 
    3432   
    3533//#define TRV000 
     
    136134public: 
    137135  virtual int FindNearestI(const SimpleRay &ray) { return 0; } 
     136  virtual int FindNearestI(const SimpleRay &ray, const AxisAlignedBox3 &localbox) { return 0;} 
    138137  void SetOffset(int offset) { rayOffset = offset; } 
    139138  virtual int FindNearestI_16oneDir(SimpleRayContainer &rays) { return 0; } 
    140   virtual int FindNearestI_16oneDir(SimpleRayContainer &rays, int offset) 
    141   { return 0; }  
     139  virtual int FindNearestI_16oneDir(SimpleRayContainer &rays, 
     140                                    int offset, int copyOffset) { return 0; }  
     141  virtual int FindNearestI_16oneDirNoSSE(SimpleRayContainer &rays, int offset) { return 0; } 
    142142  virtual int FindNearestI_16twoDir(SimpleRayContainer &rays) { return 0; } 
    143143 
     
    145145  enum { MAX_NESTING = 2}; 
    146146   
     147#ifdef _USE_HAVRAN_SSE   
    147148  // The same operations for packets of rays, if implemented by 
    148149  // a particular ASDS, otherwise it is emulated by decomposition 
     
    150151  virtual void FindNearestI(RayPacket2x2 &raypack) { } 
    151152  virtual void FindNearestI(RayPacket2x2 &raypack, Vector3 &boxmin, Vector3 &boxmax) { } 
    152  
     153#endif 
     154   
    153155  virtual void PrintStatsTR(ostream &) { } 
    154156  virtual void DynamicStatsReset() { } 
     
    306308  virtual int FindNearestI(const SimpleRay &ray); 
    307309  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); 
     310  virtual int FindNearestI_16oneDir(SimpleRayContainer &rays, 
     311                                    int offset, int copyOffset) 
     312#ifdef _USE_HAVRAN_SSE   
     313    ; // this is implemented with SSE in ktbftrav.cpp ! 
     314#else 
     315  { return 0;} 
     316#endif 
     317     
     318  virtual int FindNearestI_16oneDirNoSSE(SimpleRayContainer &rays, int offset); 
    314319 
    315320  int PrecomputeData(SimpleRayContainer &rays); 
     
    317322  virtual int FindNearestI_16twoDir(SimpleRayContainer &rays); 
    318323 
     324#ifdef _USE_HAVRAN_SSE   
    319325#ifdef __SSE__ 
    320326  // The same operations for packets of rays, if implemented by 
     
    324330  virtual void FindNearestI(RayPacket2x2 &raypack, Vector3 &boxmin, Vector3 &boxmax); 
    325331#endif // __SSE__ 
    326  
     332#endif // _USE_HAVRAN_SSE   
     333   
    327334  virtual void PrintStatsTR(ostream &) { } 
    328335 
     
    408415  virtual int FindNearestI(SimpleRay &ray); 
    409416 
     417#ifdef _USE_HAVRAN_SSE   
    410418#ifdef __SSE__ 
    411419  // The same operations for packets of rays, if implemented by 
     
    415423  virtual void FindNearestI(RayPacket2x2 &raypack, Vector3 &boxmin, Vector3 &boxmax); 
    416424#endif // __SSE__ 
     425#endif // _USE_HAVRAN_SSE   
    417426 
    418427  virtual void DynamicStatsReset(); 
  • GTP/trunk/Lib/Vis/Preprocessing/src/havran/raypack.h

    r2583 r2592  
    2121 
    2222#include "Vector3.h" 
     23#include "ktbconf.h" 
     24   
     25#ifdef _USE_HAVRAN_SSE 
    2326   
    2427#ifdef __SSE__ 
     
    337340  // initialize inverted dir ? 
    338341#ifdef _USE_INVDIR_RP 
    339   // inverted dir - maybe an overkill for SSE 
    340   // to be checked ! 
    341   idx[0] = 1.0f / dx[0]; 
    342   idx[1] = 1.0f / dx[1]; 
    343   idx[2] = 1.0f / dx[2]; 
    344   idx[3] = 1.0f / dx[3]; 
    345    
    346   idy[0] = 1.0f / dy[0]; 
    347   idy[1] = 1.0f / dy[1]; 
    348   idy[2] = 1.0f / dy[2]; 
    349   idy[3] = 1.0f / dy[3]; 
    350  
    351   idz[0] = 1.0f / dz[0]; 
    352   idz[1] = 1.0f / dz[1]; 
    353   idz[2] = 1.0f / dz[2]; 
    354   idz[3] = 1.0f / dz[3]; 
     342  // 
     343  const float epsAdd = -1e-25; 
     344  idx[0] = 1.0f / (dx[0] + epsAdd); 
     345  idx[1] = 1.0f / (dx[1] + epsAdd); 
     346  idx[2] = 1.0f / (dx[2] + epsAdd); 
     347  idx[3] = 1.0f / (dx[3] + epsAdd); 
     348   
     349  idy[0] = 1.0f / (dy[0] + epsAdd); 
     350  idy[1] = 1.0f / (dy[1] + epsAdd); 
     351  idy[2] = 1.0f / (dy[2] + epsAdd); 
     352  idy[3] = 1.0f / (dy[3] + epsAdd); 
     353   
     354  idz[0] = 1.0f / (dz[0] + epsAdd); 
     355  idz[1] = 1.0f / (dz[1] + epsAdd); 
     356  idz[2] = 1.0f / (dz[2] + epsAdd); 
     357  idz[3] = 1.0f / (dz[3] + epsAdd); 
    355358#endif 
    356359} 
     
    430433  tmax[i] = tmaxnew; 
    431434} 
    432 #else // __SSE__ 
    433  
    434 // ? What to do here 
    435 //#error "AAA" 
    436  
    437435#endif // __SSE__ 
    438436 
     437#endif // _USE_HAVRAN_SSE 
     438   
    439439} // namespace 
    440440 
  • GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro

    r2583 r2592  
    129129SOURCES += havran/allocgo2.cpp havran/ktbai.cpp havran/ktbtrav.cpp \ 
    130130havran/ktb.cpp havran/ktball.cpp havran/sbbox.cpp \ 
    131 havran/ktb8b.cpp havran/ktbftrav.cpp havran/timer.cpp 
     131havran/ktb8b.cpp havran/ktbftrav.cpp havran/ktbf2trv.cpp havran/timer.cpp 
    132132 
    133133 
Note: See TracChangeset for help on using the changeset viewer.