Ignore:
Timestamp:
10/26/08 18:29:27 (16 years ago)
Author:
mattausch
Message:
 
File:
1 edited

Legend:

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

    r3069 r3070  
    151151 
    152152 
     153 
     154inline AxisAlignedBox3 ComputeBoundingBox(SceneEntity **entities, int numEntities) 
     155{ 
     156        AxisAlignedBox3 box = entities[0]->GetWorldBoundingBox(); 
     157 
     158        for (int i = 1; i < numEntities; ++ i) 
     159        { 
     160                box.Include(entities[i]->GetWorldBoundingBox()); 
     161        } 
     162 
     163        return box; 
     164} 
     165 
     166 
    153167Bvh::Bvh() 
    154168{ 
     
    419433        if (!mDynamicEntities.empty()) 
    420434        { 
    421                 UpdateDynamicBranch(); 
     435                if (!mDynamicRoot) 
     436                        CreateDynamicBranch(); 
     437                 
     438                UpdateDynamicBranch(mDynamicRoot); 
    422439        } 
    423440} 
     
    448465        { 
    449466                SceneEntity *ent = entities[i]; 
    450                 float dist = ent->GetTransformedBoundingBox().GetMaxDistance(sNearPlane); 
     467                float dist = ent->GetWorldBoundingBox().GetMaxDistance(sNearPlane); 
    451468 
    452469                if (dist > maxDist) maxDist = dist; 
     
    800817 
    801818 
    802 void Bvh::ComputeBvhStats()  
    803 { 
     819void Bvh::ComputeBvhStats(BvhNode *root, BvhStats &bvhStats)  
     820{ 
     821        bvhStats.Reset(); 
    804822        std::stack<BvhNode *> nodeStack; 
    805         nodeStack.push(mRoot); 
     823        nodeStack.push(root); 
    806824 
    807825        int numVirtualLeaves = 0; 
     826        int numGeometry = 0; 
    808827 
    809828        while (!nodeStack.empty())  
     
    815834                { 
    816835                        ++ numVirtualLeaves; 
     836                        numGeometry += node->CountPrimitives(); 
    817837 
    818838                        BvhLeaf *leaf = static_cast<BvhLeaf *>(node); 
    819839 
    820                         mBvhStats.mTriangles += CountTriangles(leaf); 
    821                         mBvhStats.mLeafSA += leaf->mBox.SurfaceArea(); 
    822                         mBvhStats.mLeafVol += leaf->mBox.GetVolume(); 
     840                        bvhStats.mTriangles += CountTriangles(leaf); 
     841                        bvhStats.mLeafSA += leaf->mBox.SurfaceArea(); 
     842                        bvhStats.mLeafVol += leaf->mBox.GetVolume(); 
    823843                }  
    824844                else  
    825845                { 
    826                         mBvhStats.mInteriorSA += node->mBox.SurfaceArea(); 
    827                         mBvhStats.mInteriorVol += node->mBox.GetVolume(); 
     846                        bvhStats.mInteriorSA += node->mBox.SurfaceArea(); 
     847                        bvhStats.mInteriorVol += node->mBox.GetVolume(); 
    828848 
    829849                        BvhInterior *interior = static_cast<BvhInterior *>(node); 
     
    834854        } 
    835855 
    836         mBvhStats.mGeometryRatio = mGeometrySize / (float)numVirtualLeaves; 
    837         mBvhStats.mTriangleRatio = mBvhStats.mTriangles / (float)numVirtualLeaves; 
    838 } 
    839  
    840  
    841 void Bvh::PrintBvhStats() const 
    842 { 
    843         cout << "\n******** bvh stats: ***********" << endl; 
    844         cout << "interiorNodesSA = " << mBvhStats.mInteriorSA / mRoot->mBox.SurfaceArea() << endl; 
    845         cout << "leafNodesSA = " << mBvhStats.mLeafSA / mRoot->mBox.SurfaceArea() << endl; 
    846         cout << "interiorNodesVolume = " << mBvhStats.mInteriorVol / mRoot->mBox.GetVolume() << endl; 
    847         cout << "leafNodesVolume = " << mBvhStats.mLeafVol / mRoot->mBox.GetVolume() << endl; 
    848  
    849         cout << "geometry per leaf: " <<  mBvhStats.mGeometryRatio << endl; 
    850         cout << "triangles per leaf: " <<  mBvhStats.mTriangleRatio << endl; 
    851         cout << "**************" << endl << endl; 
     856        bvhStats.mGeometryRatio = (float)numGeometry / numVirtualLeaves; 
     857        bvhStats.mTriangleRatio = (float)bvhStats.mTriangles / numVirtualLeaves; 
     858        bvhStats.mLeaves = numVirtualLeaves; 
     859} 
     860 
     861 
     862void Bvh::PrintBvhStats(const BvhStats &bvhStats) const 
     863{ 
     864        cout << "\n============ BVH statistics =============" << endl; 
     865        cout << "interiorNodesSA = " << bvhStats.mInteriorSA / mRoot->mBox.SurfaceArea() << endl; 
     866        cout << "leafNodesSA = " << bvhStats.mLeafSA / mRoot->mBox.SurfaceArea() << endl; 
     867        cout << "interiorNodesVolume = " << bvhStats.mInteriorVol / mRoot->mBox.GetVolume() << endl; 
     868        cout << "leafNodesVolume = " << bvhStats.mLeafVol / mRoot->mBox.GetVolume() << endl; 
     869 
     870        cout << "geometry per leaf: " << bvhStats.mGeometryRatio << endl; 
     871        cout << "triangles per leaf: " << bvhStats.mTriangleRatio << endl; 
     872        cout << "===========================================" << endl << endl; 
    852873} 
    853874 
     
    11551176int Bvh::SortTriangles(BvhLeaf *leaf,  
    11561177                                           int axis,  
    1157                                            float position, 
    1158                                            SceneEntityContainer &entities) 
     1178                                           float position 
     1179                                           ) 
    11591180{ 
    11601181        int i = leaf->mFirst; 
    11611182        int j = leaf->mLast; 
    11621183 
    1163     while (1)  
    1164         { 
    1165                 while (entities[i]->GetCenter()[axis] < position)  
     1184    while (1) 
     1185        { 
     1186                while (mGeometry[i]->GetWorldCenter()[axis] < position)  
     1187                { 
     1188                        //cout<<" i " << i << " " << mGeometry[i]->GetWorldCenter()[axis]; 
    11661189                        ++ i; 
    1167          
    1168                 while (position < entities[j]->GetCenter()[axis]) 
     1190                } 
     1191 
     1192                while (position < mGeometry[j]->GetWorldCenter()[axis]) 
     1193                { 
     1194                        //cout<< axis << " j " << j << " " << mGeometry[j]->GetWorldCenter()[axis] << " " << position<< " "; 
    11691195                        -- j; 
     1196                } 
    11701197 
    11711198                // sorting finished 
     
    11731200 
    11741201                // swap entities 
    1175                 swap(entities[i], entities[j]); 
     1202                swap(mGeometry[i], mGeometry[j]); 
    11761203                         
    11771204                ++ i; 
     
    11841211 
    11851212int Bvh::SortTrianglesSpatialMedian(BvhLeaf *leaf,  
    1186                                                                         int axis, 
    1187                                                                         SceneEntityContainer &entities) 
     1213                                                                        int axis 
     1214                                                                        ) 
    11881215{ 
    11891216        // spatial median 
    11901217        float m = leaf->mBox.Center()[axis]; 
    1191         return SortTriangles(leaf, axis, m, entities); 
     1218        //cout << "here3 " << leaf->mBox << " " << leaf->mFirst << " " << leaf->mLast << endl; 
     1219        return SortTriangles(leaf, axis, m); 
    11921220} 
    11931221 
    11941222 
    11951223BvhNode *Bvh::SubdivideLeaf(BvhLeaf *leaf,  
    1196                                                         int parentAxis,  
    1197                                                         SceneEntityContainer &entities) 
     1224                                                        int parentAxis 
     1225                                                        ) 
    11981226{ 
    11991227        if (TerminationCriteriaMet(leaf)) 
    12001228        { 
    12011229                leaf->mIsVirtualLeaf = true; 
     1230                leaf->mIsMaxDepthForVirtualLeaf = true; 
    12021231                return leaf; 
    12031232        } 
    12041233 
    1205         //int axis = leaf->mBox.MajorAxis(); 
    1206         int axis = (parentAxis + 1) % 3; 
     1234        //const int axis = (parentAxis + 1) % 3; 
     1235        const int axis = leaf->mBox.MajorAxis(); 
     1236         
     1237 
     1238        const int scale = 20; 
    12071239 
    12081240        // position of the split in the partailly sorted array of triangles 
    12091241        // corresponding to this leaf 
    12101242        int split = -1; 
    1211         const int scale = 20; 
    1212  
    12131243        float pos = -1.0f; 
    1214  
     1244         
    12151245        // Spatial median subdivision 
    1216         split = SortTrianglesSpatialMedian(leaf, axis, entities); 
     1246        split = SortTrianglesSpatialMedian(leaf, axis); 
    12171247        pos = leaf->mBox.Center()[axis]; 
    12181248         
     
    12471277         
    12481278        // reset box 
    1249         leaf->mBox.Initialize(); 
     1279        //leaf->mBox.Initialize(); 
     1280 
     1281        front->mBox = ComputeBoundingBox(mGeometry + front->mFirst, front->CountPrimitives()); 
     1282        leaf->mBox = ComputeBoundingBox(mGeometry + leaf->mFirst, leaf->CountPrimitives()); 
    12501283 
    12511284        // recursively continue subdivision 
    1252         parent->mBack = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mBack), axis, entities); 
    1253         parent->mFront = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mFront), axis, entities); 
     1285        parent->mBack = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mBack), axis); 
     1286        parent->mFront = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mFront), axis); 
    12541287         
    12551288        return parent; 
     
    12671300 
    12681301 
    1269 void Bvh::UpdateDynamicBranch() 
     1302void Bvh::UpdateDynamicBranch(BvhNode *node) 
     1303{ 
     1304        if (node->IsLeaf()) 
     1305        { 
     1306                int numEntities; 
     1307                SceneEntity **entities = GetGeometry(node, numEntities); 
     1308 
     1309                node->mBox = ComputeBoundingBox(entities, numEntities); 
     1310                //cout << "box: " << node->mBox << endl; 
     1311        } 
     1312        else 
     1313        { 
     1314                BvhNode *f = static_cast<BvhInterior *>(node)->GetFront(); 
     1315                BvhNode *b = static_cast<BvhInterior *>(node)->GetBack(); 
     1316 
     1317                UpdateDynamicBranch(f); 
     1318                UpdateDynamicBranch(b); 
     1319 
     1320                node->mBox = f->mBox; 
     1321                node->mBox.Include(b->mBox); 
     1322        } 
     1323} 
     1324 
     1325 
     1326void Bvh::CreateDynamicBranch() 
    12701327{ 
    12711328        // the bvh has two main branches 
     
    12781335        // the movements of the objects within 
    12791336 
    1280         // delete old branch 
    1281         cout << "deleting old branch" << endl; 
    1282  
    12831337        DEL_PTR(mDynamicRoot); 
    12841338 
    1285         mDynamicRoot = new BvhLeaf(mRoot); 
    1286         mDynamicRoot->mBox = mRoot->mBox; 
    1287  
    1288         mDynamicRoot->mFirst = 0; 
    1289         mDynamicRoot->mLast = (int)mDynamicEntities.size() - 1; 
    1290         mDynamicRoot->mArea = mDynamicRoot->mBox.SurfaceArea(); 
    1291          
    1292         cout << "updating dynamic branch" << endl; 
    1293  
    1294         mDynamicRoot = SubdivideLeaf(static_cast<BvhLeaf *>(mDynamicRoot), 0, mDynamicEntities); 
    1295  
    1296         cout << "finished updating dynamic branch" << endl; 
    1297 } 
    1298  
    1299  
    1300 void Bvh::AddDynamicObject(SceneEntity *ent) 
    1301 { 
    1302         mDynamicEntities.push_back(ent); 
     1339        BvhLeaf *l = new BvhLeaf(mRoot); 
     1340 
     1341        l->mBox.Initialize(); 
     1342 
     1343        SceneEntityContainer::const_iterator sit, sit_end = mDynamicEntities.end(); 
     1344 
     1345        for (sit = mDynamicEntities.begin(); sit != sit_end; ++ sit) 
     1346        { 
     1347                l->mBox.Include((*sit)->GetWorldBoundingBox()); 
     1348        } 
     1349 
     1350        l->mFirst = (int)(mGeometrySize - mDynamicEntities.size()); 
     1351        l->mLast = (int)mGeometrySize - 1; 
     1352        l->mArea = l->mBox.SurfaceArea(); 
     1353         
     1354        cout << "updating dynamic branch " << l->mFirst << " " << l->mLast << endl; 
     1355 
     1356        mDynamicRoot = SubdivideLeaf(l, 0); 
     1357 
     1358        BvhStats bvhStats; 
     1359        ComputeBvhStats(mDynamicRoot, bvhStats); 
     1360 
     1361        cout << "\n=========== Dynamic BVH statistics: =========" << endl; 
     1362        cout << "leaves = " << bvhStats.mLeaves << endl; 
     1363        cout << "interiorNodesSA = " << bvhStats.mInteriorSA << endl; 
     1364        cout << "leafNodesSA = " << bvhStats.mLeafSA << endl; 
     1365        cout << "interiorNodesVolume = " << bvhStats.mInteriorVol  << endl; 
     1366        cout << "leafNodesVolume = " << bvhStats.mLeafVol << endl; 
     1367 
     1368        cout << "geometry per leaf: " << bvhStats.mGeometryRatio << endl; 
     1369        cout << "triangles per leaf: " << bvhStats.mTriangleRatio << endl; 
     1370        cout << "=============================================" << endl << endl; 
     1371} 
     1372 
     1373 
     1374void Bvh::AddDynamicObjects(const SceneEntityContainer &entities) 
     1375{ 
     1376        // copy old entities 
     1377        SceneEntity **newGeom = new SceneEntity*[mGeometrySize + (int)entities.size()]; 
     1378 
     1379        memcpy(newGeom, mGeometry, mGeometrySize * sizeof(SceneEntity *)); 
     1380 
     1381        delete [] mGeometry; 
     1382        mGeometry = newGeom; 
     1383 
     1384        // now add new entities 
     1385        SceneEntityContainer::const_iterator it, it_end = entities.end(); 
     1386 
     1387        size_t i = mGeometrySize; 
     1388        for (it = entities.begin(); it != it_end; ++ it, ++ i) 
     1389        { 
     1390                mGeometry[i] = (*it); 
     1391                mDynamicEntities.push_back(*it); 
     1392        } 
     1393 
     1394 
     1395        mGeometrySize += entities.size(); 
    13031396} 
    13041397 
Note: See TracChangeset for help on using the changeset viewer.