Changeset 2755 for GTP/trunk


Ignore:
Timestamp:
06/12/08 01:09:23 (16 years ago)
Author:
mattausch
Message:
 
Location:
GTP/trunk/App/Demos/Vis/CHC_revisited
Files:
6 added
18 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.cpp

    r2751 r2755  
    22#include <iostream> 
    33#include "AxisAlignedBox3.h" 
     4#include "Plane3.h" 
    45 
    56 
    67using namespace std; 
     8 
    79 
    810namespace CHCDemo 
     
    10271029                return mMin[face]; 
    10281030        else 
    1029                         return mMax[face - 3]; 
    1030 } 
    1031  
    1032  
    1033 } 
    1034  
     1031                return mMax[face - 3]; 
     1032} 
     1033 
     1034 
     1035int AxisAlignedBox3::GetIndexNearestVertex(const Vector3 &vecPlaneNormal) 
     1036{ 
     1037        int index; 
     1038 
     1039        if (vecPlaneNormal.x > 0.0f) 
     1040                index = (vecPlaneNormal.y > 0.0f) ? 0 : 3; 
     1041        else 
     1042                index = (vecPlaneNormal.y > 0.0f) ? 1 : 2; 
     1043 
     1044        return (vecPlaneNormal.z > 0.0f) ? index : 7 - index; 
     1045} 
     1046 
     1047 
     1048int AxisAlignedBox3::GetIndexFarthestVertex(const Vector3 &vecPlaneNormal) 
     1049{ 
     1050        int index; 
     1051 
     1052        if (vecPlaneNormal.x <= 0.0f) 
     1053                index = (vecPlaneNormal.y <= 0.0f) ? 0 : 3; 
     1054        else 
     1055                index = (vecPlaneNormal.y <= 0.0f) ? 1 : 2; 
     1056 
     1057        return (vecPlaneNormal.z <= 0.0f) ? index : 7 - index; 
     1058} 
     1059 
     1060 
     1061float AxisAlignedBox3::GetDistance(int index, const Plane3 &plane) const 
     1062{ 
     1063        return plane.Distance(GetVertex(index)); 
     1064} 
     1065 
     1066 
     1067float AxisAlignedBox3::GetMinVisibleDistance(const Plane3 &near) const 
     1068{ 
     1069        return  near.mNormal.x * ((near.mNormal.x > 0.0f) ? mMin.x : mMax.x) + 
     1070                        near.mNormal.y * ((near.mNormal.y > 0.0f) ? mMin.y : mMax.y) + 
     1071                        near.mNormal.z * ((near.mNormal.z > 0.0f) ? mMin.z : mMax.z) + 
     1072                        near.mD; 
     1073} 
     1074 
     1075} 
     1076 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.h

    r2751 r2755  
    33 
    44 
    5  
    65#include "Matrix4x4.h" 
    76#include "Vector3.h" 
    8 //#include "Plane3.h" 
    9 //#include "Containers.h" 
    107 
    118 
     
    1411 
    1512struct Triangle3; 
     13class Plane3; 
    1614 
    1715/** Axis alignedd box class. 
     
    5250        const Vector3& Max() const; 
    5351 
    54         void Enlarge (const Vector3 &v); 
     52        void Enlarge(const Vector3 &v); 
    5553 
    5654        void EnlargeToMinSize(); 
     
    6361 
    6462        void SetMax(int axis, const float value); 
    65  
    66         // Decrease box by given splitting plane 
     63        /** Decrease box by given splitting plane 
     64        */ 
    6765        void Reduce(int axis, int right, float value);  
    6866 
     
    7169        // the size of the box along all the axes 
    7270        Vector3 Size() const; 
    73         float Radius() const { return 0.5f*Magnitude(Size()); } 
    74         float SqrRadius() const { return 0.5f*SqrMagnitude(Size()); } 
     71        float Radius() const { return 0.5f * Magnitude(Size()); } 
     72        float SqrRadius() const { return 0.5f * SqrMagnitude(Size()); } 
    7573 
    7674        // Return whether the box is unbounded.  Unbounded boxes appear 
     
    8482        */ 
    8583        void Include(const int &axis, const float &newBound); 
    86         // int Side(const Plane3 &plane) const; 
    87  
    88         // Overlap returns 1 if the two axis-aligned boxes overlap .. even weakly 
    89         friend inline bool Overlap(const AxisAlignedBox3 &, const AxisAlignedBox3 &); 
    90  
    91         // Overlap returns 1 if the two axis-aligned boxes overlap .. only strongly 
    92         friend inline bool OverlapS(const AxisAlignedBox3 &,const AxisAlignedBox3 &); 
    93  
    94         /** Overlap returns 1 if the two axis-aligned boxes overlap for a given 
    95         epsilon. If eps > 0.0, then the boxes has to have the real intersection 
    96         box, if eps < 0.0, then the boxes need not intersect really, they 
    97         can be at eps distance in the projection. 
    98         */ 
    99         friend inline bool Overlap(const AxisAlignedBox3 &, 
    100                 const AxisAlignedBox3 &, 
    101                 float eps); 
    102  
    10384        /** Includes returns true if a includes b (completely) 
    10485        */ 
    10586        bool Includes(const AxisAlignedBox3 &b) const; 
    106  
    10787        /** Returns true if this point is inside box. 
    10888        */ 
     
    122102        /** Scales the box with the factor. 
    123103        */ 
    124         void Scale(const float scale); 
     104        void Scale(float scale); 
    125105 
    126106        void Scale(const Vector3 &scale); 
     
    177157 
    178158        int GetFaceVisibilityMask(const Vector3 &position) const; 
    179         /** Extracts plane of bounding box. 
    180         */ 
    181         //Plane3 GetPlane(const int face) const; 
    182159        /** Returns vertex indices of edge. 
    183160        */ 
    184         void GetEdge(const int edge, int  &aIdx, int &bIdx) const; 
    185  
     161        void GetEdge(int edge, int  &aIdx, int &bIdx) const; 
     162        /** Get distance of plane to vertex with specified index. 
     163        */ 
     164        float GetDistance(int index, const Plane3 &plane) const; 
     165        /** Returns the distance between the plane given by 'vecNearplaneNormal' and the vertex that 
     166            is closest to it (this vertex is unequivocally identified by the direction of the vector) 
     167        */ 
     168        float GetMinVisibleDistance(const Plane3 &near) const; 
    186169 
    187170 
    188171        //////////// 
    189172        //-- friend functions 
     173 
     174        /// Overlap returns 1 if the two axis-aligned boxes overlap .. even weakly 
     175        friend inline bool Overlap(const AxisAlignedBox3 &, const AxisAlignedBox3 &); 
     176 
     177        /// Overlap returns 1 if the two axis-aligned boxes overlap .. only strongly 
     178        friend inline bool OverlapS(const AxisAlignedBox3 &,const AxisAlignedBox3 &); 
     179 
     180        /** Overlap returns 1 if the two axis-aligned boxes overlap for a given 
     181        epsilon. If eps > 0.0, then the boxes has to have the real intersection 
     182        box, if eps < 0.0, then the boxes need not intersect really, they 
     183        can be at eps distance in the projection. 
     184        */ 
     185        friend inline bool Overlap(const AxisAlignedBox3 &,     const AxisAlignedBox3 &, float eps); 
     186 
    190187 
    191188        // Returns the smallest axis-aligned box that includes all points 
     
    250247        static const int fsvertices[27][9]; 
    251248 
     249        /** Returns the vertex index nearest from the plane specified by the normal. 
     250        */ 
     251        static int GetIndexNearestVertex(const Vector3 &vecPlaneNormal); 
     252        /** Returns the vertwx index farthest from the plane specified by the normal. 
     253        */ 
     254        static int GetIndexFarthestVertex(const Vector3 &vecPlaneNormal); 
     255 
     256 
     257 
    252258protected: 
    253259 
    254260        Vector3 mMin, mMax; 
    255  
    256261}; 
    257262 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.cpp

    r2747 r2755  
    11#include "BinaryLoader.h" 
    2 #include "yare.h" 
    3 #include "yamath.h" 
    4 #include "gzstream.h" 
    5 #include "ImageComponent.h" 
    6 #include "RenderState.h" 
    7 #include "GeometryProcessor.h" 
     2#include "Matrix4x4.h" 
     3#include "Geometry.h" 
     4#include "Material.h" 
     5//#include "gzstream.h" 
    86 
    97 
    108using namespace std; 
    119 
    12 static STL_MAP<String,Texture *> stlm_textures; 
     10 
     11namespace CHCDemo 
     12{ 
     13 
     14/*static STL_MAP<String,Texture *> stlm_textures; 
    1315 
    1416 
     
    6163 
    6264        return myTexture; 
    63 } 
    64  
    65  
    66 Shape3D *BinaryLoader::LoadShape(igzstream &str) 
     65}*/ 
     66 
     67 
     68//SceneEntity *BinaryLoader::LoadShape(igzstream &str) 
     69SceneEntity *BinaryLoader::LoadShape(ifstream &str) 
    6770{        
    6871        Geometry *geom = LoadGeometry(str); 
    69         Appearance *app = LoadAppearance(str); 
    70  
    71         Shape3D *shape = new Shape3D(geom, app); 
    72  
    73         return shape; 
    74 } 
    75  
    76  
    77 Appearance *BinaryLoader::LoadAppearance(igzstream &str) 
    78 { 
    79         Appearance *app = new Appearance(); 
    80          
     72        Material *mat = LoadMaterial(str); 
     73 
     74        Matrix4x4 *m; 
     75        SceneEntity *sceneGeom = new SceneEntity(geom, m, mat); 
     76 
     77        return sceneGeom; 
     78} 
     79 
     80 
     81//Appearance *BinaryLoader::LoadMaterial(igzstream &str) 
     82Material *BinaryLoader::LoadMaterial(ifstream &str) 
     83{ 
     84        Material *mat = new Material(); 
     85/*       
    8186        // texture 
    8287        int texnameSize; 
     
    113118                //str.read(reinterpret_cast<char *>(&spec), sizeof(Color3f)); 
    114119                //str.read(reinterpret_cast<char *>(&shine), sizeof(float)); 
    115 #if 1 
    116                 Material *mat = new Material(); 
    117120 
    118121                mat->setAmbientColor(amb); 
     
    123126 
    124127                app->setMaterial(mat); 
    125 #endif 
    126         } 
    127  
    128         return app; 
    129 } 
    130  
    131  
    132 Geometry *BinaryLoader::LoadGeometry(igzstream &str) 
    133 { 
     128        } 
     129 
     130        return app;*/ 
     131 
     132        return mat; 
     133} 
     134 
     135 
     136//Geometry *BinaryLoader::LoadGeometry(igzstream &str) 
     137Geometry *BinaryLoader::LoadGeometry(ifstream &str) 
     138{ 
     139/* 
    134140        int vertexCount; 
    135141        int stripCount; 
     
    254260         
    255261        return geom;  
    256 } 
    257  
    258  
    259 BranchGroup *BinaryLoader::Load(const string &filename) 
    260 { 
     262        */ 
     263return 0; 
     264} 
     265 
     266 
     267bool BinaryLoader::Load(const std::string &filename, SceneEntityContainer &geometry) 
     268{ 
     269#if 0 
    261270        clear_textures(); // clear the texture table 
    262271 
     
    320329 
    321330        return root; 
    322 } 
    323  
    324  
    325 #if 0 
    326  
    327 collectvertices 
    328 { 
    329         int newIndex = 0; 
    330  
    331         for (int i = 0; i < numTriangles; ++ i) 
    332         { 
    333                 Triangle tri = mTriangles[i]; 
    334  
    335                 for (int j = 0; j < 3; ++ j) 
    336                 { 
    337                         const int index = tri.mVertexIndices[j]; 
    338                         if (!mHashtable[index]) 
    339                         { 
    340                                 mHashTable[index] = newIndex; 
    341                                 mNewVertices.push_back(mVertices[index]; 
    342                         } 
    343         } 
    344  
    345         // now loop again, exchange indices; 
    346         for (int i = 0; i < numTriangles; ++ i 
    347         { 
    348                 Triangle tri = mTriangles[i]; 
    349  
    350                 for (int j = 0; j < 3; ++ j) 
    351                 { 
    352                         const int index = tri.mVertexIndices[j]; 
    353                         tri.mVertexIndices[j] = mHashTable[index]; 
    354         } 
    355 } 
    356  
    357331#endif 
     332} 
     333 
     334} 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.h

    r2747 r2755  
    44// note use forward declaration instead 
    55#include <string> 
     6#include <iostream> 
     7#include <fstream> 
     8#include "common.h" 
    69 
    710 
     11namespace CHCDemo 
     12{ 
     13 
    814class igzstream; 
    9 class Shape3D; 
    10 class BranchGroup; 
    11 class Appearance; 
     15class SceneEntity; 
     16class Material; 
    1217class Geometry; 
    1318 
     
    1722public: 
    1823 
    19         BranchGroup *Load(const std::string &filename); 
     24        bool Load(const std::string &filename, SceneEntityContainer &geometry); 
    2025 
    2126protected: 
     27         
     28        SceneEntity *LoadShape(std::ifstream &str); 
     29        Material *LoadMaterial(std::ifstream &str); 
     30        Geometry *LoadGeometry(std::ifstream &str); 
    2231 
    23         Shape3D *LoadShape(igzstream &str); 
    24  
    25         Appearance *LoadAppearance(igzstream &str); 
    26  
     32        /*SceneEntity *LoadShape(igzstream &str); 
     33        Material *LoadMaterial(igzstream &str); 
    2734        Geometry *LoadGeometry(igzstream &str); 
     35        */ 
    2836}; 
    2937 
     38} 
    3039#endif 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.cpp

    r2752 r2755  
    11#include <queue> 
    22#include <stack> 
    3 #include "Bvh.h" 
    4  
    53#include <fstream> 
    64#include <iostream> 
    75#include <iomanip> 
    86 
     7#include "Bvh.h" 
     8#include "Camera.h" 
     9#include "Plane3.h" 
     10#include "glInterface.h" 
     11#include "Triangle3.h" 
     12 
    913 
    1014namespace CHCDemo 
    1115{ 
    1216 
    13 #if TOIMPLEMENT 
    14  
    1517#define INVALID_TEST ((unsigned int)-1) 
    16  
    17 #define TYPE_INTERIOR -2 
    18 #define TYPE_LEAF -3 
    19 #define USE_TIGHTER_BOUNDS_FOR_ALL 0 
    2018 
    2119const static bool useVbos = true; 
     
    6260*/ 
    6361 
     62static Plane3 sNearPlane; 
     63static Camera::Frustum sFrustum; 
     64 
     65/// these values are valid for all nodes 
     66static int sClipPlaneAABBVertexIndices[12]; 
     67 
    6468 
    6569BvhNode::BvhNode(BvhNode *parent):  
     
    6973mPlaneMask(0), 
    7074mPreferredPlane(0), 
    71 mVizBox(NULL), 
    7275mLastRenderedFrame(-999), 
    7376mFirst(-1),  
     
    7578mNumTestNodes(1), 
    7679mTestNodesIdx(-1), 
    77 mIndicesPtr(-1) 
     80mIndicesPtr(-1), 
     81mIndices(NULL), 
     82mId(0) 
    7883{ 
    7984} 
     
    8388{ 
    8489        mVisibility.Reset(); 
    85         mMeasurements.Reset(); 
    8690 
    8791        mLastRenderedFrame = -999; 
     
    9195BvhNode::~BvhNode()  
    9296{ 
    93         if (mVizBox) mVizBox->unref(); 
    94 } 
    95  
    96  
    97 Box *BvhNode::GetOrCreateVizBox()  
    98 { 
    99         if (!mVizBox)  
    100         { 
    101                 mVizBox = new Box(mBox);  
    102                 mVizBox->ref(); 
    103         } 
    104  
    105         return mVizBox; 
    10697} 
    10798 
     
    110101{ 
    111102        mIsVisible = false; 
    112         mIsFullyVisible = false; 
    113  
    114         mVisiblePixels = 0; 
     103         
    115104        mAssumedVisibleFrames = 0; 
    116         mRemainingVisibleFrames = 0; 
    117105 
    118106        mLastVisitedFrame = -1; 
    119         mLastTestedFrame = -1; 
    120         mTurnedVisibleFrame = 0; 
    121  
     107         
    122108        mTimesInvisible = 0; 
    123         mTimesTested = 0; 
    124         mTimesChangedClassification = 0; 
    125         mAvgChangedClassification = 0; 
    126109        mIsFrustumCulled = false; 
    127110 
    128         mLastTestedVisibleFrame = 0; 
    129111        mIsNew = true; 
    130112} 
    131113 
    132114 
    133 void BvhNode::SetFullyVisible(const bool visible) 
    134 { 
    135         mVisibility.mIsFullyVisible = visible; 
    136 } 
    137  
    138  
    139115BvhLeaf::~BvhLeaf() 
    140116{ 
    141         if (mTriangleBvh) delete mTriangleBvh; 
    142117} 
    143118 
     
    148123 
    149124 
    150  
     125Bvh::Bvh(): 
     126mCamera(NULL),  
     127mFrameId(-1),  
     128mRoot(NULL),  
     129mVertices(NULL), 
     130mIndices(NULL), 
     131mTestIndices(NULL), 
     132mCurrentIndicesPtr(0) 
     133{} 
     134 
     135/* 
    151136Bvh::Bvh(const GeometryVector &geometry,  
    152137                 DistanceSortedRenderAction *const renderer): 
     
    156141mVertices(NULL), 
    157142mIndices(NULL), 
    158 mUseTighterBoundsOnlyForLeafTests(false), 
    159 mRenderer(renderer), 
    160143mTestIndices(NULL), 
    161144mCurrentIndicesPtr(0), 
    162 mCollectTighterBoundsWithMaxLevel(true) 
    163145{ 
    164146        mGeometry = new NodeGeometry*[geometry.size()]; 
     
    203185 
    204186        mMaxDepthForTestingChildren = Settings::Global()->get_nvocc_bvh_max_depth_for_testing_children(); 
    205         mUseTighterBoundsOnlyForLeafTests = (Settings::Global()->get_nvocc_use_tighter_bounds() >= 1); 
    206          
     187                 
    207188        mAreaRatioThreshold = Settings::Global()->get_nvocc_area_ratio_threshold(); 
    208189        mVolRatioThreshold = Settings::Global()->get_nvocc_vol_ratio_threshold(); 
    209190} 
    210  
     191*/ 
    211192 
    212193Bvh::~Bvh()  
     
    221202 
    222203 
    223 void Bvh::Construct() 
    224 { 
    225         PerfTimer constructTimer; 
    226         constructTimer.Entry(); 
    227  
    228         OUT1("Info: Constructing BVH"); 
    229  
    230         mRoot = SubdivideLeaf((BvhLeaf *)mRoot, 0); 
    231  
    232         constructTimer.Exit(); 
    233  
    234         OUT1("Info: Bvh done in " << constructTimer.TotalCount() << " seconds."); 
    235         OUT1("Info: Number Of BVH Nodes = " << mNumNodes); 
    236  
    237         // update stats on leaf nodes 
    238         UpdateNumLeaves(mRoot); 
    239          
    240         mAvgDepth = 1.0f + log((float)GetNumLeaves()) / log(2.0f); 
    241  
    242         BvhLeafContainer leaves; 
    243         leaves.reserve(GetNumLeaves()); 
    244         CollectLeaves(mRoot, leaves); 
    245  
    246         // compute tighter boundaries for the leaves 
    247         PostProcessLeaves(leaves); 
    248         // compute unique ids 
    249         ComputeIds(); 
    250         /// pull up some data from the leaves 
    251         UpdateInteriors(mRoot); 
    252         // recompute the boundaries once 
    253         RecomputeBounds(); 
    254         // do stats 
    255         ComputeBvhStats(); 
    256  
    257         PrintBvhStats(); 
    258 } 
    259  
    260  
    261 float Bvh::EvaluateSahCost(BvhLeaf *leaf, const int axis, const float position) 
    262 { 
    263         // count triangles on the left / right 
    264         int left = 0; 
    265         int right = 0; 
    266         BoundingBox leftBox, rightBox; 
    267  
    268         const int candidates = std::max(50, (int)(leaf->CountPrimitives() / 20)); 
    269  
    270         const float finc = leaf->CountPrimitives() / (float)candidates; 
    271  
    272         int i = leaf->mFirst; 
    273         float fi = leaf->mFirst + 0.5f; 
    274  
    275         BoundingBox box; 
    276  
    277         for (; i <= leaf->mLast;)  
    278         { 
    279                 box = mGeometry[i]->GetBoundingBox(); 
    280  
    281                 if (box.getCenter()[axis] < position)  
    282                 { 
    283                         ++ left; 
    284                         // update the box 
    285                         leftBox.combine(&box); 
    286                 }  
    287                 else  
    288                 { 
    289                         ++ right; 
    290                         rightBox.combine(&box); 
    291                 } 
    292                   
    293                 fi += finc; 
    294                 i = (int)fi; 
    295         } 
    296  
    297         float bW = 1.0f; 
    298         float leftRatio = left / (float)leaf->CountPrimitives(); 
    299         float rightRatio = right / (float)leaf->CountPrimitives(); 
    300  
    301         float saLeft = 0.0f; 
    302         float saRight = 0.0f; 
    303  
    304         // not a valid split 
    305         if (!left || !right) 
    306                 return 1e25f; 
    307  
    308         saLeft = leftBox.getSurface(); 
    309         saRight = rightBox.getSurface(); 
    310  
    311  
    312         return 
    313                 saLeft  * ((1.0f - bW) + bW * leftRatio) +  
    314                 saRight * ((1.0f - bW) + bW * rightRatio); 
    315 } 
    316  
    317  
    318 float Bvh::SelectPlaneSah(BvhLeaf *leaf, int &axis, float &minCost) 
    319 { 
    320         minCost = MAXFLOAT; 
    321         float bestPos = minCost; 
    322         int bestAxis = 0; 
    323  
    324         //  cout<<"Evaluating axis..."<<endl<<flush; 
    325  
    326         const int initialPlanes = 3; 
    327  
    328         // initiate the costs 
    329         for (axis = 0; axis < 3; ++ axis)  
    330         { 
    331                 const float size = leaf->mBox.getUpper()[axis] - leaf->mBox.getLower()[axis]; 
    332  
    333                 for (int i = 0; i < initialPlanes; ++ i)  
    334                 { 
    335                         const float pos = leaf->mBox.getLower()[axis] + (i + 1) * size / (initialPlanes + 1); 
    336                         const float cost = EvaluateSahCost(leaf, axis, pos); 
    337  
    338                         if (cost < minCost)  
    339                         { 
    340                                 minCost = cost; 
    341                                 bestPos = pos; 
    342                                 bestAxis = axis; 
    343                         } 
    344                 } 
    345         } 
    346  
    347         axis = bestAxis; 
    348  
    349         //  cout<<axis<<endl<<flush; 
    350         const float shrink = 0.5f; 
    351  
    352         // now hierarchically refine the initial interval 
    353         float size = shrink *  
    354                 (leaf->mBox.getUpper()[axis] - leaf->mBox.getLower()[axis]) / (initialPlanes + 1); 
    355  
    356         const int steps = 4; 
    357         float cost; 
    358  
    359         for (int i = 0; i < steps; ++ i)  
    360         { 
    361                 const float left = bestPos - size; 
    362                 const float right = bestPos + size; 
    363  
    364                 cost = EvaluateSahCost(leaf, axis, left); 
    365  
    366                 if (cost < minCost)  
    367                 { 
    368                         minCost = cost; 
    369                         bestPos = left; 
    370                 } 
    371  
    372                 cost = EvaluateSahCost(leaf, axis, right); 
    373  
    374                 if (cost < minCost)  
    375                 { 
    376                         minCost = cost; 
    377                         bestPos = right; 
    378                 } 
    379  
    380                 size = shrink * size; 
    381         } 
    382  
    383         //OUT1("best axis: " << axis << " " << bestPos << " " << minCost); 
    384  
    385         return bestPos; 
    386 } 
    387  
    388  
    389 void Bvh::ResizeVisibilityBuffers(const int maxSize) 
    390 { 
    391         std::stack<BvhNode *> nodeStack; 
    392  
    393         nodeStack.push(mRoot); 
    394  
    395         while (!nodeStack.empty())  
    396         { 
    397                 BvhNode *node = nodeStack.top(); 
    398                 nodeStack.pop(); 
    399  
    400                 static_cast<BvhLeaf *>(node)->mMeasurements.Reset(); 
    401  
    402                 if (!node->IsLeaf())  
    403                 { 
    404                         BvhInterior *interior = static_cast<BvhInterior *>(node); 
    405                          
    406                         nodeStack.push(interior->mBack); 
    407                         nodeStack.push(interior->mFront); 
    408                 } 
    409         } 
    410 } 
    411  
    412  
    413 int Bvh::SortTriangles(BvhLeaf *leaf,  
    414                                            const int axis,  
    415                                            const float position) 
    416 { 
    417         int i = leaf->mFirst; 
    418         int j = leaf->mLast; 
    419  
    420     while (1)  
    421         { 
    422                 while (mGeometry[i]->GetBoundingBox().getCenter()[axis] < position)  
    423                         ++ i; 
    424          
    425                 while (position < mGeometry[j]->GetBoundingBox().getCenter()[axis]) 
    426                         -- j; 
    427  
    428                 if (i < j)  
    429                 { 
    430                         std::swap(mGeometry[i], mGeometry[j]); 
    431                          
    432                         ++ i; 
    433                         -- j; 
    434                 } 
    435                 else 
    436                 { 
    437                         break; 
    438                 } 
    439         } 
    440  
    441         return j; 
    442 } 
    443  
    444  
    445 int Bvh::SortTrianglesSpatialMedian(BvhLeaf *leaf, const int axis) 
    446 { 
    447         // spatial median 
    448         float x = leaf->mBox.getCenter()[axis]; 
    449  
    450         return SortTriangles(leaf, axis, x); 
    451 } 
    452  
    453  
    454 int Bvh::SortTrianglesObjectMedian(BvhLeaf *leaf, const int axis, float &pos) 
    455 { 
    456         // Now distribute the objects into the subnodes 
    457         // Use QuickMedian sort 
    458         int l = leaf->mFirst; 
    459         int r = leaf->mLast; 
    460         int k = (l + r) / 2; 
    461  
    462         while (l < r)  
    463         { 
    464                 int i = l; 
    465                 int j = r; 
    466  
    467                 // get some estimation of the pivot 
    468                 pos = mGeometry[(l + r) / 2]->GetBoundingBox().getCenter()[axis]; 
    469  
    470                 while (1)  
    471                 { 
    472                         while ((i  <= leaf->mLast) && (mGeometry[i]->GetBoundingBox().getCenter()[axis] < pos)) 
    473                                 ++ i; 
    474  
    475                         while((j >= leaf->mFirst) && (pos < mGeometry[j]->GetBoundingBox().getCenter()[axis])) 
    476                                 -- j; 
    477  
    478                         if (i <= j)  
    479                         { 
    480                                 std::swap(mGeometry[i], mGeometry[j]); 
    481                                 ++ i; 
    482                                 -- j; 
    483                         } 
    484                         else 
    485                         { 
    486                                 break; 
    487                         } 
    488                 } 
    489  
    490                 // now check the extents 
    491                 if (i >= k) 
    492                         r = j; 
    493                 else 
    494                         l = i; 
    495         } 
    496  
    497         return k; 
    498 } 
    499  
    500  
    501 int Bvh::SortTrianglesSurfaceArea(BvhLeaf *leaf, const float sa) 
    502 { 
    503         int i = leaf->mFirst; 
    504         int j = leaf->mLast; 
    505  
    506         while(1)  
    507         { 
    508                 while ((i <= j) && (mGeometry[i]->GetBoundingBox().getSurface() < sa))  
    509                         ++ i; 
    510  
    511                 while ((i <= j) && (sa < mGeometry[j]->GetBoundingBox().getSurface())) 
    512                         -- j; 
    513  
    514                 if (i < j)  
    515                 { 
    516                         swap(mGeometry[i], mGeometry[j]); 
    517                         ++ i; 
    518                         -- j; 
    519                 } 
    520                 else 
    521                         break; 
    522         } 
    523  
    524         return j; 
    525 } 
    526  
    527  
    528 bool Bvh::TerminationCriteriaMet(BvhLeaf *leaf) const 
    529 { 
    530         const bool terminationCriteriaMet =  
    531                 (leaf->mBox.getSurface() < mMinArea) || 
    532                 (leaf->CountPrimitives() <= mMaxGeometry) || 
    533                 (CountTriangles(leaf) <= mMaxTriangles) || 
    534                 (leaf->mDepth > mMaxDepth); 
    535  
    536         return terminationCriteriaMet; 
    537 } 
    538  
    539  
    540 BvhNode *Bvh::SubdivideLeaf(BvhLeaf *leaf, const int parentAxis) 
    541 { 
    542         if (TerminationCriteriaMet(leaf)) 
    543                 return leaf; 
    544          
    545         //int axis = leaf->mBox.MajorAxis(); 
    546         int axis = (parentAxis + 1) % 3; 
    547  
    548         // position of the split in the partailly sorted array of triangles 
    549         // corresponding to this leaf 
    550         int split = -1; 
    551         const int scale = 20; 
    552  
    553         float pos = -1.0f; 
    554  
    555         // Spatial median subdivision 
    556         switch (mSplitType)  
    557         { 
    558         case SPATIAL_MEDIAN: 
    559                 split = SortTrianglesSpatialMedian(leaf, axis); 
    560  
    561                 if (  
    562                         ((split - leaf->mFirst) < leaf->CountPrimitives() / scale) || 
    563                         ((leaf->mLast - split) < leaf->CountPrimitives() / scale) )  
    564                 { 
    565                         split = SortTrianglesObjectMedian(leaf, axis, pos); 
    566                 } 
    567  
    568                 pos = leaf->mBox.getCenter()[axis]; 
    569                 break; 
    570         case OBJECT_MEDIAN: 
    571                 // Object median subdivision: approximately the same number 
    572                 // of objects on the left of the the splitting point. 
    573                 split = SortTrianglesObjectMedian(leaf, axis, pos); 
    574                 break; 
    575         case SAH: 
    576                 { 
    577                         float cost; 
    578                         pos = SelectPlaneSah(leaf, axis, cost); 
    579  
    580                         if (pos != MAXFLOAT) 
    581                         { 
    582                                 split = SortTriangles(leaf, axis, pos); 
    583                         } 
    584  
    585                         if ((pos == MAXFLOAT) || (split == leaf->mLast)) 
    586                         { 
    587                                 split = -1; 
    588                                 split = SortTrianglesObjectMedian(leaf, axis, pos); 
    589                         } 
    590                 } 
    591                 break; 
    592         case SAH_OR_SIZE:  
    593                 { 
    594                         // split by size instead 
    595                         const float saThreshold = 0.2f * leaf->GetBox().getSurface(); 
    596                         split = SortTrianglesSurfaceArea(leaf, saThreshold); 
    597  
    598                         if ((split == leaf->mLast) || (split == leaf->mFirst - 1))  
    599                         { 
    600                                 // use SAH 
    601                                 float cost; 
    602                                 pos = SelectPlaneSah(leaf, axis, cost); 
    603  
    604                                 if (pos != MAXFLOAT) 
    605                                         split = SortTriangles(leaf, axis, pos); 
    606                                 else 
    607                                         split = SortTrianglesObjectMedian(leaf, axis, pos); 
    608                         } 
    609                         else 
    610                         { 
    611                                 // note: no position is computed!! 
    612                                 //OUT1("sorted by size"); 
    613                         } 
    614                 } 
    615                 break; 
    616         default: 
    617                 OUT1("should not come here"); 
    618                 break; 
    619         } 
    620  
    621         if (1 && ((split == leaf->mLast))) 
    622         { 
    623                 // no reduction: we should never come here 
    624                 OUT1("error: no reduction " << leaf->CountPrimitives() << " " << leaf->mFirst << " " << split << " " << leaf->mLast); 
    625                 return leaf; 
    626         } 
    627  
    628         // create two more nodes 
    629         mNumNodes += 2; 
    630         BvhInterior *parent = new BvhInterior(leaf->GetParent()); 
    631         BvhLeaf *front = new BvhLeaf(parent); 
    632          
    633         parent->mAxis = axis; 
    634         parent->mBox = leaf->mBox; 
    635         parent->mDepth = leaf->mDepth; 
    636  
    637         parent->mBack = leaf; 
    638         parent->mFront = front; 
    639         parent->mPosition = pos; 
    640          
    641         // now assign the triangles to the subnodes 
    642         front->mFirst = split + 1; 
    643         front->mLast = leaf->mLast; 
    644         front->mDepth = leaf->mDepth + 1; 
    645         leaf->mLast = split; 
    646         leaf->mDepth = front->mDepth; 
    647         leaf->mParent = parent; 
    648          
    649         // reset box 
    650         leaf->mBox = BoundingBox(); 
    651  
    652         UpdateLeafBox(static_cast<BvhLeaf *>(parent->mBack)); 
    653         UpdateLeafBox(static_cast<BvhLeaf *>(parent->mFront)); 
    654  
    655         // some output 
    656         const int n = 500; 
    657         if ((GetNumLeaves() % n) == n - 1) 
    658                 OUT1("created " << GetNumLeaves() << " leaves"); 
    659          
    660 #if VERBOSE_OUTPUT 
    661         OUT1("box: " << parent->mBox.getUpper() << " " << parent->mBox.getLower()); 
    662         OUT1("depth: " << (int)parent->mDepth); 
    663         OUT1("axis: " << axis); 
    664         OUT1("bc="<<((BvhLeaf *)parent->mBack)->Count()); 
    665         OUT1("fc="<<((BvhLeaf *)parent->mFront)->Count()); 
    666         OUT1("back: " << parent->mBack->mBox.getSurface()); 
    667         OUT1("front: " << parent->mFront->mBox.getSurface()); 
    668 #endif 
    669  
    670         // recursively continue subdivision 
    671         parent->mBack = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mBack), axis); 
    672         parent->mFront = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mFront), axis); 
    673  
    674         return parent; 
    675 } 
    676  
    677  
    678 void Bvh::UpdateLeafBox(BvhLeaf *leaf) 
    679 { 
    680         for (int i = leaf->mFirst; i <= leaf->mLast; ++ i)  
    681         { 
    682                 leaf->mBox.combine(&mGeometry[i]->mBox); 
    683         } // for 
    684 } 
    685  
    686  
    687 void Bvh::UpdateNumLeaves(BvhNode *node) const 
    688 { 
    689         if (node->IsLeaf()) 
    690         { 
    691                 node->mNumLeaves = 1; 
    692         } 
    693         else 
    694         { 
    695                 BvhNode *f = static_cast<BvhInterior *>(node)->GetFront(); 
    696                 BvhNode *b = static_cast<BvhInterior *>(node)->GetBack(); 
    697  
    698                 UpdateNumLeaves(f); 
    699                 UpdateNumLeaves(b); 
    700  
    701                 node->mNumLeaves = f->mNumLeaves + b->mNumLeaves; 
    702         } 
    703 } 
    704  
    705  
    706 void Bvh::UpdateBoxes(BvhNode *node) 
    707 { 
    708         if (node->IsLeaf())  
    709         { 
    710                 UpdateLeafBox(static_cast<BvhLeaf *>(node)); 
    711         } 
    712         else  
    713         { 
    714                 BvhInterior *interior = static_cast<BvhInterior *>(node); 
    715          
    716                 UpdateBoxes(interior->mBack); 
    717                 UpdateBoxes(interior->mFront); 
    718  
    719                 node->mBox = interior->mBack->mBox; 
    720                 node->mBox.combine(&interior->mFront->mBox); 
    721         } 
    722 } 
    723  
    724  
    725 void Bvh::UpdateFullVisibility(BvhNode *node) const 
    726 {                
    727         // node not visited in this frame => no change 
    728         if (node->GetLastVisitedFrame() != mFrameId)  
    729                 return; 
    730  
    731         // leaf node: terminate recursion 
    732         if (node->IsLeaf()) 
    733         { 
    734                 node->SetFullyVisible(node->IsVisible());        
    735                 return; 
    736         } 
    737  
    738         BvhInterior *interior = static_cast<BvhInterior *>(node); 
    739          
    740         // recursive traversal 
    741         UpdateFullVisibility(interior->mBack); 
    742         UpdateFullVisibility(interior->mFront); 
    743          
    744         interior->SetFullyVisible(interior->mBack->IsFullyVisible() &&  
    745                                                           interior->mFront->IsFullyVisible()); 
    746 } 
    747  
    748  
    749204void Bvh::PullUpLastVisited(BvhNode *node, const int frameId) const 
    750205{                
     
    823278typedef pair<BvhNode *, int> tPair; 
    824279 
    825 void Bvh::CollectNodes(BvhNode *root,  
    826                                            const int depth,  
    827                                            HierarchyNodeContainer &nodes) 
     280void Bvh::CollectNodes(BvhNode *root, BvhNodeContainer &nodes, int depth) 
    828281{ 
    829282        stack<tPair> tStack; 
     
    838291 
    839292                // found depth => take this node 
    840                 if (d == depth) 
     293                if ((d == depth) || (node->IsLeaf())) 
    841294                { 
    842295                        nodes.push_back(node); 
    843296                } 
    844                 else if (node->IsLeaf()) 
    845                 { 
    846                         // found leaf 
    847                         BvhLeaf *leaf = static_cast<BvhLeaf *>(node); 
    848  
    849                         // there is no further subdivision on triangle level 
    850                         if (leaf->mTriangleBvh->GetNumNodes() == 1) 
    851                         { 
    852                                 nodes.push_back(leaf); 
    853                         } 
    854                         else // more than a root => search in local bvh 
    855                         { 
    856                                 leaf->mTriangleBvh-> 
    857                                         CollectNodes(leaf->mTriangleBvh->GetRoot(), depth - d, nodes); 
    858                         } 
    859                 } 
    860                 else // interior 
     297                else 
    861298                { 
    862299                        BvhInterior *interior = static_cast<BvhInterior *>(node); 
     
    869306 
    870307 
    871 void Bvh::CollectAllNodes(BvhNode *node, HierarchyNodeContainer &nodes) 
    872 { 
    873         BvhNodeContainer bvhNodes; 
    874  
    875         // collect nodes of geometry bvh 
    876         CollectNodes(mRoot, bvhNodes); 
    877  
    878          
    879         // first collect nodes of object bvh 
    880         BvhNodeContainer::const_iterator lit, lit_end = bvhNodes.end(); 
    881  
    882         for (lit = bvhNodes.begin(); lit != lit_end; ++ lit) 
    883         { 
    884                 nodes.push_back(*lit); 
    885         } 
    886  
    887         // collect nodes of local bvh: all except roots,  
    888         // because they are equivalent to geometry bvh leaves 
    889         for (lit = bvhNodes.begin(); lit != lit_end; ++ lit) 
    890         { 
    891                 if ((*lit)->IsLeaf()) 
    892                 { 
    893                         BvhLeaf *leaf = static_cast<BvhLeaf *>(*lit); 
    894  
    895                         TriangleBvhNodeContainer hnodes; 
    896                         leaf->mTriangleBvh->CollectNodes(leaf->mTriangleBvh->GetRoot(), hnodes); 
    897  
    898                         TriangleBvhNodeContainer::const_iterator hit, hit_end = hnodes.end(); 
    899  
    900                         for (hit = hnodes.begin(); hit != hit_end; ++ hit) 
    901                         { 
    902                                 TriangleBvhNode *n = *hit; 
    903  
    904                                 // don't include root of local bvh - it has the same bounds as the leaves 
    905                                 if (n != leaf->mTriangleBvh->GetRoot()) 
    906                                         nodes.push_back(n); 
    907                         } 
    908                 } 
    909         } 
    910 } 
    911  
    912  
    913 void Bvh::CollectVisibleLeaves(BvhNode *node, BvhLeafContainer &leaves) 
    914 { 
    915         stack<BvhNode *> tStack; 
    916         tStack.push(node); 
    917  
    918         while (!tStack.empty()) 
    919         { 
    920                 BvhNode *node = tStack.top(); 
    921                 tStack.pop(); 
    922  
    923                 if (IsWithinViewFrustum(node)) 
    924                 { 
    925                         if (!node->IsLeaf()) 
    926                         { 
    927                                 BvhInterior *interior = static_cast<BvhInterior *>(node); 
    928  
    929                                 tStack.push(interior->mFront); 
    930                                 tStack.push(interior->mBack); 
    931                         } 
    932                         else 
    933                         { 
    934                                 leaves.push_back(static_cast<BvhLeaf *>(node)); 
    935                         } 
    936                 } 
    937         } 
    938 } 
    939  
    940  
    941 BvhLeaf *Bvh::GetRandomLeaf(BvhNode *node) 
    942 { 
    943         stack<BvhNode *> nodeStack; 
    944    
    945         nodeStack.push(node); 
    946  
    947         int mask = rand(); 
    948  
    949     while (!nodeStack.empty())  
    950         { 
    951                 BvhNode *node = nodeStack.top(); 
    952                 nodeStack.pop(); 
    953                  
    954                 if (node->IsLeaf())  
    955                 { 
    956                         // random leaf 
    957                         return static_cast<BvhLeaf *>(node); 
    958                 }  
    959                 else  
    960                 { 
    961                         BvhInterior *interior = static_cast<BvhInterior *>(node); 
    962                          
    963                         BvhNode *next; 
    964                          
    965                         // random decision 
    966                         if (mask & 1) 
    967                                 next = interior->mBack; 
    968                         else 
    969                                 next = interior->mFront; 
    970  
    971                         mask = mask >> 1; 
    972  
    973                         nodeStack.push(next); 
    974                 } 
    975         } 
    976    
    977         // should never come here 
    978         return NULL; 
    979 } 
    980  
    981  
    982 BvhLeaf *Bvh::GetRandomVisibleLeaf(BvhNode *node) 
    983 { 
    984         BvhLeafContainer leaves; 
    985         leaves.reserve(node->GetNumLeaves()); 
    986  
    987         CollectVisibleLeaves(node, leaves); 
    988  
    989         if (leaves.empty()) 
    990                 return NULL; 
    991  
    992         const int r = (int)(((float)rand() / RAND_MAX) * ((float)leaves.size() - 0.5f)); 
    993  
    994         return leaves[r]; 
    995 } 
    996  
    997  
    998 void Bvh::CollectGeometry(BvhNode *node, GeometryVector &geometry) 
    999 { 
    1000         //geometry.reserve(node->CountPrimitives()); 
    1001  
    1002         for (int i = node->mFirst; i <= node->mLast; ++ i) 
    1003         { 
    1004                 geometry.push_back(mGeometry[i]); 
    1005         } 
    1006 } 
    1007  
    1008  
    1009 NodeGeometry **Bvh::GetGeometry(BvhNode *node, int &geometrySize) 
     308SceneEntity **Bvh::GetGeometry(BvhNode *node, int &geometrySize) 
    1010309{ 
    1011310        geometrySize = node->CountPrimitives(); 
     
    1014313 
    1015314 
    1016 void Bvh::UpdateInteriors(BvhNode *node) 
    1017 { 
    1018         if (!node->IsLeaf()) 
    1019         { 
    1020                 BvhInterior *interior = static_cast<BvhInterior *> (node); 
    1021                  
    1022                 // update the indices of the geometry so we can render interiors as well 
    1023                 UpdateInteriors(interior->GetBack()); 
    1024                 UpdateInteriors(interior->GetFront()); 
    1025  
    1026                 // update area 
    1027                 interior->mFirst = min(interior->GetBack()->mFirst, interior->GetFront()->mFirst); 
    1028                 interior->mLast = max(interior->GetBack()->mLast, interior->GetFront()->mLast); 
    1029          
    1030                 interior->mArea = interior->GetBack()->mArea + interior->GetFront()->mArea; 
    1031         } 
    1032 } 
    1033  
    1034  
    1035 int     Bvh::IsWithinViewFrustumLocal(BvhNode *node) 
     315int     Bvh::IsWithinViewFrustum(BvhNode *node) 
    1036316{ 
    1037317        bool bIntersect = false; 
     
    1050330                { 
    1051331                        //-- test the n-vertex 
    1052                         if (node->mBox.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f) 
     332                        if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 0], sFrustum.mClipPlanes[i]) > 0.0f) 
    1053333                        { 
    1054334                                //-- outside 
     
    1058338 
    1059339                        //-- test the p-vertex 
    1060                         if (node->mBox.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f) 
     340                        if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 1], sFrustum.mClipPlanes[i]) <= 0.0f) 
    1061341                        { 
    1062342                                //-- completely inside: children don't need to check against this plane no more 
     
    1079359                { 
    1080360                        //-- test the n-vertex 
    1081                         if (node->mBox.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f) 
     361                        if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 0], sFrustum.mClipPlanes[i]) > 0.0f) 
    1082362                        { 
    1083363                                // outside 
     
    1087367 
    1088368                        //-- test the p-vertex 
    1089                         if (node->mBox.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f) 
     369                        if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 1], sFrustum.mClipPlanes[i]) <= 0.0f) 
    1090370                        { 
    1091371                                // completely inside: children don't need to check against this plane no more 
     
    1103383 
    1104384 
    1105 int     Bvh::IsWithinViewFrustum(const BoundingBox &box, const int planeMask, const int preferredPlane) 
    1106 { 
    1107         bool bIntersect = false; 
    1108  
    1109         //////// 
    1110         //-- do the view frustum culling for the planes [mPreferredPlane - 5] 
    1111  
    1112         for (int i = preferredPlane; i < 6; ++ i) 
    1113         { 
    1114                 //-- do the test only if necessary 
    1115                 if (planeMask & (1 << i)) 
    1116                 { 
    1117                         //-- test the n-vertex 
    1118                         if (box.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f) 
    1119                                 return 0; 
    1120  
    1121                         //-- test the p-vertex 
    1122                         if (!(box.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f)) 
    1123                                 bIntersect = true; 
    1124                 } 
    1125         } 
    1126  
    1127         ////////// 
    1128         //-- do the view frustum culling for the planes [0 - m_iPreferredPlane) 
    1129  
    1130         for (int i = 0; i < preferredPlane; ++ i) 
    1131         { 
    1132                 // do the test only if necessary 
    1133                 if (planeMask & (1 << i)) 
    1134                 { 
    1135                         //-- test the n-vertex 
    1136                         if (box.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f) 
    1137                                 // outside 
    1138                                 return 0; 
    1139  
    1140                         //-- test the p-vertex 
    1141                         if (!(box.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f)) 
    1142                                 bIntersect = true; 
    1143                 } 
    1144         } 
    1145  
    1146         return bIntersect ? -1 : 1; 
    1147 } 
    1148  
    1149  
    1150 int     Bvh::IsWithinViewFrustum(BvhNode *node) 
    1151 { 
    1152         if (node->mCache.mLastFrustumTestedFrameId == mFrameId) 
    1153         { 
    1154                 return node->mCache.mFrustumCulled; 
    1155         } 
    1156  
    1157         node->mCache.mLastFrustumTestedFrameId = mFrameId; 
    1158  
    1159         timeViewFrustumCulling.Entry(); 
    1160          
    1161         if (Settings::Global()->get_nvocc_use_tighter_bounds_for_frustum_culling()) 
    1162         { 
    1163                 const int intersect = IsWithinViewFrustumLocal(node); 
    1164  
    1165                 if ((node->mNumTestNodes == 1) || (intersect != -1)) 
    1166                 { 
    1167                         //OUT1("x"); 
    1168                         node->mCache.mFrustumCulled = intersect; 
    1169                 } 
    1170                 else  
    1171                 { 
    1172                         // maybe intersecting one of the tighter boxes 
    1173                         node->mCache.mFrustumCulled = 0; 
    1174  
    1175                         for (int i = 0; i < node->mNumTestNodes; ++ i) 
    1176                         { 
    1177                                 RenderableHierarchyNode *n = mTestNodes[node->mTestNodesIdx + i]; 
    1178  
    1179                                 if (IsWithinViewFrustum(n->GetBox(),  
    1180                                                                                 node->mPlaneMask,  
    1181                                                                                 node->mPreferredPlane)) 
    1182                                 { 
    1183                                         node->mCache.mFrustumCulled = -1; 
    1184                                         break; 
    1185                                 } 
    1186                         } 
    1187                 } 
    1188         } 
    1189         else 
    1190         { 
    1191                 //OUT1("y"); 
    1192                 node->mCache.mFrustumCulled = IsWithinViewFrustumLocal(node); 
    1193         } 
    1194  
    1195         timeViewFrustumCulling.Exit(); 
    1196  
    1197         return node->mCache.mFrustumCulled; 
    1198 } 
    1199  
    1200  
    1201 void Bvh::InitFrame(Camera *camera, const int currentFrameId, Viewer *viewer) 
     385void Bvh::InitFrame(Camera *camera, int currentFrameId) 
    1202386{ 
    1203387        // = 0011 1111 which means that at the beginning, all six planes have to frustum culled 
     
    1207391        mFrameId = currentFrameId; 
    1208392 
    1209         // to begin with, we must grab the plane equations of the six clipplanes of the viewfrustum 
    1210         Matrix4f matViewing, matProjectionView; 
    1211         Transform3D     transform; 
    1212  
    1213         camera->GetTransform(transform); 
    1214         transform.get(matViewing); 
    1215  
    1216         camera->GetProjectionMatrix(matProjectionView); 
    1217         matProjectionView *= matViewing; 
    1218  
    1219         Vec3f vec; 
    1220         float fInvLength; 
    1221  
    1222  
    1223         ////////// 
    1224         //-- extract the plane equations 
    1225  
    1226         for (int i = 0; i < 4; ++ i) 
    1227         { 
    1228                 mFrustum.mClipPlane[0][i] = matProjectionView[i][3] - matProjectionView[i][0];  // right plane 
    1229                 mFrustum.mClipPlane[1][i] = matProjectionView[i][3] + matProjectionView[i][0];  // left plane 
    1230                 mFrustum.mClipPlane[2][i] = matProjectionView[i][3] + matProjectionView[i][1];  // bottom plane 
    1231                 mFrustum.mClipPlane[3][i] = matProjectionView[i][3] - matProjectionView[i][1];  // top plane 
    1232                 mFrustum.mClipPlane[4][i] = matProjectionView[i][3] - matProjectionView[i][2];  // far plane 
    1233                 mFrustum.mClipPlane[5][i] = matProjectionView[i][3] + matProjectionView[i][2];  // near plane 
    1234         } 
    1235  
    1236         //////////// 
    1237         //-- normalize the coefficients and find the indices of the n- and p-vertices 
    1238  
    1239         for (int i = 0; i < 6; ++ i) 
    1240         { 
    1241                 // the clipping planes look outward the frustum, 
    1242                 // so distances > 0 mean that a point is outside 
    1243                 fInvLength      = -1.0f / sqrt( mFrustum.mClipPlane[i][0] * mFrustum.mClipPlane[i][0] +  
    1244                                                                         mFrustum.mClipPlane[i][1] * mFrustum.mClipPlane[i][1] +  
    1245                                                                         mFrustum.mClipPlane[i][2] * mFrustum.mClipPlane[i][2]); 
    1246  
    1247                 mFrustum.mClipPlane[i][0] *= fInvLength; 
    1248                 mFrustum.mClipPlane[i][1] *= fInvLength; 
    1249                 mFrustum.mClipPlane[i][2] *= fInvLength; 
    1250                 mFrustum.mClipPlane[i][3] *= fInvLength; 
    1251  
    1252                 vec.x = mFrustum.mClipPlane[i][0]; 
    1253                 vec.y = mFrustum.mClipPlane[i][1]; 
    1254                 vec.z = mFrustum.mClipPlane[i][2]; 
    1255  
    1256                 // n-vertex 
    1257                 mClipPlaneAABBVertexIndices[i][0] = BoundingBox::getIndexNearestVertex(vec); 
    1258                 // p-vertex 
    1259                 mClipPlaneAABBVertexIndices[i][1] = BoundingBox::getIndexFurthestVertex(vec);    
    1260         } 
    1261  
    1262  
    1263         const float aspect = mCamera->GetAspect(); 
    1264         const float fov = mCamera->GetFov(); 
    1265          
    1266         mScale = sqrt(aspect) * 2.0f * tan(fov * mypi / 180.0f); 
    1267  
    1268         mNearPlane = mCamera->GetRealViewDirection(); 
    1269         mNearPlaneD = - mNearPlane * (mCamera->GetPosition() - Origin3f); 
     393        mCamera->CalcFrustum(sFrustum); 
     394        sFrustum.CalcNPVertexIndices(sClipPlaneAABBVertexIndices); 
     395 
     396        // calc near plane 
     397        sNearPlane = Plane3(mCamera->GetDirection(),  
     398                                -mCamera->GetDirection() * mCamera->GetPosition()); 
    1270399} 
    1271400 
     
    1273402float Bvh::CalcDistance(BvhNode *node) const 
    1274403{ 
    1275         timeDistance.Entry(); 
    1276  
    1277         float distance; 
    1278  
    1279 #if USE_TIGHTER_BOUNDS_FOR_ALL 
    1280         float minDist = 1e25f; 
    1281  
    1282         //OUT1("testing " << mNumTestNodes << " nodes"); 
    1283         for (int i = 0; i < node->mNumTestNodes; ++ i) 
    1284         { 
    1285                 RenderableHierarchyNode *hnode = mTestNodes[node->mTestNodesIdx + i]; 
    1286  
    1287                 if(hnode->mCache.mLastDistanceTestedFrameId < mFrameId) 
    1288                 { 
    1289                         hnode->mCache.mDistance =  
    1290                                 hnode->GetBox().getMinVisibleDistance(mNearPlane, mNearPlaneD); 
    1291                         hnode->mCache.mLastDistanceTestedFrameId = mFrameId; 
    1292                 } 
    1293  
    1294                 if (hnode->mCache.mDistance < minDist) 
    1295                         minDist = hnode->mCache.mDistance; 
    1296         } 
    1297  
    1298         distance = minDist; 
    1299  
    1300 #else 
    1301  
    1302         if(node->mCache.mLastDistanceTestedFrameId != mFrameId) 
    1303         { 
    1304                 //OUT1("z " << node->mLastDistanceTestedFrameId  << " " << mFrameId); 
    1305                 node->mCache.mDistance = node->GetBox().getMinVisibleDistance(mNearPlane, mNearPlaneD); 
    1306                 node->mCache.mLastDistanceTestedFrameId = mFrameId; 
    1307         } 
    1308  
    1309         distance = node->mCache.mDistance; 
    1310 #endif 
    1311  
    1312         timeDistance.Exit(); 
    1313  
    1314         return distance; 
    1315 } 
    1316  
    1317  
    1318 float Bvh::GetSquareDistance(BvhNode *node) const 
    1319 { 
    1320         timeDistance.Entry(); 
    1321  
    1322         float distance; 
    1323  
    1324 #if USE_TIGHTER_BOUNDS_FOR_ALL 
    1325         const Vector3f nearplane = mCamera->GetRealViewDirection(); 
    1326         const float nearplaneD = - nearplane * (mCamera->GetPosition() - Origin3f); 
    1327  
    1328         float minDist = 1e25f; 
    1329          
    1330         //OUT1("testing " << mNumTestNodes << " nodes"); 
    1331         for (int i = 0; i < node->mNumTestNodes; ++ i) 
    1332         { 
    1333                 RenderableHierarchyNode *hnode = mTestNodes[node->mTestNodesIdx + i]; 
    1334                 const float dist = GetMinSquareDistance(hnode->GetBox()); 
    1335  
    1336                 if (dist < minDist) 
    1337                         minDist = dist; 
    1338         } 
    1339  
    1340         distance = minDist; 
    1341 #else 
    1342         distance = GetMinSquareDistance(node->GetBox()); 
    1343 #endif 
    1344  
    1345         timeDistance.Exit(); 
    1346  
    1347         return distance; 
    1348 } 
    1349  
    1350  
    1351 float Bvh::GetMinSquareDistance(const BoundingBox &box) const 
    1352 { 
    1353         float minDist = 1e25f; 
    1354  
    1355         const Point3f *pts = (const Point3f *)box.getVertexData(); 
    1356         const Point3f pos = mCamera->GetPosition(); 
    1357  
    1358         for (int i = 0; i < 8; ++ i) 
    1359         { 
    1360                 const float newDist = DistanceSquared(pts[i], pos); 
    1361  
    1362                 if (newDist < minDist) 
    1363                         minDist = newDist; 
    1364         } 
    1365  
    1366         return minDist; 
    1367 } 
    1368  
    1369  
    1370 bool Bvh::ExportBinTree(const string &filename) 
    1371 { 
    1372         ofstream stream(filename.c_str(), ifstream::binary); 
    1373          
    1374         if (!stream.is_open()) return false; 
    1375  
    1376         OUT1("exporting bvh"); 
    1377  
    1378         std::queue<BvhNode *> tStack; 
    1379         tStack.push(mRoot); 
    1380  
    1381         while(!tStack.empty()) 
    1382         { 
    1383                 BvhNode *node = tStack.front(); 
    1384                 tStack.pop(); 
    1385                  
    1386                 if (node->IsLeaf()) 
    1387                 { 
    1388                         //OUT1("l"); 
    1389                         ExportBinLeaf(stream, static_cast<BvhLeaf *>(node)); 
    1390                 } 
    1391                 else 
    1392                 { 
    1393                         //OUT1("i"); 
    1394                         BvhInterior *interior = static_cast<BvhInterior *>(node); 
    1395  
    1396                         ExportBinInterior(stream, interior); 
    1397                          
    1398                         tStack.push(interior->mFront); 
    1399                         tStack.push(interior->mBack); 
    1400                 } 
    1401         } 
    1402  
    1403         OUT1("... finished"); 
    1404  
    1405         return true; 
    1406 } 
    1407  
    1408  
    1409 void Bvh::ExportBinLeaf(ofstream &stream, BvhLeaf *leaf) 
    1410 { 
    1411         int type = TYPE_LEAF; 
    1412         int first = leaf->mFirst; 
    1413         int last = leaf->mLast; 
    1414  
    1415         stream.write(reinterpret_cast<char *>(&type), sizeof(int)); 
    1416         stream.write(reinterpret_cast<char *>(&first), sizeof(int)); 
    1417         stream.write(reinterpret_cast<char *>(&last), sizeof(int)); 
    1418 } 
    1419  
    1420  
    1421 void Bvh::ExportBinInterior(ofstream &stream, BvhInterior *interior) 
    1422 { 
    1423         int type = TYPE_INTERIOR; 
    1424         stream.write(reinterpret_cast<char *>(&type), sizeof(int)); 
    1425         stream.write(reinterpret_cast<char *>(&interior->mAxis), sizeof(char)); 
    1426         stream.write(reinterpret_cast<char *>(&interior->mPosition), sizeof(float)); 
    1427 } 
    1428  
    1429  
    1430 BvhLeaf *Bvh::ImportBinLeaf(ifstream &stream, BvhInterior *parent) 
    1431 { 
    1432         BvhLeaf *leaf = new BvhLeaf(parent); 
    1433  
    1434         int first, last; 
    1435  
    1436         stream.read(reinterpret_cast<char *>(&first), sizeof(int)); 
    1437         stream.read(reinterpret_cast<char *>(&last), sizeof(int)); 
    1438  
    1439         leaf->mFirst = first; 
    1440         leaf->mLast = last; 
    1441  
    1442         return leaf; 
    1443 } 
    1444  
    1445  
    1446 BvhInterior *Bvh::ImportBinInterior(ifstream &stream, BvhInterior *parent) 
    1447 { 
    1448         BvhInterior *interior = new BvhInterior(parent); 
    1449  
    1450         stream.read(reinterpret_cast<char *>(&interior->mAxis), sizeof(char)); 
    1451         stream.read(reinterpret_cast<char *>(&interior->mPosition), sizeof(float)); 
    1452  
    1453         return interior; 
    1454 } 
    1455  
    1456  
    1457 BvhNode *Bvh::LoadNextNode(ifstream &stream, BvhInterior *parent) 
    1458 { 
    1459         int nodeType; 
    1460         stream.read(reinterpret_cast<char *>(&nodeType), sizeof(int)); 
    1461  
    1462         if (nodeType == TYPE_LEAF) 
    1463         { 
    1464                 //OUT1("l"); 
    1465                 return ImportBinLeaf(stream, static_cast<BvhInterior *>(parent)); 
    1466         } 
    1467  
    1468         if (nodeType == TYPE_INTERIOR) 
    1469         { 
    1470                 //OUT1("i"); 
    1471                 return ImportBinInterior(stream, static_cast<BvhInterior *>(parent)); 
    1472         } 
    1473  
    1474         return NULL; 
    1475 } 
    1476  
    1477  
    1478 Bvh *Bvh::LoadFromFile(const string &filename, const GeometryVector &geom) 
    1479 { 
    1480         // export binary version of mesh 
    1481         queue<BvhNode *> tStack; 
    1482         ifstream stream(filename.c_str(), ifstream::binary); 
    1483  
    1484         if (!stream.is_open()) return NULL; 
    1485  
    1486         OUT1("loading bvh"); 
    1487         Bvh *bvh = new Bvh(); 
    1488  
    1489         bvh->mGeometrySize = geom.size(); 
    1490         bvh->mGeometry = new NodeGeometry*[bvh->mGeometrySize]; 
    1491  
    1492         for (size_t i = 0; i < bvh->mGeometrySize; ++ i) 
    1493                 bvh->mGeometry[i] = geom[i]; 
    1494  
    1495         bvh->mRoot = bvh->LoadNextNode(stream, NULL); 
    1496  
    1497         tStack.push(bvh->mRoot); 
    1498         bvh->mNumNodes = 1; 
    1499  
    1500         while(!tStack.empty()) 
    1501         { 
    1502                 BvhNode *node = tStack.front(); 
    1503                 tStack.pop(); 
    1504  
    1505                 if (!node->IsLeaf()) 
    1506                 { 
    1507                         bvh->mNumNodes += 2; 
    1508  
    1509                         BvhInterior *interior = static_cast<BvhInterior *>(node); 
    1510  
    1511             BvhNode *front = bvh->LoadNextNode(stream, interior); 
    1512                         BvhNode *back = bvh->LoadNextNode(stream, interior); 
    1513          
    1514                         interior->mFront = front; 
    1515                         interior->mBack = back; 
    1516  
    1517                         front->mDepth = interior->mDepth + 1; 
    1518                         back->mDepth = interior->mDepth + 1; 
    1519  
    1520                         tStack.push(front);                      
    1521                         tStack.push(back); 
    1522                 } 
    1523         } 
    1524  
    1525         OUT1("... finished loading " << bvh->mNumNodes << " nodes, updating boxes"); 
    1526  
    1527         //adjust bounding boxes 
    1528         bvh->UpdateBoxes(bvh->mRoot); 
    1529         bvh->UpdateNumLeaves(bvh->mRoot); 
    1530  
    1531         // compute unique ids 
    1532         bvh->ComputeIds(); 
    1533         // update the indices of the geometry so we can render interiors as well 
    1534         bvh->UpdateInteriors(bvh->mRoot); 
    1535         // do this once so at least the current node bounding box is tested 
    1536         bvh->RecomputeBounds(); 
    1537  
    1538         return bvh; 
    1539 } 
    1540  
    1541  
    1542 float Bvh::ComputeScreenSpaceProjection(BvhNode *node) const 
    1543 { 
    1544 #if 0 
    1545         int projection = 0; 
    1546  
    1547         for (int i = 0; i < node->mNumTestNodes; ++ i) 
    1548         { 
    1549                 RenderableHierarchyNode *n = mTestNodes[node->mTestNodesIdx + i]; 
    1550  
    1551                 if(hnode->.mCache.mLastProjectionFrameId < mFrameId) 
    1552                 { 
    1553                         hnode->mCache.mProjection =  
    1554                                 ComputeScreenSpaceProjection(hnode->GetBox()); 
    1555                         hnode->mCache.mLastProjectionFrameId = mCurrentFrameId; 
    1556                 } 
    1557                  
    1558                 projection += hnode->mCache.mProjection; 
    1559         } 
    1560  
    1561         return projection; 
    1562  
    1563 #else 
    1564  
    1565         if(node->mCache.mLastProjectionFrameId < mFrameId) 
    1566         { 
    1567                 node->mCache.mProjection =  
    1568                         ComputeScreenSpaceProjection(node->GetBox()); 
    1569                 node->mCache.mLastProjectionFrameId = mFrameId; 
    1570         } 
    1571  
    1572         return node->mCache.mProjection; 
    1573 #endif 
    1574 } 
    1575  
    1576  
    1577 float Bvh::ComputeScreenSpaceProjection(const BoundingBox &box) const 
    1578 { 
    1579 #if 0 
    1580         const float dist = CalcDistance(box); 
    1581 #else 
    1582         //const float dist = sqrt(GetMinSquareDistance(box)); 
    1583         const float dist = Distance(mCamera->GetPosition(), box.getCenter()); 
    1584 #endif 
    1585  
    1586         const float scale = dist ? dist * mScale : 1e-6; 
    1587         const float f = 1.0f / scale; 
    1588         const float coverage = f * f * box.getSurface() / 6.0f; 
    1589  
    1590 #if 0 
    1591         OUT1("scale: " << scale); 
    1592         OUT1("box: " << box.getSurface()); 
    1593         OUT1("aspect: " << aspect); 
    1594         OUT1("fov: " << fov); 
    1595         OUT1("tan: " << tan(fov * mypi / 180.0f)); 
    1596         //OUT1("w: " << w << " h: " << h); 
    1597         OUT1("cov: " << coverage << " pix: " << coverage * w * h << " f: " << f); 
    1598 #endif 
    1599         return coverage; 
     404        return node->GetBox().GetMinVisibleDistance(sNearPlane); 
    1600405} 
    1601406 
     
    1603408void Bvh::RenderBoundingBox(BvhNode *node) 
    1604409{ 
    1605 #if 1 
    1606410        static BvhNodeContainer dummy(1); 
    1607411        dummy[0] = node; 
    1608412        RenderBoundingBoxes(dummy); 
    1609 #else 
    1610         RenderBoxIndividual(node); 
    1611 #endif 
    1612 } 
    1613  
    1614  
    1615 void Bvh::RenderBoundingBoxImmediate(const BoundingBox &box, const bool restartStrip) 
    1616 { 
    1617         const Point3f *pU = box.getUpperPtr(); 
    1618         const Point3f *pL = box.getLowerPtr(); 
    1619  
    1620         /////////// 
    1621         //-- render AABB as triangle strips 
    1622  
    1623         glVertex3f(pL->x, pL->y, pU->z); 
    1624         glVertex3f(pU->x, pL->y, pU->z); 
    1625         glVertex3f(pL->x, pU->y, pU->z); 
    1626         glVertex3f(pU->x, pU->y, pU->z); 
    1627         glVertex3f(pL->x, pU->y, pL->z);  
    1628         glVertex3f(pU->x, pU->y, pL->z); 
    1629         glVertex3f(pL->x, pL->y, pL->z);  
    1630         glVertex3f(pU->x, pL->y, pL->z); 
    1631  
    1632         glPrimitiveRestartNV(); 
    1633  
    1634         //-- render second half of AABB 
    1635         glVertex3f(pL->x, pU->y, pU->z);  
    1636         glVertex3f(pL->x, pU->y, pL->z); 
    1637         glVertex3f(pL->x, pL->y, pU->z); 
    1638         glVertex3f(pL->x, pL->y, pL->z); 
    1639         glVertex3f(pU->x, pL->y, pU->z);  
    1640         glVertex3f(pU->x, pL->y, pL->z); 
    1641         glVertex3f(pU->x, pU->y, pU->z);  
    1642         glVertex3f(pU->x, pU->y, pL->z); 
    1643  
    1644          
    1645         // restart for all but last node 
    1646         if (restartStrip) 
    1647         { 
    1648                 glPrimitiveRestartNV(); 
    1649         } 
    1650 } 
    1651  
    1652  
    1653 int Bvh::RenderBoundingBoxesImmediate(const BvhNodeContainer &nodes) 
    1654 { 
    1655         timeSetup.Entry(); 
    1656         int renderedBoxes = 0; 
    1657          
    1658         glBegin(GL_TRIANGLE_STRIP); 
    1659  
    1660         BvhNodeContainer::const_iterator bit, bit_end = nodes.end(); 
    1661  
    1662         for (bit = nodes.begin(); bit != bit_end; ++ bit) 
    1663         { 
    1664                 BvhNode *node = *bit; 
    1665  
    1666                 renderedBoxes += node->mNumTestNodes; 
    1667 #if 0 
    1668                 const bool restartStrip = false; 
    1669                 RenderBoundingBoxImmediate(node->GetBox(), restartStrip); 
    1670 #else 
    1671                 //OUT1("nodes: " << node->mTestNodes.size() << " l: " << node->IsLeaf()); 
    1672                 for (int i = 0; i < node->mNumTestNodes; ++ i) 
    1673                 { 
    1674                         RenderableHierarchyNode *testNode = mTestNodes[node->mTestNodesIdx + i]; 
    1675                         const BoundingBox &box = testNode->GetBox(); 
    1676  
    1677                         // restart for all but last node 
    1678                         const bool restartStrip = (bit != bit_end - 1) || (i != node->mNumTestNodes - 1); 
    1679  
    1680                         RenderBoundingBoxImmediate(box, restartStrip); 
    1681                 } 
    1682 #endif 
    1683         } 
    1684         glEnd(); 
    1685         timeSetup.Exit(); 
     413} 
     414 
     415 
     416 
     417int Bvh::RenderBoundingBoxes(const BvhNodeContainer &nodes) 
     418{ 
     419        int renderedBoxes = PrepareBoundingBoxesWithDrawArrays(nodes); 
     420        RenderBoundingBoxesWithDrawArrays(renderedBoxes); 
    1686421 
    1687422        return renderedBoxes; 
    1688 } 
    1689  
    1690  
    1691 int Bvh::RenderBoundingBoxes(const BvhNodeContainer &nodes) 
    1692 { 
    1693         // always render in immediate mode if there is only one box to render 
    1694         if (((nodes.size() == 1) && (nodes[0]->mNumTestNodes == 1)) ||  
    1695                 !Settings::Global()->get_nvocc_use_index_arrays()) 
    1696         {        
    1697                 // render bounding boxes individually 
    1698                 return RenderBoundingBoxesImmediate(nodes); 
    1699         } 
    1700         else  
    1701         { 
    1702                 const int renderedBoxes =  
    1703                         PrepareBoundingBoxesWithDrawArrays(nodes); 
    1704                 RenderBoundingBoxesWithDrawArrays(renderedBoxes); 
    1705  
    1706                 return renderedBoxes; 
    1707         } 
    1708423} 
    1709424 
     
    1726441 
    1727442        /////////////// 
    1728  
    1729         timeSetup.Entry(); 
    1730443 
    1731444        int numNodes = 0; 
     
    1750463        } 
    1751464 
    1752         timeSetup.Exit(); 
    1753  
    1754465        return numNodes; 
    1755466} 
    1756467 
    1757468 
    1758 void Bvh::RenderBoundingBoxesWithDrawArrays(const int numNodes) 
     469void Bvh::RenderBoundingBoxesWithDrawArrays(int numNodes) 
    1759470{ 
    1760471        ////// 
    1761472        //-- Rendering the vbo 
    1762  
    1763         timeIssueDrawElements.Entry(); 
    1764  
    1765473        if (useVbos) 
    1766474                // set the vertex pointer to the vertex buffer 
     
    1774482        // don't render first degenerate index 
    1775483        glDrawElements(GL_TRIANGLE_STRIP, numElements, GL_UNSIGNED_INT, mIndices + 1);  
    1776          
    1777         timeIssueDrawElements.Exit(); 
    1778484} 
    1779485 
     
    1787493        CollectNodes(mRoot, nodes); 
    1788494 
    1789         OUT1("creating new indices"); 
     495        cout << "creating new indices" << endl; 
    1790496 
    1791497        int numMaxIndices = 0; 
     
    1804510 
    1805511 
    1806         OUT1("creating global indices buffer"); 
     512        cout << "creating global indices buffer" << endl; 
    1807513 
    1808514        if (mIndices) delete [] mIndices; 
     
    1831537                for (int i = 0; i < node->mNumTestNodes; ++ i, numIndices += sNumIndicesPerBox) 
    1832538                { 
    1833                         RenderableHierarchyNode *testNode = mTestNodes[node->mTestNodesIdx + i]; 
     539                        BvhNode *testNode = mTestNodes[node->mTestNodesIdx + i]; 
    1834540 
    1835541                        // add indices to root node 
     
    1851557 
    1852558 
     559/* 
    1853560void Bvh::ComputeIds() 
    1854561{ 
     
    1856563        // warning: root nodes local bvh are not in there, as they  
    1857564        // are equivalent geometry bvh leaves 
    1858         HierarchyNodeContainer nodes; 
     565        BvhNodeContainer nodes; 
    1859566        CollectAllNodes(mRoot, nodes); 
    1860567 
     
    1868575        } 
    1869576} 
    1870  
     577*/ 
    1871578 
    1872579void Bvh::PrepareVertices() 
    1873580{ 
    1874         // collect all nodes, also the nodes from local bvh 
    1875         // warning: root nodes local bvh are not in there, as they  
    1876         // are equivalent geometry bvh leaves 
    1877         HierarchyNodeContainer nodes; 
     581        // collect all nodes 
     582        BvhNodeContainer nodes; 
    1878583 
    1879584        nodes.reserve(GetNumNodes()); 
    1880         CollectAllNodes(mRoot, nodes); 
     585        CollectNodes(mRoot, nodes); 
    1881586 
    1882587        const unsigned int bufferSize = 8 * (int)nodes.size(); 
    1883         mVertices = new Point3f[bufferSize]; 
     588        mVertices = new Vector3[bufferSize]; 
    1884589         
    1885590        int i = 0; 
    1886591         
    1887592        // store bounding box vertices 
    1888         HierarchyNodeContainer::const_iterator lit, lit_end = nodes.end(); 
     593        BvhNodeContainer::const_iterator lit, lit_end = nodes.end(); 
    1889594 
    1890595        for (lit = nodes.begin(); lit != lit_end; ++ lit, i += 8) 
    1891596        { 
    1892                 RenderableHierarchyNode *node = *lit; 
    1893                 const Point3f *vertices = (const Point3f *)node->GetBox().getVertexData(); 
     597                BvhNode *node = *lit; 
    1894598 
    1895599                for (int j = 0; j < 8; ++ j) 
    1896                 {        
    1897                         ((Point3f *)mVertices)[node->GetId() * 8 + j] = vertices[j]; 
    1898                 } 
     600                        ((Vector3 *)mVertices)[node->GetId() * 8 + j] = node->GetBox().GetVertex(j); 
    1899601        } 
    1900602 
     
    1906608         
    1907609                glBufferDataARB(GL_ARRAY_BUFFER_ARB,  
    1908                                     bufferSize * sizeof(Point3f),  
     610                                    bufferSize * sizeof(Vector3),  
    1909611                                    mVertices,  
    1910612                                                GL_STATIC_DRAW_ARB); 
     
    1913615 
    1914616                // data handled by graphics driver from now on 
    1915                 DELAPTR(mVertices); 
    1916  
    1917                 OUT1("***** created vbos *********"); 
     617                DEL_PTR(mVertices); 
     618 
     619                cout << "***** created vbos *********" << endl; 
    1918620        } 
    1919621        else 
     
    1922624        glVertexPointer(3, GL_FLOAT, 0, mVertices); 
    1923625 
    1924                 OUT1("created vertices"); 
    1925         } 
    1926 } 
    1927  
    1928  
    1929 void Bvh::SetMaxDepthForTestingChildren(const int maxDepth)  
     626                cout << "******* created vertex arrays ********" << endl; 
     627        } 
     628} 
     629 
     630 
     631void Bvh::SetMaxDepthForTestingChildren(int maxDepth)  
    1930632{ 
    1931633        if (maxDepth != mMaxDepthForTestingChildren) 
     
    1937639 
    1938640 
    1939 void Bvh::SetAreaRatioThresholdForTestingChildren(const float ratio)  
     641void Bvh::SetAreaRatioThresholdForTestingChildren(float ratio)  
    1940642{ 
    1941643        if (ratio != mAreaRatioThreshold) 
    1942644        { 
    1943645                mAreaRatioThreshold = ratio; 
    1944                 RecomputeBounds(); 
    1945         } 
    1946 } 
    1947  
    1948  
    1949 void Bvh::SetVolRatioThresholdForTestingChildren(const float ratio)  
    1950 { 
    1951         if (ratio != mVolRatioThreshold) 
    1952         { 
    1953                 mVolRatioThreshold = ratio; 
    1954                 RecomputeBounds(); 
    1955         } 
    1956 } 
    1957  
    1958  
    1959 void Bvh::SetUseTighterBoundsForTests(const bool tighterBoundsForTests) 
    1960 { 
    1961         if (mUseTighterBoundsOnlyForLeafTests != tighterBoundsForTests) 
    1962         { 
    1963                 mUseTighterBoundsOnlyForLeafTests = tighterBoundsForTests; 
    1964                 RecomputeBounds(); 
    1965         } 
    1966 } 
    1967  
    1968  
    1969 void Bvh::SetCollectTighterBoundsWithMaxLevel(bool t) 
    1970 { 
    1971         if (mCollectTighterBoundsWithMaxLevel != t) 
    1972         { 
    1973                 mCollectTighterBoundsWithMaxLevel = t; 
    1974646                RecomputeBounds(); 
    1975647        } 
     
    1986658        CollectNodes(mRoot, nodes); 
    1987659 
    1988         OUT1("recomputing bounds, children will be tested in depth " << mMaxDepthForTestingChildren); 
    1989  
    1990         if (mCollectTighterBoundsWithMaxLevel) 
    1991                 OUT1("creating tighter bounds using max level"); 
    1992         else 
    1993                 OUT1("creating tighter bounds using best set"); 
     660        cout << "recomputing bounds, children will be tested in depth " << mMaxDepthForTestingChildren << endl; 
    1994661 
    1995662        int success = 0; 
     
    2000667                BvhNode *node = *lit; 
    2001668 
    2002                 if (mCollectTighterBoundsWithMaxLevel) 
    2003                 { 
    2004                         //OUT1("creating tighter bounds using max level"); 
    2005  
    2006                         // recreate list of nodes that will be tested as a proxy ... 
    2007                         if (CreateNodeRenderList(node)) 
    2008                                 ++ success; 
    2009                 } 
    2010                 else 
    2011                 { 
    2012                         //OUT1("creating tighter bounds using best set"); 
    2013  
    2014                         HierarchyNodeContainer hnodes; 
    2015                         CollectBestNodes(node, hnodes);  
    2016  
    2017                         // the new test nodes are added at the end of the vector 
    2018                         node->mTestNodesIdx = mTestNodes.size(); 
    2019  
    2020                         HierarchyNodeContainer::const_iterator cit; 
    2021  
    2022                         // use the found nodes as nodes during the occlusion tests 
    2023                         for (cit = hnodes.begin(); cit != hnodes.end(); ++ cit) 
    2024                         { 
    2025                                 RenderableHierarchyNode *child = *cit; 
    2026                                 mTestNodes.push_back(child); 
    2027                         } 
    2028  
    2029                         node->mNumTestNodes = (int)hnodes.size(); 
    2030                 } 
    2031                 //OUT1("testnodes: " << node->mNumTestNodes); 
    2032         } 
    2033  
    2034         const float p = 100.0f * (float)success / nodes.size(); 
    2035  
    2036         OUT1("created tighter bounds for " << p << " percent of the nodes"); 
     669                // recreate list of nodes that will be tested as a proxy ... 
     670                if (CreateNodeRenderList(node)) 
     671                        ++ success; 
     672        } 
     673 
     674        float p = 100.0f * (float)success / nodes.size(); 
     675        cout << "created tighter bounds for " << p << " percent of the nodes" << endl; 
    2037676 
    2038677        // recreate indices used for indirect mode rendering 
    2039678        if (mIndices) 
    2040         { 
    2041679                CreateIndices(); 
    2042         } 
    2043680} 
    2044681 
     
    2046683bool Bvh::CreateNodeRenderList(BvhNode *node) 
    2047684{ 
    2048         HierarchyNodeContainer children; 
    2049  
    2050         if (mUseTighterBoundsOnlyForLeafTests && !node->IsLeaf()) 
    2051         { 
    2052                 children.push_back(node); 
    2053         } 
    2054         else 
    2055         { 
    2056                 // collect nodes that will be tested instead of the leaf node 
    2057                 // in order to get a tighter bounding box test 
    2058                 CollectNodes(node, mMaxDepthForTestingChildren, children); 
    2059         } 
    2060  
     685        BvhNodeContainer children; 
     686 
     687        // collect nodes that will be tested instead of the leaf node 
     688        // in order to get a tighter bounding box test 
     689        CollectNodes(node, children, mMaxDepthForTestingChildren); 
     690         
    2061691 
    2062692        // using the tighter bounds is not feasable in case 
     
    2068698        float area = 0; 
    2069699 
    2070         HierarchyNodeContainer::const_iterator cit; 
     700        BvhNodeContainer::const_iterator cit; 
    2071701 
    2072702        for (cit = children.begin(); cit != children.end(); ++ cit) 
    2073         { 
    2074                 RenderableHierarchyNode *c = *cit; 
    2075  
    2076                 area += c->GetBox().getSurface(); 
    2077                 vol += c->GetBox().getVolume(); 
    2078         } 
    2079  
    2080         const float volRatio = vol / node->GetBox().getVolume(); 
    2081         const float areaRatio = area / node->GetBox().getSurface(); 
     703                area += (*cit)->GetBox().SurfaceArea(); 
     704 
     705        const float areaRatio = area / node->GetBox().SurfaceArea(); 
    2082706         
    2083707        bool success; 
    2084708 
    2085         if ((areaRatio < mAreaRatioThreshold) && 
    2086                 (volRatio < mVolRatioThreshold)) 
    2087         { 
     709        if (areaRatio < mAreaRatioThreshold) 
    2088710                success = true; 
    2089         } 
    2090711        else 
    2091712        { 
     
    2098719 
    2099720        // the new test nodes are added at the end of the vector 
    2100         node->mTestNodesIdx = mTestNodes.size(); 
     721        node->mTestNodesIdx = (int)mTestNodes.size(); 
    2101722 
    2102723        // use the found nodes as nodes during the occlusion tests 
    2103724        for (cit = children.begin(); cit != children.end(); ++ cit) 
    2104725        { 
    2105                 RenderableHierarchyNode *child = *cit; 
     726                BvhNode *child = *cit; 
    2106727                mTestNodes.push_back(child); 
    2107728        } 
     
    2129750 
    2130751 
    2131 int Bvh::PostProcessLeaves(BvhLeafContainer &leaves) 
    2132 { 
    2133         OUT1("creating tighter bounds for leaves"); 
    2134  
    2135         BvhLeafContainer::const_iterator lit, lit_end = leaves.end(); 
    2136  
    2137         int i = 0; 
    2138         int tighter = 0; 
    2139  
    2140         for (lit = leaves.begin(); lit != lit_end; ++ lit, ++ i) 
    2141         { 
    2142                 BvhLeaf *leaf = *lit; 
    2143  
    2144                 int triangleCount; 
    2145                 // collect the triangles from the stored geometry 
    2146                 Point3f *triangles = CollectTriangles(leaf, triangleCount); 
    2147  
    2148                 if (CreateTighterBoundsForLeaf(leaf, triangles, triangleCount)) 
    2149                         ++ tighter; 
    2150  
    2151                 leaf->mArea = ComputeGeometryArea(leaf, triangles, triangleCount); 
    2152  
    2153                 delete [] triangles; 
    2154  
    2155                 if (i % 1000 == 999) 
    2156                         OUT1(i << " leaves processed "); 
    2157         } 
    2158  
    2159         const float p = 100.0f * tighter / leaves.size(); 
    2160         OUT1("created tighter bounds for " << p << " percent of the leaves"); 
    2161  
    2162         return tighter; 
    2163 } 
    2164  
    2165  
    2166 bool Bvh::CreateTighterBoundsForLeaf(BvhLeaf *leaf, Point3f *triangles, const int triangleCount) 
    2167 { 
    2168         // create a local bvh over the triangles 
    2169         if (leaf->mTriangleBvh) delete leaf->mTriangleBvh; 
    2170  
    2171         leaf->mTriangleBvh = new TriangleBvh((Triangle *)triangles, triangleCount); 
    2172  
    2173         const int maxDepth = Settings::Global()->get_nvocc_local_bvh_max_depth(); 
    2174         const int maxTriangles = Settings::Global()->get_nvocc_local_bvh_max_triangles(); 
    2175         const int minArea = Settings::Global()->get_nvocc_local_bvh_min_area(); 
    2176         const int splitType = Settings::Global()->get_nvocc_local_bvh_split_type(); 
    2177  
    2178         leaf->mTriangleBvh->SetMaxDepth(maxDepth); 
    2179         leaf->mTriangleBvh->SetMaxTriangles(maxTriangles); 
    2180         leaf->mTriangleBvh->SetMinAreaRatio(minArea); 
    2181         leaf->mTriangleBvh->SetSplitType(splitType); 
    2182          
    2183         leaf->mTriangleBvh->SetVerboseOutput(false); 
    2184  
    2185         // construct 
    2186         leaf->mTriangleBvh->Construct(); 
    2187  
    2188         return true; 
    2189 } 
    2190  
    2191  
    2192 float Bvh::ComputeGeometryArea(BvhLeaf *leaf, Point3f *triangles, const int triangleCount) const 
    2193 { 
    2194         float area = 0; 
    2195  
    2196         for (int i = 0; i < triangleCount; ++ i) 
    2197         { 
    2198                 area += ((Triangle *)triangles)[i].GetArea(); 
    2199         } 
    2200  
    2201         return area; 
    2202 } 
    2203  
    2204  
    2205 Point3f *Bvh::CollectTriangles(BvhLeaf *leaf, int &triangleCount) 
    2206 { 
    2207         // count triangles in the leaf 
    2208         triangleCount = 0; 
    2209  
    2210         for (int geomIdx = leaf->mFirst; geomIdx <= leaf->mLast; ++ geomIdx) 
    2211         { 
    2212                 Shape3D *sh = static_cast<Shape3D *>(mGeometry[geomIdx]->GetNode()); 
    2213                 IndexedTriangleStripArray *strips = static_cast<IndexedTriangleStripArray *>(sh->getGeometry()); 
    2214  
    2215                 triangleCount += strips->getNumTriangles(); 
    2216         } 
    2217  
    2218         Triangle *triangles = new Triangle[triangleCount]; 
    2219         //OUT1("The leaf contains " << triangleCount << " triangles in " << (int)geometry.size() << " nodes"); 
    2220  
    2221         int currentIdx = 0; 
    2222          
    2223         for (int geomIdx = leaf->mFirst; geomIdx <= leaf->mLast; ++ geomIdx) 
    2224         { 
    2225                 NodeGeometry *geom = mGeometry[geomIdx]; 
    2226  
    2227                 Shape3D *sh = static_cast<Shape3D *>(geom->GetNode()); 
    2228                  
    2229                 IndexedTriangleStripArray *strips =  
    2230                         static_cast<IndexedTriangleStripArray *>(sh->getGeometry()); 
    2231  
    2232                 // get indices of containted triangles (strips are converted before) 
    2233                 int *indices; 
    2234          
    2235                 int tCount = strips->getNumTriangles(); 
    2236                 int indexCount = tCount * 3; 
    2237                  
    2238                 // compute triangles from strips 
    2239                 Point3f *coordinates = (Point3f *)strips->getCoordRef3f(); 
    2240                 strips->getTriangleCoordinateIndices(0, &indices, indexCount); 
    2241  
    2242                 for (int i = 0; i < tCount; ++ i) 
    2243                 { 
    2244                         triangles[i + currentIdx].mVertices[0] = coordinates[indices[i * 3 + 0]];  
    2245                         triangles[i + currentIdx].mVertices[1] = coordinates[indices[i * 3 + 1]];  
    2246                         triangles[i + currentIdx].mVertices[2] = coordinates[indices[i * 3 + 2]];  
    2247  
    2248                         if (geom->mMatId != NV_RenderPredictorRenderAction::NO_MAT) 
    2249                         { 
    2250                                 const Matrix4f &m = mRenderer->app_mats[geom->mMatId]; 
    2251                                 Transform3D tf(m); 
    2252                                 tf.transform(triangles[i + currentIdx].mVertices[0]); 
    2253                                 tf.transform(triangles[i + currentIdx].mVertices[1]); 
    2254                                 tf.transform(triangles[i + currentIdx].mVertices[2]); 
    2255                         } 
    2256                 } 
    2257  
    2258                 currentIdx += tCount; 
    2259         } 
    2260  
    2261         return (Point3f *)triangles; 
    2262 } 
    2263  
    2264  
    2265752int Bvh::CountTriangles(BvhLeaf *leaf) const 
    2266753{ 
     
    2268755         
    2269756        for (int i = leaf->mFirst; i <= leaf->mLast; ++ i) 
    2270         { 
    2271                 triangleCount += mGeometry[i]->mNumTriangles; 
    2272         } 
    2273  
     757                triangleCount += mGeometry[i]->GetGeometry()->CountTriangles(); 
     758         
    2274759        return triangleCount; 
    2275760} 
     
    2290775                        BvhLeaf *leaf = static_cast<BvhLeaf *>(node); 
    2291776 
    2292                         mBvhStats.mLeafSA += leaf->mBox.getSurface(); 
    2293                         mBvhStats.mLeafVol += leaf->mBox.getVolume(); 
    2294  
    2295                         TriangleBvh::TriangleBvhStats tStats; 
    2296                         leaf->mTriangleBvh->GetBvhStats(tStats); 
    2297  
    2298                         mBvhStats.mBoundsLeafSA += tStats.mLeafSA; 
    2299                         mBvhStats.mBoundsInteriorSA += tStats.mInteriorSA; 
    2300  
    2301                         mBvhStats.mBoundsLeafVol += tStats.mLeafVol; 
    2302                         mBvhStats.mBoundsInteriorVol += tStats.mInteriorVol; 
    2303  
    2304                         mBvhStats.mBoundsLeavesCount += leaf->mTriangleBvh->GetNumLeaves(); 
     777                        mBvhStats.mLeafSA += leaf->mBox.SurfaceArea(); 
     778                        mBvhStats.mLeafVol += leaf->mBox.GetVolume(); 
    2305779                }  
    2306780                else  
    2307781                { 
    2308                         mBvhStats.mInteriorSA += node->mBox.getSurface(); 
    2309                         mBvhStats.mInteriorVol += node->mBox.getVolume(); 
     782                        mBvhStats.mInteriorSA += node->mBox.SurfaceArea(); 
     783                        mBvhStats.mInteriorVol += node->mBox.GetVolume(); 
    2310784 
    2311785                        BvhInterior *interior = static_cast<BvhInterior *>(node); 
     
    2323797void Bvh::PrintBvhStats() const 
    2324798{ 
    2325         //OUT1("triangle bvh surface " << mBvhStats.mBoundsLeafSA); 
    2326         //OUT1("triangle bvh volume " << mBvhStats.mBoundsLeafVol); 
    2327  
    2328         OUT1("bvh stats:"); 
    2329         OUT1("interiorNodesSA = " << mBvhStats.mInteriorSA / mRoot->mBox.getSurface()); 
    2330         OUT1("leafNodesSA = " << mBvhStats.mLeafSA / mRoot->mBox.getSurface()); 
    2331         OUT1("interiorNodesVolume = " << mBvhStats.mInteriorVol / mRoot->mBox.getVolume()); 
    2332         OUT1("leafNodesVolume = " << mBvhStats.mLeafVol / mRoot->mBox.getVolume() << "\n"); 
    2333  
    2334         OUT1("boundsInteriorNodesSA = " << mBvhStats.mBoundsInteriorSA / mBvhStats.mLeafSA); 
    2335         OUT1("boundsLeafNodesSA = " << mBvhStats.mBoundsLeafSA / mBvhStats.mLeafSA); 
    2336         OUT1("boundsInteriorNodesVolume = " << mBvhStats.mBoundsInteriorVol / mBvhStats.mLeafVol); 
    2337         OUT1("boundsLeafNodesVolume = " << mBvhStats.mBoundsLeafVol / mBvhStats.mLeafVol << "\n"); 
    2338  
    2339         OUT1("boundsLeaves: " <<  (float)mBvhStats.mBoundsLeavesCount / (float)GetNumLeaves() << "\n"); 
    2340         OUT1("geometry per leaf: " <<  mBvhStats.mGeometryRatio); 
    2341         OUT1("triangles per leaf: " <<  mBvhStats.mTriangleRatio); 
    2342         OUT1(""); 
    2343 } 
    2344  
    2345  
    2346 static void RenderBoxForViz(const BoundingBox &box) 
    2347 { 
    2348         glBegin(GL_LINE_LOOP); 
    2349         glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 
    2350         glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 
    2351         glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 
    2352         glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 
    2353         glEnd(); 
    2354  
    2355         glBegin(GL_LINE_LOOP); 
    2356         glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 
    2357         glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 
    2358         glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 
    2359         glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 
    2360         glEnd(); 
    2361  
    2362         glBegin(GL_LINE_LOOP); 
    2363         glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 
    2364         glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 
    2365         glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 
    2366         glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 
    2367         glEnd(); 
    2368  
    2369         glBegin(GL_LINE_LOOP); 
    2370         glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 
    2371         glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 
    2372         glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 
    2373         glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 
    2374         glEnd(); 
    2375  
    2376         glBegin(GL_LINE_LOOP); 
    2377         glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 
    2378         glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z); 
    2379         glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 
    2380         glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z); 
    2381         glEnd(); 
    2382  
    2383         glBegin(GL_LINE_LOOP); 
    2384         glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 
    2385         glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z); 
    2386         glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 
    2387         glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z); 
    2388  
    2389         glEnd(); 
    2390 } 
    2391  
    2392  
    2393 void Bvh::RenderBoundingBoxesForViz(const int mode) 
    2394 { 
    2395         BvhLeafContainer leaves; 
    2396         leaves.reserve(mRoot->GetNumLeaves()); 
    2397  
    2398         CollectLeaves(mRoot, leaves); 
    2399  
    2400         BvhLeafContainer::const_iterator it, it_end = leaves.end(); 
    2401  
    2402         for (it = leaves.begin(); it != it_end; ++ it) 
    2403         { 
    2404                 BvhLeaf *leaf = *it; 
    2405  
    2406                 if ((mode == 0) || (mode == 2)) 
    2407                 { 
    2408                         glColor3f(1.0f, 1.0f, 1.0f); 
    2409             RenderBoxForViz(leaf->GetBox()); 
    2410                 } 
    2411                  
    2412                 if ((mode == 1) || (mode == 2))  
    2413                 { 
    2414                         glColor3f(1.0f, 0, 0); 
    2415                         for (int i = 0; i < leaf->mNumTestNodes; ++ i) 
    2416                         { 
    2417                                 RenderBoxForViz(mTestNodes[leaf->mTestNodesIdx + i]->GetBox()); 
    2418                         } 
    2419                 } 
    2420         } 
     799        cout << "bvh stats:" << endl; 
     800        cout << "interiorNodesSA = " << mBvhStats.mInteriorSA / mRoot->mBox.SurfaceArea() << endl; 
     801        cout << "leafNodesSA = " << mBvhStats.mLeafSA / mRoot->mBox.SurfaceArea() << endl; 
     802        cout << "interiorNodesVolume = " << mBvhStats.mInteriorVol / mRoot->mBox.GetVolume() << endl; 
     803        cout << "leafNodesVolume = " << mBvhStats.mLeafVol / mRoot->mBox.GetVolume() << endl; 
     804 
     805        cout << "boundsInteriorNodesSA = " << mBvhStats.mBoundsInteriorSA / mBvhStats.mLeafSA << endl; 
     806        cout << "boundsLeafNodesSA = " << mBvhStats.mBoundsLeafSA / mBvhStats.mLeafSA << endl; 
     807        cout << "boundsInteriorNodesVolume = " << mBvhStats.mBoundsInteriorVol / mBvhStats.mLeafVol << endl; 
     808        cout << "boundsLeafNodesVolume = " << mBvhStats.mBoundsLeafVol / mBvhStats.mLeafVol << "\n" << endl; 
     809 
     810        cout << "boundsLeaves: " <<  (float)mBvhStats.mBoundsLeavesCount / (float)GetNumLeaves() << "\n" << endl; 
     811        cout << "geometry per leaf: " <<  mBvhStats.mGeometryRatio << endl; 
     812        cout << "triangles per leaf: " <<  mBvhStats.mTriangleRatio << endl; 
    2421813} 
    2422814 
     
    2428820        for (int i = node->mFirst; i <= node->mLast; ++ i) 
    2429821        { 
    2430                 numTriangles += mGeometry[i]->mNumTriangles; 
     822                numTriangles += mGeometry[i]->GetGeometry()->CountTriangles(); 
    2431823        } 
    2432824 
     
    2440832} 
    2441833 
    2442  
    2443 float Bvh::GetAvgDepth() const 
    2444 { 
    2445         return mAvgDepth; 
    2446 } 
    2447  
    2448  
    2449 static float GetNodePriority(RenderableHierarchyNode *node) 
    2450 { 
    2451         if (node->IsLeaf()) 
    2452                 return 0.0f; 
    2453  
    2454         float result; 
    2455  
    2456         if (node->GetType() == BVH_NODE) 
    2457         { 
    2458                 BvhInterior *interior = static_cast<BvhInterior *>(node); 
    2459                  
    2460                 // evaluate the priority of this node 
    2461                 const float correctionFactor = 0.0f; 
    2462                 //  1.0f*interior->box.FaceArea(node->axis); 
    2463  
    2464                 result =  
    2465                         interior->GetBox().getSurface() -  
    2466                         (interior->GetBack()->GetBox().getSurface() + interior->GetFront()->GetBox().getSurface()) +  
    2467                         correctionFactor; 
    2468         } 
    2469         else 
    2470         { 
    2471                 TriangleBvhInterior *interior = static_cast<TriangleBvhInterior *>(node); 
    2472                  
    2473                 // evaluate the priority of this node 
    2474                 const float correctionFactor = 0.0f; 
    2475                 //  1.0f*interior->box.FaceArea(node->axis); 
    2476  
    2477                 result =  
    2478                         interior->GetBox().getSurface() -  
    2479                         (interior->GetBack()->GetBox().getSurface() + interior->GetFront()->GetBox().getSurface()) +  
    2480                         correctionFactor; 
    2481         } 
    2482  
    2483         return result; 
    2484 } 
    2485  
    2486  
    2487 struct NodeEntry 
    2488 { 
    2489         NodeEntry(RenderableHierarchyNode *node, float p): mNode(node), mPriority(p) 
    2490         {} 
    2491  
    2492         RenderableHierarchyNode *mNode; 
    2493         float mPriority; 
    2494 }; 
    2495  
    2496  
    2497 bool operator<(const NodeEntry &a, const NodeEntry &b) 
    2498 { 
    2499         return a.mPriority < b.mPriority; 
    2500 } 
    2501  
    2502  
    2503 void Bvh::CollectBestNodes(RenderableHierarchyNode *node, HierarchyNodeContainer &nodes) 
    2504 { 
    2505         int maxNodes = 32; 
    2506         priority_queue<NodeEntry> nodeStack; 
    2507  
    2508         nodeStack.push(NodeEntry(node, GetNodePriority(node))); 
    2509         nodes.clear(); 
    2510  
    2511         float SA = node->GetBox().getSurface(); 
    2512         float saThreshold = 1.1f * SA; 
    2513         int numNodes = 1; 
    2514         OUT1(numNodes << " " << SA); 
    2515  
    2516         while (!nodeStack.empty() && 
    2517                 int(nodes.size() + nodeStack.size()) < maxNodes) 
    2518         { 
    2519                 NodeEntry entry = nodeStack.top(); 
    2520                 nodeStack.pop(); 
    2521  
    2522                 RenderableHierarchyNode *current = entry.mNode; 
    2523  
    2524                 if (current->IsLeaf()) 
    2525                 { 
    2526                         // check if there further subdivision on triangle level 
    2527                         if ((current->GetType() == BVH_NODE) && (((BvhLeaf *)current)->mTriangleBvh->GetNumNodes() > 1)) 
    2528                         { 
    2529                                 // push back the root of the local bvh 
    2530                                 nodeStack.push(NodeEntry(((BvhLeaf *)current)->mTriangleBvh->GetRoot(), entry.mPriority)); 
    2531                         } 
    2532                         else // terminate traversal 
    2533                         { 
    2534                                 nodes.push_back(current); 
    2535                         } 
    2536                 } 
    2537                 else // interior node 
    2538                 { 
    2539                         // surface area of child nodes 
    2540                         SA -= entry.mPriority; 
    2541                  
    2542                         // finish the search if we have too much fillrate increase 
    2543                         if (SA > saThreshold) 
    2544                         { 
    2545                                 OUT1("break at " << SA << " > " << saThreshold); 
    2546                                 nodes.push_back(current); 
    2547                         } 
    2548                         else 
    2549                         { 
    2550                                 ++ numNodes; 
    2551  
    2552                                 OUT1(numNodes << " " << SA << " " << entry.mPriority); 
    2553  
    2554                                 if (current->GetType() == BVH_NODE) 
    2555                                 { 
    2556                                         BvhInterior *interior = static_cast<BvhInterior *>(current); 
    2557  
    2558                                         nodeStack.push(NodeEntry(interior->GetBack(),  
    2559                                                 GetNodePriority(interior->GetBack()))); 
    2560                                         nodeStack.push(NodeEntry(interior->GetFront(), 
    2561                                                 GetNodePriority(interior->GetFront()))); 
    2562                                 } 
    2563                                 else 
    2564                                 { 
    2565                                         TriangleBvhInterior *interior = static_cast<TriangleBvhInterior *>(current); 
    2566  
    2567                                         nodeStack.push(NodeEntry(interior->GetBack(),  
    2568                                                 GetNodePriority(interior->GetBack()))); 
    2569                                         nodeStack.push(NodeEntry(interior->GetFront(), 
    2570                                                 GetNodePriority(interior->GetFront()))); 
    2571                                 } 
    2572                         } 
    2573                 } 
    2574         } 
    2575  
    2576         while (!nodeStack.empty())  
    2577         { 
    2578                 NodeEntry entry = nodeStack.top(); 
    2579          
    2580                 nodeStack.pop(); 
    2581                 RenderableHierarchyNode *current = entry.mNode; 
    2582                 nodes.push_back(current); 
    2583         } 
    2584 }  
    2585  
    2586 #endif 
    2587  
    2588 } 
     834} 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h

    r2753 r2755  
    55 
    66#include "Geometry.h" 
    7 //#include "FlexibleHeap.h" 
    87 
    98 
     
    1413// Forward declarations 
    1514 
    16 class SceneGeometry; 
     15class SceneEntity; 
    1716class Camera; 
    1817 
     
    2322{ 
    2423        friend class Bvh; 
     24        friend class BvhLoader; 
     25        friend class myless; 
    2526 
    2627public: 
     
    5253        */ 
    5354        BvhNode(BvhNode *parent); 
    54          
    5555        /** Returns true if this node is a leaf. 
    5656        */ 
     
    7575        virtual void ResetVisibility(); 
    7676 
    77         virtual int GetType() = 0; //{ return BVH_NODE; } 
    78  
    79  
    80         ///////////////////// 
     77        virtual bool IsLeaf() = 0; //{ return BVH_NODE; } 
     78 
     79 
     80        //////////////// 
    8181        //-- visibility culling related functions 
    8282 
    8383        inline int GetLastVisitedFrame() const; 
    8484 
    85         inline void SetLastVisitedFrame(const int lastVisited); 
     85        inline void SetLastVisitedFrame(int lastVisited); 
    8686        /** If this node is considered visible. 
    8787        */ 
     
    8989        /** Set visibility flag of the node. 
    9090        */ 
    91         inline void SetVisible(const bool visible); 
     91        inline void SetVisible(bool visible); 
    9292        /** The assumed visible time span of this node. 
    9393        */ 
    94         inline void SetAssumedVisibleFrames(const int t); 
     94        inline void SetAssumedVisibleFrames(int t); 
    9595        /** See set. 
    9696        */ 
     
    108108         
    109109        inline int GetTimesInvisible() const; 
    110         inline void SetTimesInvisible(const int t); 
     110        inline void SetTimesInvisible(int t); 
    111111         
    112112        inline int GetTurnedVisibleFrame() const; 
    113         inline void SetTurnedVisibleFrame(const int turnedVisibleFrame); 
     113        inline void SetTurnedVisibleFrame(int turnedVisibleFrame); 
    114114 
    115115        inline int GetLastTestedFrame(); 
    116         inline void SetLastTestedFrame(const int lastTested); 
     116        inline void SetLastTestedFrame(int lastTested); 
    117117         
    118118        inline bool IsViewFrustumCulled() const; 
    119         inline void SetViewFrustumCulled(const bool frustumCulled); 
     119        inline void SetViewFrustumCulled(bool frustumCulled); 
    120120 
    121121        inline bool IsNew() const; 
    122         inline void SetIsNew(const bool isNew); 
     122        inline void SetIsNew(bool isNew); 
     123 
     124 
     125        /** Returns the bounding box of this node. 
     126        */ 
     127        inline const AxisAlignedBox3 &GetBox() { return mBox; } 
     128        /** Return index of this node. 
     129        */ 
     130        inline int GetId() const { return mId; } 
     131        /** See get 
     132        */ 
     133        inline void SetId(int id) { mId = id; } 
    123134 
    124135 
     
    152163        /// the parent node 
    153164        BvhNode *mParent; 
    154         /// stores the visibility related parameters 
     165        /// stores the visibility related info 
    155166        VisibilityInfo mVisibility; 
    156167 
     
    181192        /// these nodes can be tested instead of the current node 
    182193        int mTestNodesIdx; 
     194         
    183195        int mNumTestNodes; 
     196 
    184197        int mIndicesPtr; 
     198 
    185199        /// Area of this node 
    186200        float mArea; 
     201        /// distance to the camera 
     202        float mDistance; 
     203        /// the index of this node 
     204        unsigned int mId; 
     205        /// indices used for draw array rendering 
     206        unsigned int *mIndices; 
     207        /// the bounding box 
     208        AxisAlignedBox3 mBox; 
     209 
    187210}; 
    188211 
     
    302325class BvhInterior: public BvhNode 
    303326{ 
    304 friend class Bvh; 
     327        friend class Bvh; 
     328        friend class BvhLoader; 
    305329 
    306330public: 
     331 
    307332        BvhInterior(BvhNode *parent): mBack(NULL), mFront(NULL), BvhNode(parent) 
    308333        {} 
     
    319344        /** Returns split axis of this interior node. 
    320345        */ 
    321         inline int GetAxis() {return (int)mAxis;} 
     346        inline int GetAxis() { return (int)mAxis; } 
    322347        /** Returns position of the split axis. 
    323348        */ 
     
    337362class BvhLeaf: public BvhNode 
    338363{ 
    339 friend class Bvh; 
     364        friend class Bvh; 
     365        friend class BvhLoader; 
    340366 
    341367public: 
     
    347373 
    348374        virtual bool IsLeaf() { return true; } 
     375}; 
     376 
     377 
     378/**     This class implements the compare operator for the priority queue. 
     379        a lower distance has a higher value in the queue 
     380*/ 
     381class myless 
     382{ 
     383public: 
     384        bool operator() (BvhNode *v1, BvhNode *v2) const 
     385    { 
     386                return (v1->mDistance > v2->mDistance); 
     387    } 
    349388}; 
    350389 
     
    354393class Bvh 
    355394{ 
     395        friend class BvhLoader; 
     396 
    356397        /** Bvh properties 
    357398        */ 
     
    401442        */ 
    402443        inline int GetNumLeaves() const {return mNumNodes / 2 + 1;} 
    403         /** Constructs the bounding volume hierarchy. 
    404         */ 
    405         void Construct(); 
    406444        /** Returns root node of the bvh. 
    407445        */ 
    408         BvhNode *GetRoot() {return mRoot;} 
     446        BvhNode *GetRoot() { return mRoot; } 
    409447        /** Counts the triangle in this leaf. 
    410448        */ 
     
    412450 
    413451 
     452        void CollectNodes(BvhNode *node, BvhNodeContainer &nodes, int depth); 
     453        void CollectNodes(BvhNode *node, BvhNodeContainer &nodes); 
     454        void CollectLeaves(BvhNode *node, BvhLeafContainer &leaves); 
     455 
     456 
    414457        ////////////////////// 
    415458 
    416459        /** Returns geometry by reference (faster). 
    417460        */ 
    418         SceneGeometry **GetGeometry(BvhNode *node, int &size); 
     461        SceneEntity **GetGeometry(BvhNode *node, int &size); 
    419462 
    420463 
     
    442485        */ 
    443486        int     IsWithinViewFrustum(BvhNode *node); 
    444         /** sets frame dependent values. 
    445         */ 
    446         void InitFrame(Camera *camera, const int currentFrameId); 
    447         /** this gives the orthogonal distance from the viewpoint to the nearest bounding box vertex 
     487        /** Sets frame dependent values. 
     488        */ 
     489        void InitFrame(Camera *camera, int currentFrameId); 
     490        /** This gives the orthogonal distance from the viewpoint to the nearest bounding box vertex 
    448491                note that negative values can appear because culling is done only afterwards 
    449492        */ 
    450493        float CalcDistance(BvhNode *node) const; 
    451         /** Sets maximal depth for taking the bounding boxes to test the 
    452                 visibility of a node. The deeper the more the box fits to the geometry. 
    453         */ 
    454         void SetMaxDepthForTestingChildren(const int maxDepth); 
    455         /** Pulls up the fully visible classification in the bvh. 
    456         */ 
    457         void UpdateFullVisibility(BvhNode *node) const; 
    458494        /** Pulls up the last visited classification in the bvh. 
    459495        */ 
    460         void PullUpLastVisited(BvhNode *node, const int frameId) const; 
     496        void PullUpLastVisited(BvhNode *node, int frameId) const; 
    461497        /** Resets the node classifications in the tree. 
    462498        */ 
     
    465501                wireframes for visualization purpose. 
    466502        */ 
    467         void RenderBoundingBoxesForViz(const int mode); 
    468         /** Returns squared min distance to the view point. 
    469         */ 
    470         float GetSquareDistance(BvhNode *node) const; 
     503        //void RenderBoundingBoxesForViz(int mode); 
    471504        /** Count triangles the node contains. 
    472505        */ 
     
    477510 
    478511 
    479         //////////// 
    480         //-- functions that change the boundaries of the nodes 
    481  
    482         void SetUseTighterBoundsForTests(bool tighterBoundsForTests); 
    483  
    484         void SetAreaRatioThresholdForTestingChildren(const float ratio); 
    485  
    486  
     512        //////// 
     513        //-- functions influencing tighter bounds 
     514 
     515 
     516        /** Sets maximal depth for taking the bounding boxes to test the 
     517                visibility of a node.  
     518                Deeper => the bounds adapt more to the geometry. 
     519        */ 
     520        void SetMaxDepthForTestingChildren(int maxDepth); 
     521 
     522        void SetAreaRatioThresholdForTestingChildren(float ratio); 
     523 
     524        /** Returns stats. 
     525        */ 
    487526        const BvhStats &GetBvhStats() const {return mBvhStats;} 
    488  
    489         void SetCollectTighterBoundsWithMaxLevel(bool t); 
    490  
    491  
    492         ////////////// 
    493  
    494         static unsigned int sCurrentVboId; 
    495527         
    496528 
    497529protected: 
    498530 
    499         /** Small struct representing a frustum. 
    500         */ 
    501         struct Frustum 
    502         { 
    503                 /// the 6 clip planes 
    504                 float mClipPlane[6][4]; 
    505         }; 
    506          
    507  
    508  
    509531        //////////////////// 
    510532 
    511         /** Constructor loading the bvh from disc 
    512         */ 
    513         Bvh(const std::string &filename); 
    514533        /** protected constructor: do nothing. 
    515534        */ 
    516         //Bvh(): mCamera(NULL), mFrameId(-1), mVertices(NULL), mRenderer(NULL) {} 
     535        Bvh(); 
    517536        /** Destructor. 
    518537        */ 
     
    534553        void RenderBoundingBoxesWithDrawArrays(int numNodes); 
    535554 
    536         int RenderBoundingBoxesImmediate(const BvhNodeContainer &nodes); 
    537         /** Renders a bounding box in immediate mode using index restart 
    538                 and restarts the strip only if wished. 
    539         */ 
    540         void RenderBoundingBoxImmediate(const AxisAlignedBox3 &box, bool restartStrip); 
    541555        /** Create the indices that each node needs to use vbo rendering. 
    542556        */ 
     
    550564        */ 
    551565        void UpdateInteriors(BvhNode *node); 
    552         /** Recomputes the boundaries of the nodes. This function is always called if 
    553                 some boundary options are changed. 
     566        /** Recomputes the boundaries of the nodes.  
     567            This function is always called if some boundary options are changed. 
    554568        */ 
    555569        void RecomputeBounds(); 
     
    558572        */ 
    559573        int PostProcessLeaves(BvhLeafContainer &leaves); 
    560  
    561  
    562         int     IsWithinViewFrustumLocal(BvhNode *node); 
    563  
    564         int     IsWithinViewFrustum(const AxisAlignedBox3 &box, int planeMask, int preferredPlane); 
    565          
    566         float GetMinSquareDistance(const AxisAlignedBox3 &box) const; 
    567          
     574                 
    568575         
    569576        //////////////////////// 
     
    572579        BvhNode *mRoot; 
    573580        /// pointers to the geometry associated with this node 
    574         SceneGeometry **mGeometry; 
     581        SceneEntity **mGeometry; 
    575582        /// #of entities 
    576583        size_t mGeometrySize; 
     
    579586        //////////////// 
    580587 
    581  
    582         /// these values are valid for all nodes 
    583         char mClipPlaneAABBVertexIndices[6][2]; 
    584         /// the current view frustum 
    585         Frustum mFrustum; 
    586588        /// the current camera 
    587589        Camera *mCamera; 
     
    589591        int mFrameId; 
    590592        /// a vertex array used if working with indexed arrays (without vbo) 
    591         //Point3f *mVertices; 
     593        Vector3 *mVertices; 
    592594        /// indices used for draw array rendering 
    593595        unsigned int *mIndices; 
     
    599601 
    600602        float mAreaRatioThreshold; 
    601         float mVolRatioThreshold; 
     603 
    602604 
    603605        BvhStats mBvhStats; 
    604606 
    605         //HierarchyNodeContainer mTestNodes; 
     607        BvhNodeContainer mTestNodes; 
    606608         
    607609        unsigned int *mTestIndices; 
     
    609611        int mCurrentIndicesPtr; 
    610612 
    611         float mScale; 
    612  
    613         Vector3 mNearPlane; 
    614         float mNearPlaneD; 
    615613        int mNumNodes; 
     614 
     615 
     616        ////////////// 
     617 
     618        static unsigned int sCurrentVboId; 
    616619}; 
    617620 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.cpp

    r2753 r2755  
    11#include "common.h" 
    22#include "Camera.h" 
    3  
     3#include "glInterface.h" 
    44 
    55 
     
    7070} 
    7171 
     72 
     73void Camera::GetProjectionMatrix(Matrix4x4 &mat) 
     74{ 
     75        //float m[16]; 
     76         
     77        glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat.x); 
     78        //mat = Matrix4x4((const float *)m); 
    7279} 
    7380 
     81 
     82void Camera::GetModelViewMatrix(Matrix4x4 &mat) 
     83{ 
     84        //float m[16]; 
     85 
     86        glGetFloatv(GL_MODELVIEW_MATRIX, (float *)mat.x); 
     87        //mat = Matrix4f((const float *)m); 
     88} 
     89 
     90 
     91void Camera::CalcFrustum(Frustum &frustum) 
     92{ 
     93        // we grab the plane equations of the six clipplanes of the viewfrustum 
     94        Matrix4x4 matViewing, matProjectionView; 
     95 
     96        GetModelViewMatrix(matViewing); 
     97        GetProjectionMatrix(matProjectionView); 
     98 
     99        matProjectionView *= matViewing; 
     100 
     101         
     102        float fInvLength; 
     103 
     104        float planes[6][4]; 
     105 
     106        ////////// 
     107        //-- extract the plane equations 
     108 
     109        for (int i = 0; i < 4; ++ i) 
     110        { 
     111                planes[0][i] = matProjectionView.x[i][3] - matProjectionView.x[i][0]; // right plane 
     112                planes[1][i] = matProjectionView.x[i][3] + matProjectionView.x[i][0]; // left plane 
     113                planes[2][i] = matProjectionView.x[i][3] + matProjectionView.x[i][1]; // bottom plane 
     114                planes[3][i] = matProjectionView.x[i][3] - matProjectionView.x[i][1]; // top plane 
     115                planes[4][i] = matProjectionView.x[i][3] - matProjectionView.x[i][2]; // far plane 
     116                planes[5][i] = matProjectionView.x[i][3] + matProjectionView.x[i][2]; // near plane 
     117        } 
     118 
     119 
     120        //////////// 
     121        //-- normalize the coefficients 
     122 
     123        for (int i = 0; i < 6; ++ i) 
     124        { 
     125                // the clipping planes look outward the frustum, 
     126                // so distances > 0 mean that a point is outside 
     127                fInvLength      = -1.0f / sqrt(planes[i][0] * planes[i][0] +     
     128                                                                   planes[i][1] * planes[i][1] +         
     129                                                                   planes[i][2] * planes[i][2]); 
     130 
     131                planes[i][0] *= fInvLength; 
     132                planes[i][1] *= fInvLength; 
     133                planes[i][2] *= fInvLength; 
     134                planes[i][3] *= fInvLength; 
     135 
     136                Vector3 normal(planes[i][0], planes[i][1], planes[i][2]); 
     137                frustum.mClipPlanes[i] = Plane3(normal, planes[i][3]); 
     138        } 
     139} 
     140 
     141 
     142void Camera::Frustum::CalcNPVertexIndices(int *indices) 
     143{ 
     144        for (int i = 0; i < 6; ++ i) 
     145        { 
     146                // n-vertex 
     147                indices[i * 2 + 0] = AxisAlignedBox3::GetIndexNearestVertex(mClipPlanes[i].mNormal); 
     148                // p-vertex 
     149                indices[i * 2 + 1] = AxisAlignedBox3::GetIndexFarthestVertex(mClipPlanes[i].mNormal);    
     150        } 
     151} 
     152 
     153 
     154} 
     155 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.h

    r2753 r2755  
    44#include "Vector3.h" 
    55#include "AxisAlignedBox3.h" 
     6#include "Plane3.h" 
    67 
    78 
    8 namespace CHCDemo { 
     9namespace CHCDemo  
     10{ 
    911 
    1012 
     
    1214{ 
    1315public: 
     16         
     17        /** Small struct representing a frustum. 
     18        */ 
     19        struct Frustum 
     20        { 
     21                /// the 6 clip planes 
     22                //float mClipPlane[6][4]; 
     23                Plane3 mClipPlanes[6]; 
    1424 
     25                void CalcNPVertexIndices(int *indices); 
     26        }; 
     27         
    1528        Camera(); 
    1629 
     
    3447        inline float GetFov() const { return mFovy; } 
    3548        inline void GetSize(int &width, int &height) const { width = mWidth; height = mHeight; } 
     49        inline float GetAspect() const { return (float) mWidth / mHeight; } 
     50 
     51        void GetProjectionMatrix(Matrix4x4 &mat); 
     52        void GetModelViewMatrix(Matrix4x4 &mat); 
     53 
     54        void CalcFrustum(Frustum &frustum); 
     55 
    3656 
    3757protected: 
     
    5070        int mWidth; 
    5171        int mHeight; 
    52  
    5372}; 
    5473 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.cpp

    r2751 r2755  
    1 #if 0 
    2  
    3  
    41#include "Geometry.h" 
    5 #include "glInterface.h" 
    6 #include "stdio.h" 
    7 #include "teapot.h" 
    8  
    9 #include <math.h> 
     2#include "Triangle3.h" 
    103 
    114 
     
    136{ 
    147 
    15 #define NO_LIST    -1 
    16 #define STRIP_END  -1 
     8Geometry::Geometry(const TriangleContainer &triangles) 
     9{} 
    1710 
    18 int Geometry::num_torus_indices; 
    19 int Geometry::num_torus_vertices; 
    20 int Geometry::num_torus_normals; 
    2111 
    22 const int Geometry::torus_precision = 24; 
    23 const int Geometry::sphere_precision = 24; 
    24  
    25 float *Geometry::torus_vertices; 
    26 float *Geometry::torus_normals; 
    27 int *Geometry::torus_indices; 
    28  
    29 // choose size so the glut-rendered sphere is approximately 
    30 // as big as the other objects 
    31 const float Geometry::sphere_radius = 1.0 / 9.0f; 
    32 const float Geometry::torus_inner_radius = 0.05; 
    33 const float Geometry::torus_outer_radius = 0.07; 
    34  
    35 int Geometry::sDisplayList[NUM_OBJECTS]; 
    36  
    37 bool Geometry::sIsInitialised = Init(); 
    38  
    39 Geometry::Geometry():  
    40 mXRotation(0), mYRotation(0), mZRotation(0), mScale(1.0), mObjectType(TEAPOT) 
     12SceneEntity::SceneEntity(Geometry *geometry,  
     13                                                 Matrix4x4 *trafo,  
     14                                                 Material *mat): 
     15mGeometry(geometry), mTransform(trafo), mMaterial(mat) 
    4116{ 
    42         copyVector3Values(mTranslation, 0, 0, 0); 
    43          
    44         SetAmbientColor(0.1745, 0.01175, 0.01175); 
    45         SetDiffuseColor(0.61424, 0.04136, 0.04136); 
    46         SetSpecularColor(0.727811, 0.626959, 0.626959); 
    47          
    48         CalcBoundingVolume(); 
    49         CalcTransform(); 
    50         GenerateList(); 
    51 } 
    52  
    53 Geometry::Geometry(Vector3 translation, float xRot, float yRot, float zRot, float scale, int objectType): 
    54 mXRotation(xRot), mYRotation(yRot), mZRotation(zRot), mScale(scale), mObjectType(objectType) 
    55 { 
    56         copyVector3(mTranslation, translation); 
    57  
    58         SetAmbientColor(0.1745, 0.01175, 0.01175); 
    59         SetDiffuseColor(0.61424, 0.04136, 0.04136); 
    60         SetSpecularColor(0.727811, 0.626959, 0.626959); 
    61          
    62         CalcBoundingVolume(); 
    63         CalcTransform(); 
    64         GenerateList(); 
    65 } 
    66  
    67 void Geometry::ResetLists() 
    68 { 
    69         for(int i = 0; i < NUM_OBJECTS; i++) 
    70         { 
    71         if(sDisplayList[i] == NO_LIST) 
    72                         glDeleteLists(sDisplayList[i], 1); 
    73  
    74                 sDisplayList[i] = NO_LIST; 
    75         } 
    76 } 
    77  
    78 void Geometry::CleanUp() 
    79 { 
    80         ResetLists(); 
    81  
    82         delete [] torus_vertices; 
    83         delete [] torus_normals; 
    84         delete [] torus_indices; 
    8517} 
    8618 
    8719 
    88 bool Geometry::Init() 
     20void SceneEntity::Render() 
    8921{ 
    90         for(int i=0; i < NUM_OBJECTS; i++) 
    91                 sDisplayList[i] = NO_LIST; 
    92  
    93         // parameters chosen so torus is approximately as big as teapot 
    94         CreateTorus(torus_inner_radius, torus_outer_radius, torus_precision); 
    95  
    96         return true; 
    9722} 
    9823 
    9924 
    100 void Geometry::GenerateList() 
     25void SceneEntity::SetGeometry(Geometry *geom) 
    10126{ 
    102         if(sDisplayList[mObjectType] == NO_LIST) 
    103         { 
    104                 sDisplayList[mObjectType] = glGenLists(1); 
    105                 glNewList(sDisplayList[mObjectType], GL_COMPILE); 
    106  
    107                 switch(mObjectType) 
    108                 { 
    109                         case TEAPOT: 
    110                                 RenderTeapot(); 
    111                                 break; 
    112                         case TORUS: 
    113                                 RenderTorus(); 
    114                                 break; 
    115                         case SPHERE:     
    116                                 RenderSphere(); 
    117                                 break; 
    118                          
    119                         default: 
    120                                 break; 
    121                 } 
    122  
    123                 glEndList(); 
    124         } 
     27        mGeometry = geom; 
    12528} 
    12629 
    12730 
    128 void Geometry::Render() 
     31void SceneEntity::SetTransformation(Matrix4x4 *trafo) 
    12932{ 
    130         glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbientColor); 
    131         glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuseColor); 
    132         glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecularColor); 
    133          
    134         glPushMatrix(); 
    135          
    136         Transform(); 
    137          
    138         glCallList(sDisplayList[mObjectType]); 
    139  
    140         glPopMatrix(); 
     33        mTransform = trafo; 
    14134} 
    14235 
    14336 
    144 //! sets rotations around the three axis: executed in the order specified here 
    145 void Geometry::SetRotations(float xRot, float yRot, float zRot) 
     37void SceneEntity::SetMaterial(Material *mat) 
    14638{ 
    147         mXRotation = xRot; 
    148         mYRotation = yRot; 
    149         mZRotation = zRot; 
    150  
    151         CalcBoundingVolume(); 
    152         CalcTransform(); 
     39        mMaterial = mat; 
    15340} 
    15441 
    15542 
    156 void Geometry::SetTranslation(Vector3 translation) 
    157 { 
    158         copyVector3(mTranslation, translation); 
    159  
    160         CalcBoundingVolume(); 
    161         CalcTransform(); 
    162 } 
    163  
    164  
    165 void Geometry::SetScale(float scale) 
    166 { 
    167         mScale = scale; 
    168         CalcTransform(); 
    169  
    170         CalcBoundingVolume(); 
    171 } 
    172  
    173  
    174 void Geometry::SetAmbientColor(float ambientR, float ambientG, float ambientB) 
    175 { 
    176         mAmbientColor[0] = ambientR; 
    177         mAmbientColor[1] = ambientG; 
    178         mAmbientColor[2] = ambientB; 
    179 } 
    180  
    181  
    182 void Geometry::SetDiffuseColor(float diffuseR, float diffuseG, float diffuseB) 
    183 { 
    184         mDiffuseColor[0] = diffuseR; 
    185         mDiffuseColor[1] = diffuseG; 
    186         mDiffuseColor[2] = diffuseB; 
    187 } 
    188  
    189  
    190 void Geometry::SetSpecularColor(float specularR, float specularG, float specularB) 
    191 { 
    192         mSpecularColor[0] = specularR; 
    193         mSpecularColor[1] = specularG; 
    194         mSpecularColor[2] = specularB; 
    195 } 
    196  
    197  
    198 float Geometry::GetScale() 
    199 { 
    200         return mScale; 
    201 } 
    202  
    203  
    204 void Geometry::GetTranslation(Vector3 translation) 
    205 { 
    206         copyVector3(translation, mTranslation); 
    207 } 
    208  
    209  
    210 void Geometry::GetRotations(float &xRot, float &yRot, float &zRot) 
    211 { 
    212         xRot = mXRotation; 
    213         yRot = mYRotation; 
    214         zRot = mZRotation; 
    215 } 
    216  
    217          
    218 const AABox &Geometry::GetBoundingVolume() 
     43const AxisAlignedBox3& SceneEntity::GetBoundingVolume() 
    21944{ 
    22045        return mBoundingBox; 
     
    22247 
    22348 
    224 void Geometry::SetLastVisited(int lastVisited) 
     49void SceneEntity::SetLastVisited(int lastVisited) 
    22550{ 
    22651        mLastVisited = lastVisited; 
     
    22853 
    22954 
    230 int Geometry::GetLastVisited() 
     55int SceneEntity::GetLastVisited() const 
    23156{ 
    23257        return mLastVisited; 
     
    23459 
    23560 
    236 void Geometry::SetObjectType(int type) 
    237 { 
    238         mObjectType = type; 
    239         GenerateList(); 
    24061} 
    241  
    242  
    243 void Geometry::RenderTeapot() 
    244 { 
    245         int i = 0; 
    246  
    247         while(i < num_teapot_indices) 
    248         { 
    249                 glBegin(GL_TRIANGLE_STRIP); 
    250                  
    251                 while (teapot_indices[i] != STRIP_END) 
    252                 {        
    253                         int index = teapot_indices[i] * 3; 
    254  
    255                         glNormal3fv(teapot_normals + index); 
    256                         glVertex3fv(teapot_vertices + index); 
    257                          
    258                         ++ i;            
    259                 } 
    260  
    261                 glEnd(); 
    262  
    263                 ++ i; // skip strip end flag 
    264         } 
    265 } 
    266  
    267  
    268 void Geometry::CalcBoundingVolume() 
    269 { 
    270     switch(mObjectType) 
    271         { 
    272                 case TORUS: 
    273                         CalcBoundingVolume(torus_vertices, num_torus_vertices); 
    274                         break; 
    275                 case SPHERE: 
    276                         CalcSphereBoundingVolume(); 
    277                         break; 
    278                 case TEAPOT: 
    279                         CalcBoundingVolume(teapot_vertices, num_teapot_vertices); 
    280                         break; 
    281                 default: 
    282                         break; 
    283         } 
    284 } 
    285  
    286  
    287 void Geometry::CalcBoundingVolume(float *vertices, const int num_vertices) 
    288 { 
    289         Vector3 *rotatedPoints = new Vector3[num_vertices]; 
    290          
    291         for (int i = 0; i < num_vertices; ++ i) 
    292         { 
    293                 copyVector3Values(rotatedPoints[i], vertices[i * 3], 
    294                                                   vertices[i * 3 + 1], vertices[i * 3 + 2]); 
    295          
    296                 rotateVectorZ(rotatedPoints[i], mZRotation * PI_180); 
    297                 rotateVectorY(rotatedPoints[i], mYRotation * PI_180); 
    298                 rotateVectorX(rotatedPoints[i], mXRotation * PI_180); 
    299         } 
    300  
    301         calcCubicHull(mBoundingBox.min, mBoundingBox.max, rotatedPoints, num_vertices); 
    302  
    303         for (int i = 0; i < 3; ++ i) 
    304         { 
    305                 mBoundingBox.min[i] *= mScale; 
    306                 mBoundingBox.max[i] *= mScale; 
    307         } 
    308  
    309         addVector3(mBoundingBox.min, mTranslation, mBoundingBox.min); 
    310     addVector3(mBoundingBox.max, mTranslation, mBoundingBox.max); 
    311  
    312         delete [] rotatedPoints; 
    313 } 
    314  
    315  
    316 void Geometry::CalcSphereBoundingVolume() 
    317 { 
    318         float len = mScale * sphere_radius; 
    319         Vector3 size = {len, len, len}; 
    320                                          
    321         diffVector3(mBoundingBox.min, mTranslation, size); 
    322         addVector3(mBoundingBox.max, mTranslation, size); 
    323 } 
    324  
    325  
    326 void Geometry::RenderTorus() 
    327 { 
    328         glVertexPointer(3, GL_FLOAT, sizeof(float), torus_vertices); 
    329         glEnableClientState(GL_VERTEX_ARRAY); 
    330  
    331         glNormalPointer(GL_FLOAT, sizeof(float), torus_normals); 
    332         glEnableClientState(GL_NORMAL_ARRAY); 
    333  
    334     glDrawElements(GL_TRIANGLES, num_torus_indices, GL_UNSIGNED_INT, torus_indices); 
    335  
    336         glDisableClientState(GL_VERTEX_ARRAY); 
    337         glDisableClientState(GL_NORMAL_ARRAY); 
    338 } 
    339  
    340 /*      Creates a torus with specified radii, with number of rings and ring 
    341         subdivision = precision. 
    342 */ 
    343 void Geometry::CreateTorus(float innerRadius, float outerRadius, int precision) 
    344 { 
    345         num_torus_vertices = num_torus_normals = (precision + 1) * (precision + 1); 
    346         num_torus_indices = 2 * precision * precision * 3; 
    347  
    348         torus_vertices = new float[num_torus_vertices * 3]; 
    349         torus_normals = new float[num_torus_normals * 3]; 
    350         torus_indices = new int[num_torus_indices]; 
    351  
    352         for (int i = 0; i < precision + 1; ++ i) 
    353         { 
    354                 int index = i * 3; 
    355  
    356                 Vector3 currentVertex = {innerRadius, 0.0f, 0.0f}; 
    357                 rotateVectorZ(currentVertex, ((float)i * 2.0 * PI) / (float)precision); 
    358  
    359                 currentVertex[0] += outerRadius; 
    360                  
    361                 Vector3 sTangent = {0.0f, 0.0f, -1.0f}; 
    362                 Vector3 tTangent = {0, -1, 0}; 
    363                 rotateVectorZ(tTangent, ((float)i * 2.0 * PI) / (float)precision); 
    364  
    365         Vector3 currentNormal; 
    366  
    367                 cross(currentNormal, tTangent, sTangent); 
    368  
    369                 torus_normals[index + 0] = currentNormal[0]; 
    370                 torus_normals[index + 1] = currentNormal[1]; 
    371                 torus_normals[index + 2] = currentNormal[2]; 
    372                  
    373                 torus_vertices[index + 0] = currentVertex[0]; 
    374                 torus_vertices[index + 1] = currentVertex[1]; 
    375                 torus_vertices[index + 2] = currentVertex[2]; 
    376         } 
    377  
    378         for (int i_rng = 1; i_rng < precision + 1; ++ i_rng) 
    379         { 
    380                 for(int i = 0; i<precision + 1; ++ i) 
    381                 { 
    382                         int index = 3 * (i_rng * (precision + 1) + i); 
    383  
    384                         Vector3 currentVertex = {torus_vertices[i*3], torus_vertices[i*3+1], torus_vertices[i*3+2]}; 
    385                          
    386                         rotateVectorY(currentVertex, ((float)i_rng * 2.0 * PI) / (float)precision); 
    387                                                  
    388                         Vector3 currentNormal = {torus_normals[i*3], torus_normals[i*3+1], torus_normals[i*3+2]}; 
    389                          
    390                         rotateVectorY(currentNormal, ((float)i_rng * 2.0 * PI) / (float)precision); 
    391  
    392                         torus_normals[index + 0] = currentNormal[0]; 
    393                         torus_normals[index + 1] = currentNormal[1]; 
    394                         torus_normals[index + 2] = currentNormal[2]; 
    395                  
    396                         torus_vertices[index + 0] = currentVertex[0]; 
    397                         torus_vertices[index + 1] = currentVertex[1]; 
    398                         torus_vertices[index + 2] = currentVertex[2]; 
    399                 } 
    400         } 
    401  
    402         for (int i_rng = 0; i_rng < precision; ++ i_rng) 
    403         { 
    404                 for (int i = 0; i < precision; ++ i) 
    405                 { 
    406                         int index = ((i_rng * precision + i) * 2) * 3; 
    407  
    408                         torus_indices[index+0] = (i_rng     * (precision+1) + i)*3; 
    409                         torus_indices[index+1] = ((i_rng+1) * (precision+1) + i)*3; 
    410                         torus_indices[index+2] = (i_rng     * (precision+1) + i + 1)*3; 
    411  
    412                         index = ((i_rng * precision + i) * 2 + 1) * 3; 
    413  
    414                         torus_indices[index+0] = (i_rng     * (precision+1) + i + 1)*3; 
    415                         torus_indices[index+1] = ((i_rng+1) * (precision+1) + i)*3; 
    416                         torus_indices[index+2] = ((i_rng+1) * (precision+1) + i + 1)*3; 
    417                 } 
    418         } 
    419 } 
    420  
    421  
    422 /** Counts the triangles of the teapot. 
    423         traverses through all the triangle strips. 
    424 */ 
    425 int Geometry::CountTeapotTriangles() 
    426 { 
    427         int result = 0; 
    428         int i = 0; 
    429  
    430         // n - 2 triangles are drawn for a strip 
    431         while (i < num_teapot_indices) 
    432         { 
    433                 while (teapot_indices[i] != STRIP_END) 
    434                 {        
    435                         result ++;; 
    436                         ++ i;            
    437                 } 
    438                 result -= 2; 
    439                 ++ i; // skip STRIP_END 
    440         } 
    441  
    442         return result; 
    443 } 
    444  
    445  
    446 /**     Counts the triangles of the torus 
    447 */ 
    448 int Geometry::CountTorusTriangles() 
    449 { 
    450         // every 3 indices specify one triangle 
    451         return num_torus_indices / 3; 
    452 } 
    453  
    454 /** 
    455         counts the triangles of the sphere. 
    456         sphere_precision / 2 + 1 strips with sphere_precision * 2 - 2 triangles each 
    457 */ 
    458 int Geometry::CountSphereTriangles() 
    459 { 
    460         return sphere_precision * sphere_precision; 
    461 } 
    462  
    463  
    464 int Geometry::CountTriangles(int objectType) 
    465 { 
    466         int result = 0; 
    467  
    468         switch (objectType) 
    469         { 
    470                 case TEAPOT: 
    471                         result = CountTeapotTriangles(); 
    472                         break; 
    473                 case TORUS: 
    474                         result = CountTorusTriangles(); 
    475                         break; 
    476                 case SPHERE:     
    477                         result = CountSphereTriangles(); 
    478                         break; 
    479                 default: 
    480                         break; 
    481         } 
    482  
    483         return result; 
    484 } 
    485  
    486  
    487 void Geometry::Transform() 
    488 { 
    489         glMultMatrixd(mTransform); 
    490 } 
    491  
    492 void Geometry::CalcTransform() 
    493 { 
    494         Matrix4x4 scale; 
    495         Matrix4x4 xrot; 
    496         Matrix4x4 yrot; 
    497         Matrix4x4 zrot; 
    498         Matrix4x4 transl; 
    499  
    500         makeScaleMtx(scale, mScale, mScale, mScale); 
    501         makeTranslationMtx(transl, mTranslation); 
    502         makeRotationXMtx(xrot, mXRotation * PI_180); 
    503         makeRotationYMtx(yrot, mYRotation * PI_180); 
    504         makeRotationZMtx(zrot, mZRotation * PI_180); 
    505  
    506         copyMatrix(mTransform, IDENTITY); 
    507         mult(mTransform, mTransform, transl); 
    508         mult(mTransform, mTransform, xrot); 
    509         mult(mTransform, mTransform, yrot); 
    510         mult(mTransform, mTransform, zrot); 
    511         mult(mTransform, mTransform, scale); 
    512 } 
    513  
    514  
    515 /** Renders a sphere with sphere_precision subdivisions.  
    516     Note: works only for even sphere_precision 
    517 */ 
    518 void Geometry::RenderSphere() 
    519 { 
    520         Vector3 vertex; 
    521  
    522         // this algorithm renders the triangles clockwise 
    523         glFrontFace(GL_CW); 
    524  
    525         for (int j = 0; j < sphere_precision / 2; ++ j)  
    526         { 
    527                 double alpha = j * PI * 2.0 / (double)sphere_precision - PI_2; 
    528                 double beta = (j + 1) * PI * 2.0 / (double)sphere_precision - PI_2; 
    529  
    530                 glBegin(GL_TRIANGLE_STRIP); 
    531  
    532                 for (int i = 0; i <= sphere_precision; ++ i)  
    533                 { 
    534                         double gamma = i * PI * 2.0 / (double)sphere_precision; 
    535          
    536                         vertex[0] = sphere_radius * cos(beta) * cos(gamma); 
    537                         vertex[1] = sphere_radius * sin(beta); 
    538                         vertex[2] = sphere_radius * cos(beta) * sin(gamma); 
    539  
    540                         glNormal3dv(vertex); 
    541                         glVertex3dv(vertex); 
    542  
    543                         vertex[0] = sphere_radius * cos(alpha) * cos(gamma); 
    544                         vertex[1] = sphere_radius * sin(alpha); 
    545                         vertex[2] = sphere_radius * cos(alpha) * sin(gamma); 
    546  
    547                     glNormal3dv(vertex); 
    548                         glVertex3dv(vertex); 
    549  
    550                 } 
    551                 glEnd(); 
    552         } 
    553  
    554         glFrontFace(GL_CCW); 
    555 } 
    556  
    557 } 
    558  
    559 #endif 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.h

    r2752 r2755  
    44#include "common.h" 
    55#include "AxisAlignedBox3.h" 
    6  
     6#include "Triangle3.h" 
    77 
    88 
     
    2323        Geometry(const TriangleContainer &triangles); 
    2424 
     25        int CountTriangles() const { return (int)mTriangles.size(); } 
     26 
     27 
    2528protected: 
    2629 
     
    3538class SceneEntity 
    3639{ 
     40public: 
     41 
    3742        /** Create scene entity. 
    3843        */ 
     
    4449        */ 
    4550        void SetGeometry(Geometry *geom); 
     51        /** See set 
     52        */ 
     53        Geometry *GetGeometry() const { return mGeometry; } 
    4654        /** Set pointer to the geometry 
    4755        */ 
    48         void SetTransformation(const Matrix4x4 *trafo); 
     56        void SetTransformation(Matrix4x4 *trafo); 
    4957        /** Set pointer to the material 
    5058        */ 
     
    5967        */ 
    6068        int GetLastVisited() const; 
     69 
    6170 
    6271protected: 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Material.cpp

    r2751 r2755  
    88{ 
    99        return RgbColor(a + Random(b), a + Random(b), a + Random(b)); 
     10} 
     11 
     12 
     13  
     14Material::Material(): mId(0) 
     15{} 
     16   
     17 
     18Material::Material(const int id): mId(id) 
     19{ 
     20} 
     21 
     22 
     23Material::Material(const RgbColor &color):mDiffuseColor(color), 
     24mAmbientColor(color), 
     25mSpecularColor(0,0,0), mId(0) 
     26{ 
     27} 
     28 
     29 
     30int Material::GetId() const 
     31{ 
     32        return mId; 
    1033} 
    1134 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Material.h

    r2751 r2755  
    66{ 
    77 
     8 
    89class RgbColor  
    910{ 
     11 
    1012public: 
     13 
    1114  float r, g, b; 
    1215 
     
    4447{ 
    4548public: 
     49 
    4650  RgbColor mDiffuseColor; 
    4751  RgbColor mSpecularColor; 
    4852  RgbColor mAmbientColor; 
    4953   
    50   Material(): mId(0) 
    51   { 
    52   } 
     54  Material(); 
    5355   
    54   Material(const int id): mId(id) 
    55   { 
    56   } 
     56  Material(const int id); 
    5757 
    58   Material(const RgbColor &color):mDiffuseColor(color), 
    59                                                                   mAmbientColor(color), 
    60                                                                   mSpecularColor(0,0,0), mId(0) 
    61   { 
    62   } 
    63    
    64   friend Material RandomMaterial(); 
    65    
     58  Material(const RgbColor &color); 
    6659  /** Returns unique material id. 
    6760  */ 
    68   int GetId() const 
    69   { 
    70           return mId; 
    71   } 
     61  int GetId() const; 
     62 
     63  friend Material RandomMaterial(); 
    7264 
    7365protected: 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.cpp

    r2751 r2755  
    88Plane3::Plane3(const Vector3 &a, const Vector3 &b, const Vector3 &c)  
    99{ 
    10     Vector3 v1=a-b, v2=c-b; 
    11     mNormal = Normalize(CrossProd(v2,v1)); 
     10    Vector3 v1 = a - b, v2 = c - b; 
     11    mNormal = Normalize(CrossProd(v2, v1)); 
    1212    mD = -DotProd(b, mNormal); 
     13} 
     14 
     15 
     16Plane3::Plane3(Vector3 &normal, float dist):  
     17mNormal(normal), mD(dist) 
     18{ 
    1319} 
    1420 
     
    2834        Vector3 sx(a.mNormal.x, b.mNormal.x, c.mNormal.x), 
    2935                    sy(a.mNormal.y, b.mNormal.y, c.mNormal.y), 
    30                         sz(a.mNormal.z, b.mNormal.z, c.mNormal.z), 
    31                         sd(a.mD, b.mD, c.mD); 
     36                    sz(a.mNormal.z, b.mNormal.z, c.mNormal.z), 
     37                    sd(a.mD, b.mD, c.mD); 
    3238 
    33   Matrix4x4 md(a.mNormal, b.mNormal, c.mNormal), mx, my, mz; 
     39        Matrix4x4 md(a.mNormal, b.mNormal, c.mNormal), mx, my, mz; 
    3440 
    35   mx.SetColumns(sd, sy, sz); 
    36   my.SetColumns(sx, sd, sz); 
    37   mz.SetColumns(sx, sy, sd); 
    38    
    39   const float det = md.Det3x3(); 
     41        mx.SetColumns(sd, sy, sz); 
     42        my.SetColumns(sx, sd, sz); 
     43        mz.SetColumns(sx, sy, sd); 
    4044 
    41   if (fabs(det) < TRASH) 
    42     return false; 
     45        const float det = md.Det3x3(); 
    4346 
    44   result.SetValue(mx.Det3x3()/det, 
    45                                   my.Det3x3()/det, 
    46                                   mz.Det3x3()/det); 
    47    
    48   return true; 
     47        if (fabs(det) < TRASH) 
     48                return false; 
     49 
     50        result.SetValue(mx.Det3x3()/det, 
     51                my.Det3x3()/det, 
     52                mz.Det3x3()/det); 
     53 
     54        return true; 
    4955} 
    5056 
    5157 
    52  bool PlaneIntersection(const Plane3 &p1, const Plane3 &p2) 
    53  { 
    54          return  
    55                  p1.mNormal.x != p2.mNormal.x || 
    56                  p1.mNormal.y != p2.mNormal.y || 
    57                  p1.mNormal.z != p2.mNormal.z || 
    58                  p1.mD == p2.mD; 
    59  } 
     58bool PlaneIntersection(const Plane3 &p1, const Plane3 &p2) 
     59{ 
     60        return  
     61                p1.mNormal.x != p2.mNormal.x || 
     62                p1.mNormal.y != p2.mNormal.y || 
     63                p1.mNormal.z != p2.mNormal.z || 
     64                p1.mD == p2.mD; 
     65} 
    6066 
    6167 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.h

    r2751 r2755  
    1 #ifndef _Plane3_H__ 
    2 #define _Plane3_H__ 
     1#ifndef __Plane3_H__ 
     2#define __Plane3_H__ 
    33 
    44#include "Vector3.h" 
     5 
    56 
    67namespace CHCDemo  
     
    1516        Plane3() {} 
    1617 
     18        Plane3(Vector3 &normal, float dist); 
     19 
    1720        Plane3(const Vector3 &a, const Vector3 &b, const Vector3 &c); 
    1821 
    1922        Plane3(const Vector3 &normal, const Vector3 &point); 
    2023 
    21         void ReverseOrientation() 
     24        inline void ReverseOrientation() 
    2225        { 
    2326                mNormal *= -1; 
    2427                mD *= -1; 
    2528        } 
    26  
    27         float Distance(const Vector3 &v) const  
     29        /** Get disance to point. 
     30        */ 
     31        inline float Distance(const Vector3 &v) const  
    2832        { 
    2933                return DotProd(v, mNormal) + mD; 
     
    3135 
    3236        enum {BACK_SIDE = -1, INTERSECTS = 0, FRONT_SIDE = 1}; 
    33  
    3437        /** Returns 1 if v is on front side, -1 if on back side, 0 if on plane. 
    3538        */ 
     
    5255 
    5356 
    54         ////////////////// 
     57        /////////// 
    5558        //-- friends 
    5659 
     
    6164        friend std::ostream &operator<<(std::ostream &s, const Plane3 &p)  
    6265        {        
    63                 s<<p.mNormal<<" "<<p.mD; 
     66                s << p.mNormal << " " << p.mD; 
    6467                return s; 
    6568        } 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp

    r2754 r2755  
    5757}*/ 
    5858 
    59 #if 0 
    60 void RenderTraverser::TraverseNode(HierarchyNode *node) 
    61 { 
    62         if(node->IsLeaf()) 
    63                 mNumRenderedGeometry += node->Render(); 
     59void RenderTraverser::EnqueueNode(BvhNode *node) 
     60{ 
     61        mBvh->CalcDistance(node); 
     62        mDistanceQueue.push(node); 
     63} 
     64 
     65 
     66void RenderTraverser::TraverseNode(BvhNode *node) 
     67{ 
     68        if (node->IsLeaf()) 
     69        { 
     70                //mNumRenderedGeometry += node->Render(); 
     71        } 
    6472        else  
    6573        { 
    6674                // for non leafs this renders only the bounding volume (if the flag is set) 
    6775                //node->Render(); 
    68                 mDistanceQueue.push(node->GetLeftChild()); 
    69                 mDistanceQueue.push(node->GetRightChild()); 
    70         } 
    71 } 
     76                BvhInterior *interior = static_cast<BvhInterior *>(node); 
     77 
     78                EnqueueNode(interior->GetFront()); 
     79                EnqueueNode(interior->GetBack()); 
     80        } 
     81} 
     82 
     83#if 0 
    7284 
    7385void RenderTraverser::RenderVisualization() 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.h

    r2754 r2755  
    55#include <stack> 
    66#include "glInterface.h" 
    7  
     7#include "Bvh.h" 
    88 
    99namespace CHCDemo 
    1010{ 
    1111 
    12 class BvhNode; 
    13 class Bvh; 
    1412class Camera; 
    1513class Matrix4x4; 
     
    4442 
    4543//typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, myless<std::vector<BvhNode *>::value_type> > TraversalQueue; 
     44typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, myless> TraversalQueue; 
    4645 
    4746/** Abstract class implementing a scene traversal for rendering. 
     
    112111        void Switch2GLQueryState(); 
    113112 
     113        void EnqueueNode(BvhNode *node); 
    114114 
    115 protected: 
     115        //////////// 
     116        //-- members 
    116117 
    117118        // /the current clip planes of the view frustum 
     
    126127        Bvh *mBvh; 
    127128        /// use a priority queue rather than a renderstack 
    128         //PriorityQueue mDistanceQueue;  
     129        TraversalQueue mDistanceQueue;  
    129130         
    130131        int mFrameID; 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/chc_revisited.vcproj

    r2754 r2755  
    120120                        <Tool 
    121121                                Name="VCCLCompilerTool" 
     122                                Optimization="3" 
    122123                                InlineFunctionExpansion="2" 
    123124                                EnableIntrinsicFunctions="true" 
     
    130131                                RuntimeTypeInfo="false" 
    131132                                UsePrecompiledHeader="0" 
     133                                BrowseInformation="1" 
    132134                                WarningLevel="3" 
    133135                                Detect64BitPortabilityProblems="true" 
     
    205207                        </File> 
    206208                        <File 
     209                                RelativePath=".\Material.cpp" 
     210                                > 
     211                        </File> 
     212                        <File 
    207213                                RelativePath=".\OcclusionQuery.cpp" 
    208214                                > 
     
    247253                        </File> 
    248254                        <File 
     255                                RelativePath=".\BinaryLoader.cpp" 
     256                                > 
     257                        </File> 
     258                        <File 
     259                                RelativePath=".\BinaryLoader.h" 
     260                                > 
     261                        </File> 
     262                        <File 
     263                                RelativePath=".\BvhLoader.cpp" 
     264                                > 
     265                        </File> 
     266                        <File 
     267                                RelativePath=".\BvhLoader.h" 
     268                                > 
     269                        </File> 
     270                        <File 
    249271                                RelativePath=".\common.cpp" 
    250272                                > 
     
    256278                        <File 
    257279                                RelativePath=".\glInterface.h" 
    258                                 > 
    259                         </File> 
    260                         <File 
    261                                 RelativePath=".\Material.cpp" 
    262280                                > 
    263281                        </File> 
  • GTP/trunk/App/Demos/Vis/CHC_revisited/common.h

    r2754 r2755  
    2525class BvhLeaf; 
    2626class OcclusionQuery; 
     27class SceneEntity; 
     28 
    2729 
    2830 
     
    465467 
    466468typedef std::vector<BvhNode *> BvhNodeContainer; 
     469typedef std::vector<SceneEntity *> SceneEntityContainer; 
    467470typedef std::vector<BvhLeaf *> BvhLeafContainer; 
    468471typedef std::vector<Triangle3> TriangleContainer; 
Note: See TracChangeset for help on using the changeset viewer.