Ignore:
Timestamp:
01/12/09 00:17:58 (15 years ago)
Author:
mattausch
Message:
 
Location:
GTP/trunk/App/Demos/Vis/FriendlyCulling/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp

    r3267 r3269  
    857857        CollectNodes(mRoot, nodes); 
    858858 
    859         cout << "recomputing bounds, children will be tested in depth " << mMaxDepthForTestingChildren << endl; 
     859        cout << "\nrecomputing bounds, children will be tested in depth " << mMaxDepthForTestingChildren << endl; 
    860860 
    861861        int success = 0; 
     
    14301430        // the movements of the objects within 
    14311431 
     1432         
     1433        cout << "\n==============================" << endl; 
    14321434        cout << "creating dynamic bvh branch"  << endl; 
    14331435 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhConstructor.cpp

    r3268 r3269  
    88#include <stack> 
    99#include <fstream> 
     10 
     11#define MAX_FLOAT 1e20f 
     12 
    1013 
    1114#ifdef _CRT_SET 
     
    3235mFirst(first), 
    3336mLast(last), 
    34 mMaxDepth(10), 
     37mMaxDepth(20), 
    3538mMaxObjects(1), 
    36 mNumNodes(0) 
    37 { 
     39mMaxTriangles(1), 
     40mNumNodes(0), 
     41mSplitType(SAH) 
     42{ 
     43} 
     44 
     45 
     46float BvhConstructor::EvaluateSahCost(BvhLeaf *leaf, int axis, float position) 
     47{ 
     48        // count triangles on the left / right 
     49        int left = 0; 
     50        int right = 0; 
     51        AxisAlignedBox3 leftBox, rightBox; 
     52 
     53        leftBox.Initialize(); 
     54        rightBox.Initialize(); 
     55 
     56        const int candidates = std::max(50, (int)(leaf->CountPrimitives() / 20)); 
     57        const float finc = leaf->CountPrimitives() / (float)candidates; 
     58 
     59        int i = leaf->mFirst; 
     60        float fi = leaf->mFirst + 0.5f; 
     61 
     62        AxisAlignedBox3 box; 
     63 
     64        for (; i <= leaf->mLast;)  
     65        { 
     66                box = mEntities[i]->GetWorldBoundingBox(); 
     67 
     68                if (box.Center(axis) < position)  
     69                { 
     70                        ++ left; 
     71                        // update the box 
     72                        leftBox.Include(box); 
     73                }  
     74                else  
     75                { 
     76                        ++ right; 
     77                        rightBox.Include(box); 
     78                } 
     79                  
     80                fi += finc; 
     81                i = (int)fi; 
     82        } 
     83 
     84        float bW = 1.0f; 
     85        float leftRatio = left / (float)leaf->CountPrimitives(); 
     86        float rightRatio = right / (float)leaf->CountPrimitives(); 
     87 
     88        float saLeft = 0.0f; 
     89        float saRight = 0.0f; 
     90 
     91        // not a valid split 
     92        if (!left || !right) 
     93                return 1e25f; 
     94 
     95        saLeft = leftBox.SurfaceArea(); 
     96        saRight = rightBox.SurfaceArea(); 
     97 
     98 
     99        return 
     100                saLeft  * ((1.0f - bW) + bW * leftRatio) +  
     101                saRight * ((1.0f - bW) + bW * rightRatio); 
     102} 
     103 
     104 
     105float BvhConstructor::SelectPlaneSah(BvhLeaf *leaf, int &axis, float &minCost) 
     106{ 
     107        minCost = MAX_FLOAT; 
     108        float bestPos = minCost; 
     109        int bestAxis = 0; 
     110 
     111        //  cout<<"Evaluating axis..."<<endl<<flush; 
     112 
     113        const int initialPlanes = 3; 
     114 
     115        // initiate the costs 
     116        for (axis = 0; axis < 3; ++ axis)  
     117        { 
     118                const float size = leaf->mBox.Size(axis); 
     119 
     120                for (int i = 0; i < initialPlanes; ++ i)  
     121                { 
     122                        const float pos = leaf->mBox.Min(axis) + (i + 1) * size / (initialPlanes + 1); 
     123                        const float cost = EvaluateSahCost(leaf, axis, pos); 
     124 
     125                        if (cost < minCost)  
     126                        { 
     127                                minCost = cost; 
     128                                bestPos = pos; 
     129                                bestAxis = axis; 
     130                        } 
     131                } 
     132        } 
     133 
     134        axis = bestAxis; 
     135 
     136        //  cout<<axis<<endl<<flush; 
     137        const float shrink = 0.5f; 
     138 
     139        // now hierarchically refine the initial interval 
     140        float size = shrink *  
     141                (leaf->mBox.Max(axis) - leaf->mBox.Min(axis)) / (initialPlanes + 1); 
     142 
     143        const int steps = 4; 
     144        float cost; 
     145 
     146        for (int i = 0; i < steps; ++ i)  
     147        { 
     148                const float left = bestPos - size; 
     149                const float right = bestPos + size; 
     150 
     151                cost = EvaluateSahCost(leaf, axis, left); 
     152 
     153                if (cost < minCost)  
     154                { 
     155                        minCost = cost; 
     156                        bestPos = left; 
     157                } 
     158 
     159                cost = EvaluateSahCost(leaf, axis, right); 
     160 
     161                if (cost < minCost)  
     162                { 
     163                        minCost = cost; 
     164                        bestPos = right; 
     165                } 
     166 
     167                size = shrink * size; 
     168        } 
     169 
     170        //OUT1("best axis: " << axis << " " << bestPos << " " << minCost); 
     171 
     172        return bestPos; 
    38173} 
    39174 
     
    102237 
    103238 
     239int BvhConstructor::SortTrianglesObjectMedian(BvhLeaf *leaf, int axis, float &pos) 
     240{ 
     241        // Now distribute the objects into the subnodes 
     242        // Use QuickMedian sort 
     243        int l = leaf->mFirst; 
     244        int r = leaf->mLast; 
     245        int k = (l + r) / 2; 
     246 
     247        while (l < r)  
     248        { 
     249                int i = l; 
     250                int j = r; 
     251 
     252                // get some estimation of the pivot 
     253                pos = mEntities[(l + r) / 2]->GetBoundingBox().Center(axis); 
     254 
     255                while (1)  
     256                { 
     257                        while ((i <= leaf->mLast) && (mEntities[i]->GetWorldBoundingBox().Center(axis) < pos)) 
     258                                ++ i; 
     259 
     260                        while((j >= leaf->mFirst) && (pos < mEntities[j]->GetWorldBoundingBox().Center(axis))) 
     261                                -- j; 
     262 
     263                        if (i <= j)  
     264                        { 
     265                                std::swap(mEntities[i], mEntities[j]); 
     266                                ++ i; 
     267                                -- j; 
     268                        } 
     269                        else 
     270                        { 
     271                                break; 
     272                        } 
     273                } 
     274 
     275                // now check the extents 
     276                if (i >= k) 
     277                        r = j; 
     278                else 
     279                        l = i; 
     280        } 
     281 
     282        return k; 
     283} 
     284 
     285 
    104286BvhNode *BvhConstructor::SubdivideLeaf(BvhLeaf *leaf,  
    105287                                                                           int parentAxis 
     
    114296 
    115297        //const int axis = (parentAxis + 1) % 3; 
    116         const int axis = leaf->mBox.MajorAxis(); 
     298        int axis = leaf->mBox.MajorAxis(); 
    117299        const int scale = 20; 
    118300 
     
    121303        int split = -1; 
    122304        float pos = -1.0f; 
    123          
     305 
    124306        // Spatial median subdivision 
    125         split = SortTrianglesSpatialMedian(leaf, axis); 
    126         pos = leaf->mBox.Center()[axis]; 
     307        switch (mSplitType)  
     308        { 
     309        case SPATIAL_MEDIAN: 
     310                split = SortTrianglesSpatialMedian(leaf, axis); 
     311                pos = leaf->mBox.Center()[axis]; 
     312                break; 
     313        case OBJECT_MEDIAN: 
     314                // Object median subdivision: approximately the same number 
     315                // of objects on the left of the the splitting point. 
     316                split = SortTrianglesObjectMedian(leaf, axis, pos); 
     317                break; 
     318        case SAH: 
     319                { 
     320                        float cost; 
     321                        pos = SelectPlaneSah(leaf, axis, cost); 
     322 
     323                        if (pos != MAX_FLOAT) 
     324                        { 
     325                                split = SortTriangles(leaf, axis, pos); 
     326                        } 
     327 
     328                        if ((pos == MAX_FLOAT) || (split == leaf->mLast)) 
     329                        { 
     330                                split = -1; 
     331                                split = SortTrianglesObjectMedian(leaf, axis, pos); 
     332                        } 
     333                } 
     334                break; 
     335        default: 
     336                cerr << "should not come here" << endl; 
     337                break; 
     338        } 
    127339         
    128340        if (split == leaf->mLast) 
     
    168380 
    169381 
     382int BvhConstructor::CountTriangles(BvhNode *node) const 
     383{ 
     384        int numTriangles = 0; 
     385 
     386        for (int i = node->mFirst; i <= node->mLast; ++ i) 
     387        { 
     388                numTriangles += mEntities[i]->CountNumTriangles(0); 
     389        } 
     390 
     391        return numTriangles; 
     392} 
     393 
     394 
    170395bool BvhConstructor::TerminationCriteriaMet(BvhLeaf *leaf) const 
    171396{ 
    172397        const bool criteriaMet =  
    173398                (leaf->mDepth > mMaxDepth) || 
    174                 (leaf->CountPrimitives() <= mMaxObjects); 
     399                (leaf->CountPrimitives() <= mMaxObjects) || 
     400                (CountTriangles(leaf) <= mMaxTriangles); 
    175401 
    176402        return criteriaMet; 
     
    188414        l->mLast = mLast; 
    189415 
    190         cout << "constructing bvh from "  << l->mFirst << " to " << l->mLast << endl; 
     416        cout << "\n================================" << endl; 
     417        cout << "constructing bvh for " << l->mLast - l->mFirst + 1 << " entities" << endl; 
    191418 
    192419        l->mBox = SceneEntity::ComputeBoundingBox(mEntities + mFirst, mLast - mFirst + 1); 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhConstructor.h

    r3267 r3269  
    2121        BvhNode *Construct(int &nodes); 
    2222 
     23        /** Types of split heuristics. 
     24        */       
     25        enum {SPATIAL_MEDIAN, OBJECT_MEDIAN, SAH};       
    2326 
    2427protected: 
    2528 
    26         int SortTriangles(BvhLeaf *leaf, int axis, float position); 
     29        ////////// 
     30        //-- sorting functions 
    2731 
    28         int SortTrianglesSpatialMedian(BvhLeaf *leaf, int axis); 
    29  
     32        /** The method of subdividing objects into halves in some axis using spatial median 
     33        */ 
     34        int     SortTrianglesSpatialMedian(BvhLeaf *leaf, int axis); 
     35        /** The method of subdividing objects into halves in some axis 
     36                using object median. 
     37        */ 
     38        int SortTrianglesObjectMedian(BvhLeaf *leaf, int axis, float &pos); 
     39        /** sort triangles along the axis with respect to the splitting plane  
     40                given by axis/position return index of the first tiangles belong  
     41                to the front of the splitting plane. 
     42        */ 
     43        int     SortTriangles(BvhLeaf *leaf, const int axis, const float position); 
     44        /** sort triangles by their area. 
     45        */ 
     46        int SortTrianglesSurfaceArea(BvhLeaf *leaf, float sa); 
     47        /** This function drives the subdivision. 
     48        */ 
    3049        BvhNode *SubdivideLeaf(BvhLeaf *leaf, int parentAxis); 
    3150 
    3251        inline bool TerminationCriteriaMet(BvhLeaf *leaf) const; 
     52        /** Update the bounding box of this node and the child nodes 
     53        */ 
     54        void UpdateBoundingBoxes(BvhNode *node); 
     55        /** Select splitting plane using SAH - returns the position of the splitting plane. 
     56        */ 
     57        float SelectPlaneSah(BvhLeaf *leaf, int &axis, float &minCost); 
     58        /** evaluate the SAH cost of a particulkar splitting plane 
     59        */ 
     60        float EvaluateSahCost(BvhLeaf *leaf, int axis, float position); 
    3361 
    34         void UpdateBoundingBoxes(BvhNode *node); 
     62        int CountTriangles(BvhNode *node) const; 
     63 
    3564 
    3665 
     
    4574        int mMaxObjects; 
    4675        int mNumNodes; 
     76        int mSplitType; 
     77        int mMaxTriangles; 
    4778}; 
    4879 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhLoader.cpp

    r3267 r3269  
    138138{ 
    139139 
    140         cout << "\n******************* bvh *******************" << endl; 
    141  
    142140        Bvh *bvh = new Bvh(staticEntities, dynamicEntities, maxDepthForTestingChildren); 
    143141 
    144         cout << "here8 " << (int)bvh->mStaticGeometrySize - 1 << endl; 
    145142        BvhConstructor bvhConstructor(bvh->mGeometry,  
    146143                                          0, 
  • GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp

    r3268 r3269  
    13871387 
    13881388                if (recordFrames && replayPath) 
     1389                { 
     1390                        // record all frames of the walkthrough 
    13891391                        deferredShader->SetSaveFrame(recordedFramesSuffix, currentReplayFrame); 
     1392                } 
    13901393                else if (makeSnapShot) 
    1391                         deferredShader->SetSaveFrame("snap", snapShotIdx ++);            
     1394                { 
     1395                        // make snap shot 
     1396                        deferredShader->SetSaveFrame("snap", snapShotIdx ++); 
     1397                } 
    13921398                else 
     1399                { 
     1400                        // do nothing 
    13931401                        deferredShader->SetSaveFrame("", -1);            
    1394  
     1402                } 
    13951403                //if (makeSnapShot) makeSnapShot = false; 
    13961404 
     
    14021410        renderState.SetRenderTechnique(FORWARD); 
    14031411        renderState.Reset(); 
    1404  
    14051412 
    14061413        glDisableClientState(GL_VERTEX_ARRAY); 
Note: See TracChangeset for help on using the changeset viewer.