Changeset 1089


Ignore:
Timestamp:
07/06/06 16:22:15 (18 years ago)
Author:
mattausch
Message:
 
Location:
GTP/trunk/Lib/Vis/Preprocessing/src
Files:
5 edited

Legend:

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

    r1076 r1089  
    9292  } 
    9393 
    94         ProcessLeafObjects(leaf, NULL); 
     94        ProcessLeafObjects(NULL, leaf, NULL); 
    9595 
    9696  cout <<"KdTree Root Box:"<<mBox<<endl; 
     
    308308  } 
    309309   
    310    ProcessLeafObjects(back, leaf); 
    311     ProcessLeafObjects(front, leaf); 
     310   ProcessLeafObjects(leaf, front, back); 
     311   
    312312 
    313313  delete leaf; 
    314314  return node; 
    315315} 
    316  
    317316 
    318317 
     
    10951094 
    10961095 
    1097 void KdTree::ProcessLeafObjects(KdLeaf *leaf, KdLeaf *parent) const 
    1098 { 
    1099         ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end(); 
    1100  
    1101         for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit) 
     1096void KdTree::ProcessLeafObjects(KdLeaf *parent, KdLeaf *front, KdLeaf *back) const 
     1097{ 
     1098        if (parent) 
    11021099        { 
    1103                 Intersectable *object = *oit; 
    1104  
    1105                 if (parent) 
     1100                // remove the parents from the set 
     1101                ObjectContainer::const_iterator oit, oit_end = parent->mObjects.end(); 
     1102 
     1103                for (oit = parent->mObjects.begin(); oit != oit_end; ++ oit) 
    11061104                { 
     1105                        Intersectable *object = *oit; 
     1106 
    11071107                        set<KdLeaf *>::iterator kdit = object->mKdLeaves.find(parent); 
    11081108 
     
    11111111                                object->mKdLeaves.erase(kdit); 
    11121112                } 
    1113  
    1114                 object->mKdLeaves.insert(leaf); 
    1115  
    1116                 if (object->mKdLeaves.size() > 1) 
    1117                         leaf->mMultipleObjects.push_back(object); 
    11181113        } 
    1119 } 
    1120  
    1121  
    1122 } 
     1114 
     1115        //Intersectable::NewMail(); 
     1116 
     1117        if (front) 
     1118        { 
     1119                // Add front to leaf kd cells 
     1120                ObjectContainer::const_iterator oit, oit_end = front->mObjects.end(); 
     1121 
     1122                for (oit = front->mObjects.begin(); oit != oit_end; ++ oit) 
     1123                { 
     1124                        Intersectable *object = *oit; 
     1125                        object->mKdLeaves.insert(front); 
     1126                } 
     1127        } 
     1128 
     1129        if (back) 
     1130        { 
     1131                // Add back to leaf kd cells 
     1132                ObjectContainer::const_iterator oit, oit_end = back->mObjects.end(); 
     1133 
     1134                for (oit = back->mObjects.begin(); oit != oit_end; ++ oit) 
     1135                { 
     1136                        Intersectable *object = *oit; 
     1137                        object->mKdLeaves.insert(back);  
     1138                } 
     1139        } 
     1140 
     1141        // note: can find out about multiple objects only now after adding and deleting 
     1142        // finished  
     1143        if (front) 
     1144        { 
     1145                // find objects from multiple kd-leaves 
     1146                ObjectContainer::const_iterator oit, oit_end = front->mObjects.end(); 
     1147 
     1148                for (oit = front->mObjects.begin(); oit != oit_end; ++ oit) 
     1149                { 
     1150                        Intersectable *object = *oit; 
     1151 
     1152                        if (object->mKdLeaves.size() > 1) 
     1153                                front->mMultipleObjects.push_back(object); 
     1154                } 
     1155        } 
     1156 
     1157        if (back)  
     1158        { 
     1159                // find objects from multiple kd-leaves 
     1160                ObjectContainer::const_iterator oit, oit_end = back->mObjects.end(); 
     1161 
     1162                for (oit = back->mObjects.begin(); oit != oit_end; ++ oit) 
     1163                { 
     1164                        Intersectable *object = *oit; 
     1165 
     1166                        if (object->mKdLeaves.size() > 1) 
     1167                                back->mMultipleObjects.push_back(object); 
     1168                } 
     1169        } 
     1170         
     1171} 
     1172 
     1173 
     1174} 
  • GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.h

    r1074 r1089  
    531531 
    532532 
    533   /** does some post processing on the objects that are contained 
    534   in this leaf. 
    535   */ 
    536   void ProcessLeafObjects(KdLeaf *leaf, KdLeaf *parent) const; 
     533  /** does some post processing on the objects in the new child leaves. 
     534  */ 
     535  void ProcessLeafObjects(KdLeaf *parent, KdLeaf *front, KdLeaf *back) const; 
    537536 
    538537  int mTermMaxNodes; 
  • GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h

    r1077 r1089  
    109109 
    110110  /** Removes sample from PVS if reference count is zero. 
    111           @param visibleSampels number of references to be removed 
     111          @param visibleSamples number of references to be removed 
    112112  */ 
    113113  bool RemoveSample(T sample, const float pdf); 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp

    r1084 r1089  
    729729        interior->SetBoundingBox(tData.mBoundingBox); 
    730730 
    731         frontData.mNode = interior->GetFront(); 
    732         backData.mNode = interior->GetBack(); 
    733  
    734731        interior->mTimeStamp = mTimeStamp ++; 
    735732         
     
    738735 
    739736 
     737 
     738void VspTree::ProcessViewCellObjects(ViewCell *parent, ViewCell *front, ViewCell *back) const 
     739{ 
     740        if (parent) 
     741        { 
     742                // remove the parents from the object pvss 
     743                ObjectPvsMap::const_iterator oit, oit_end = parent->GetPvs().mEntries.end(); 
     744 
     745                for (oit = parent->GetPvs().mEntries.begin(); oit != oit_end; ++ oit) 
     746                { 
     747                        Intersectable *object = (*oit).first; 
     748                        // HACK: make sure that the view cell is removed from the pvs 
     749                        const float high_contri = 99999999999; 
     750                        object->mViewCellPvs.RemoveSample(parent, 999999); 
     751                } 
     752        } 
     753 
     754        if (front) 
     755        { 
     756                // Add front view cell to the object pvsss 
     757                ObjectPvsMap::const_iterator oit, oit_end = front->GetPvs().mEntries.end(); 
     758 
     759                for (oit = front->GetPvs().mEntries.begin(); oit != oit_end; ++ oit) 
     760                { 
     761                        Intersectable *object = (*oit).first; 
     762                        object->mViewCellPvs.AddSample(front, 1); 
     763                } 
     764        } 
     765 
     766        if (back) 
     767        { 
     768                // Add back view cell to the object pvsss 
     769                ObjectPvsMap::const_iterator oit, oit_end = back->GetPvs().mEntries.end(); 
     770 
     771                for (oit = back->GetPvs().mEntries.begin(); oit != oit_end; ++ oit) 
     772                { 
     773                        Intersectable *object = (*oit).first; 
     774                        object->mViewCellPvs.AddSample(back, 1); 
     775                } 
     776        } 
     777} 
     778 
     779 
    740780void VspTree::AddToPvs(VspLeaf *leaf, 
    741                                                   const RayInfoContainer &rays, 
    742                                                   float &sampleContributions, 
    743                                                   int &contributingSamples) 
     781                                           const RayInfoContainer &rays, 
     782                                           float &sampleContributions, 
     783                                           int &contributingSamples) 
    744784{ 
    745785        sampleContributions = 0; 
     
    762802                { 
    763803                        if (vc->AddPvsSample(ray->mTerminationObject, ray->mPdf, contribution)) 
     804                        { 
    764805                                madeContrib = true; 
     806                        } 
     807 
    765808                        sc += contribution; 
    766809                } 
     
    769812                { 
    770813                        if (vc->AddPvsSample(ray->mOriginObject, ray->mPdf, contribution)) 
     814                        { 
    771815                                madeContrib = true; 
     816                        } 
     817 
    772818                        sc += contribution; 
    773819                } 
     
    13271373 
    13281374 
    1329 inline void VspTree::GenerateUniqueIdsForPvs() 
    1330 { 
    1331         Intersectable::NewMail(); sBackId = Intersectable::sMailId; 
    1332         Intersectable::NewMail(); sFrontId = Intersectable::sMailId; 
    1333         Intersectable::NewMail(); sFrontAndBackId = Intersectable::sMailId; 
    1334 } 
    1335  
    1336  
    13371375float VspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane, 
    13381376                                                                          const VspTraversalData &data) const 
     
    13521390 
    13531391        // create unique ids for pvs heuristics 
    1354         GenerateUniqueIdsForPvs(); 
     1392        Intersectable::NewMail(); 
    13551393         
    13561394        RayInfoContainer::const_iterator rit, rit_end = data.mRays->end(); 
     
    14181456         
    14191457        // create unique ids for pvs heuristics 
    1420         GenerateUniqueIdsForPvs(); 
     1458        Intersectable::NewMail(); 
    14211459 
    14221460        const int pvsSize = data.mPvs; 
     
    14701508        const int renderCost = 1; 
    14711509 
    1472         // new object 
    1473         if ((obj->mMailbox != sFrontId) && 
    1474                 (obj->mMailbox != sBackId) && 
    1475                 (obj->mMailbox != sFrontAndBackId)) 
     1510        // object in no pvs => new 
     1511        if (!obj->Mailed() && !obj->Mailed(1) && !obj->Mailed(2)) 
    14761512        { 
    14771513                totalPvs += renderCost; 
     
    14811517        //if (cf == Ray::COINCIDENT) return; 
    14821518 
    1483         // object belongs to both PVS 
    1484         if (cf >= 0) 
    1485         { 
    1486                 if ((obj->mMailbox != sFrontId) && 
    1487                         (obj->mMailbox != sFrontAndBackId)) 
     1519        if (cf >= 0) // front pvs 
     1520        { 
     1521                if (!obj->Mailed() && !obj->Mailed(2)) 
    14881522                { 
    14891523                        frontPvs += renderCost; 
    14901524                 
    1491                         if (obj->mMailbox == sBackId) 
    1492                                 obj->mMailbox = sFrontAndBackId; 
     1525                        // already in back pvs => in both pvss 
     1526                        if (obj->Mailed(1)) 
     1527                                obj->Mail(2); 
    14931528                        else 
    1494                                 obj->mMailbox = sFrontId; 
    1495                 } 
    1496         } 
    1497  
    1498         if (cf <= 0) 
    1499         { 
    1500                 if ((obj->mMailbox != sBackId) && 
    1501                         (obj->mMailbox != sFrontAndBackId)) 
     1529                                obj->Mail(); 
     1530                } 
     1531        } 
     1532 
     1533        if (cf <= 0) // back pvs 
     1534        { 
     1535                if (!obj->Mailed(1) && !obj->Mailed(2)) 
    15021536                { 
    15031537                        backPvs += renderCost; 
    15041538                 
    1505                         if (obj->mMailbox == sFrontId) 
    1506                                 obj->mMailbox = sFrontAndBackId; 
     1539                        // already in front pvs => in both pvss 
     1540                        if (obj->Mailed()) 
     1541                                obj->Mail(2); 
    15071542                        else 
    1508                                 obj->mMailbox = sBackId; 
     1543                                obj->Mail(1); 
    15091544                } 
    15101545        } 
     
    26762711 
    26772712        SplitObjects(splitPlane, leaf->mObjects, back->mObjects, front->mObjects); 
     2713 
     2714        ProcessLeafObjects(back, leaf); 
     2715    ProcessLeafObjects(front, leaf); 
    26782716   
    26792717        //delete leaf; 
     
    27452783{ 
    27462784        float frontProb; 
    2747         float backtProb; 
     2785        float backProb; 
    27482786         
    27492787        KdLeaf *leaf = dynamic_cast<KdLeaf *>(tData.mNode); 
     
    27552793        //TODO 
    27562794        // compute global decrease in render cost 
    2757         splitData.mPriority = EvalRenderCostDecrease(splitData.mSplitPlane, tData); 
    2758         splitData.mParentData = tData; 
    2759         splitData.mMaxCostMisses = success ? tData.mMaxCostMisses : tData.mMaxCostMisses + 1; 
     2795        splitCandidate.mPriority = EvalRenderCostDecrease(splitCandidate.mSplitPlane, tData); 
     2796        splitCandidate.mParentData = tData; 
     2797        splitCandidate.mMaxCostMisses = success ? tData.mMaxCostMisses : tData.mMaxCostMisses + 1; 
    27602798} 
    27612799 
     
    30723110 
    30733111 
    3074 float OspTree::SelectSplitPlane(const VspTraversalData &tData, 
     3112float OspTree::SelectSplitPlane(const OspTraversalData &tData, 
    30753113                                                                AxisAlignedPlane &plane, 
    30763114                                                                float &pFront, 
     
    30933131        } 
    30943132 
     3133/* 
    30953134        //sAxis = 2; 
    30963135        for (int axis = 0; axis < 3; ++ axis) 
     
    31323171        } 
    31333172 
    3134  
     3173*/ 
    31353174        //-- assign values 
    31363175         
     
    31453184        return nCostRatio[bestAxis]; 
    31463185} 
     3186 
     3187 
     3188float OspTree::EvalViewCellPvsIncr(Intersectable *object) const 
     3189{ 
     3190        return 0; 
     3191} 
     3192 
     3193 
     3194float OspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane, 
     3195                                                                          const OspTraversalData &data) const 
     3196{ 
     3197#if 0 
     3198        return (float)-data.mDepth; 
     3199#endif 
     3200 
     3201        float pvsFront = 0; 
     3202        float pvsBack = 0; 
     3203        float totalPvs = 0; 
     3204 
     3205        // probability that view point lies in back / front node 
     3206        float pOverall = data.mProbability; 
     3207        float pFront = 0; 
     3208        float pBack = 0; 
     3209 
     3210 
     3211        Intersectable::NewMail(); 
     3212        ViewCell::NewMail(); 
     3213 
     3214        KdLeaf *leaf = dynamic_cast<KdLeaf *>(data.mNode); 
     3215        ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end(); 
     3216 
     3217        for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit) 
     3218        { 
     3219                Intersectable *obj = *oit; 
     3220                const AxisAlignedBox3 box = obj->GetBox(); 
     3221 
     3222                if (box.Max(candidatePlane.mAxis) > candidatePlane.mPosition) 
     3223                        pvsFront += EvalViewCellPvsIncr(obj); 
     3224                if (box.Min(candidatePlane.mAxis) > candidatePlane.mPosition) 
     3225                        pvsBack += EvalViewCellPvsIncr(obj); 
     3226        } 
     3227 
     3228 
     3229        AxisAlignedBox3 frontBox; 
     3230        AxisAlignedBox3 backBox; 
     3231 
     3232        data.mBoundingBox.Split(candidatePlane.mAxis, candidatePlane.mPosition, frontBox, backBox); 
     3233 
     3234        pFront = frontBox.GetVolume(); 
     3235        pBack = pOverall - pFront; 
     3236                 
     3237 
     3238        //-- pvs rendering heuristics 
     3239        const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize(); 
     3240        const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize(); 
     3241 
     3242        //-- only render cost heuristics or combined with standard deviation 
     3243        const float penaltyOld = EvalPvsPenalty((int)totalPvs, lowerPvsLimit, upperPvsLimit); 
     3244    const float penaltyFront = EvalPvsPenalty((int)pvsFront, lowerPvsLimit, upperPvsLimit); 
     3245        const float penaltyBack = EvalPvsPenalty((int)pvsBack, lowerPvsLimit, upperPvsLimit); 
     3246                         
     3247        const float oldRenderCost = pOverall * penaltyOld; 
     3248        const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack; 
     3249 
     3250        //Debug << "decrease: " << oldRenderCost - newRenderCost << endl; 
     3251        const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBoundingBox.GetVolume(); 
     3252         
     3253        // take render cost of node into account  
     3254        // otherwise danger of being stuck in a local minimum!! 
     3255        const float factor = 0.99f; 
     3256 
     3257        const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume(); 
     3258        return factor * renderCostDecrease + (1.0f - factor) * normalizedOldRenderCost; 
     3259} 
     3260 
     3261 
     3262void OspTree::PrepareConstruction(const ObjectContainer &objects, 
     3263                                                                  AxisAlignedBox3 *forcedBoundingBox)  
     3264{ 
     3265        mOspStats.nodes = 1; 
     3266         
     3267        if (forcedBoundingBox) 
     3268        { 
     3269                mBoundingBox = *forcedBoundingBox; 
     3270        } 
     3271        else // compute vsp tree bounding box 
     3272        { 
     3273                mBoundingBox.Initialize(); 
     3274 
     3275                ObjectContainer::const_iterator oit, oit_end = objects.end(); 
     3276 
     3277                //-- compute bounding box 
     3278        for (oit = objects.begin(); oit != oit_end; ++ oit) 
     3279                { 
     3280                        Intersectable *obj = *oit; 
     3281 
     3282                        // compute bounding box of view space 
     3283                        mBoundingBox.Include(obj->GetBox()); 
     3284                        mBoundingBox.Include(obj->GetBox()); 
     3285                } 
     3286 
     3287                mTermMinProbability *= mBoundingBox.GetVolume(); 
     3288                mGlobalCostMisses = 0; 
     3289        } 
     3290} 
     3291 
     3292 
     3293void OspTree::ProcessLeafObjects(KdLeaf *leaf, KdLeaf *parent) const 
     3294{ 
     3295        ObjectContainer::const_iterator oit, oit_end = leaf->mObjects.end(); 
     3296 
     3297        for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit) 
     3298        { 
     3299                Intersectable *object = *oit; 
     3300 
     3301                if (parent) 
     3302                { 
     3303                        set<KdLeaf *>::iterator kdit = object->mKdLeaves.find(parent); 
     3304 
     3305                        // remove parent leaf 
     3306                        if (kdit != object->mKdLeaves.end()) 
     3307                                object->mKdLeaves.erase(kdit); 
     3308                } 
     3309 
     3310                object->mKdLeaves.insert(leaf); 
     3311 
     3312                if (object->mKdLeaves.size() > 1) 
     3313                        leaf->mMultipleObjects.push_back(object); 
     3314        } 
     3315} 
     3316 
    31473317 
    31483318 
     
    32083378        cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl; 
    32093379 
    3210         /// add first candidate for view space partition 
     3380 
     3381        int pvsSize = mVspTree.ComputePvsSize(rays); 
     3382 
     3383        // -- prepare view space partition 
     3384 
     3385        // add first candidate for view space partition 
    32113386        mVspTree.mRoot = new VspLeaf(); 
    32123387        const float prop = mVspTree.mBoundingBox.GetVolume(); 
    32133388 
    3214         /// first traversal data 
    3215         VspTree::VspTraversalData tData(mVspTree.mRoot, 
     3389        // first vsp traversal data 
     3390        VspTree::VspTraversalData vData(mVspTree.mRoot, 
    32163391                                                                        0, 
    32173392                                                                        &rays, 
    32183393                                                                        //(int)objects.size(), 
    3219                                                                         mVspTree.ComputePvsSize(rays), 
     3394                                                                        pvsSize,         
    32203395                                                                        prop, 
    32213396                                                                        mVspTree.mBoundingBox); 
    32223397 
     3398 
    32233399        // compute first split candidate 
    32243400        VspTree::VspSplitCandidate *splitCandidate = new VspTree::VspSplitCandidate(); 
    3225     mVspTree.EvalSplitCandidate(tData, *splitCandidate); 
     3401    mVspTree.EvalSplitCandidate(vData, *splitCandidate); 
    32263402 
    32273403        mTQueue.push(splitCandidate); 
    32283404 
    3229         //mOspTree->PrepareConstruction(sampleRays, forcedViewSpace, rays); 
     3405 
     3406        //-- object space partition 
     3407 
     3408        mOspTree.PrepareConstruction(objects, forcedViewSpace); 
     3409 
     3410        // add first candidate for view space partition 
     3411        KdLeaf *leaf = new KdLeaf(NULL, 0); 
     3412        leaf->mObjects = objects; 
     3413 
     3414        mOspTree.mRoot = leaf; 
     3415         
     3416 
     3417        // first osp traversal data 
     3418        OspTree::OspTraversalData oData(mOspTree.mRoot, 
     3419                                                                        0, 
     3420                                                                        &rays, 
     3421                                                                        pvsSize, 
     3422                                                                        prop, 
     3423                                                                        mOspTree.mBoundingBox); 
     3424 
     3425                 
     3426        mOspTree.ProcessLeafObjects(leaf, NULL); 
     3427 
     3428        // compute first split candidate 
     3429        OspTree::OspSplitCandidate *oSplitCandidate = new OspTree::OspSplitCandidate(); 
     3430    mOspTree.EvalSplitCandidate(oData, *oSplitCandidate); 
     3431 
     3432        mTQueue.push(splitCandidate); 
    32303433} 
    32313434 
     
    32403443                return mVspTree.GlobalTerminationCriteriaMet(sc->mParentData); 
    32413444        } 
     3445        else 
     3446        { 
     3447                OspTree::OspSplitCandidate *sc =  
     3448                        dynamic_cast<OspTree::OspSplitCandidate *>(candidate); 
     3449                 
     3450                return mOspTree.GlobalTerminationCriteriaMet(sc->mParentData); 
     3451        } 
    32423452 
    32433453        return true; 
     
    32873497                } 
    32883498                else // object space split 
    3289                 { 
    3290 #if TODO 
    3291                         KdNode *r = mKdtree.Subdivide(tOspQueue, dynamic_cast<OspSplitCandidate<(splitCandidate)); 
    3292 #endif 
     3499                {                        
     3500                        OspTree::OspSplitCandidate *sc =  
     3501                                dynamic_cast<OspTree::OspSplitCandidate *>(splitCandidate); 
     3502 
     3503                        KdNode *r = mOspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 
    32933504                } 
    32943505 
  • GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h

    r1084 r1089  
    990990        float GetMemUsage() const; 
    991991 
     992        void ProcessViewCellObjects(ViewCell *parent, ViewCell *front, ViewCell *back) const; 
    992993 
    993994protected: 
     
    13801381                                                                 const OspTraversalData &data) const; 
    13811382 
     1383        float EvalViewCellPvsIncr(Intersectable *object) const; 
     1384 
     1385 
    13821386        /** Collects view cells in the subtree under root. 
    13831387        */ 
     
    14251429                                                          AxisAlignedBox3 &frontBBox); 
    14261430 
    1427         /*KdInterior *SubdivideNode(const AxisAlignedPlane &splitPlane, 
    1428                                                           OspTraversalData &tData, 
    1429                                                           OspTraversalData &frontData, 
    1430                                                           OspTraversalData &backData);*/ 
     1431        void ProcessLeafObjects(KdLeaf *leaf, KdLeaf *parent) const; 
    14311432 
    14321433        /** Selects an axis aligned for the next split. 
     
    14941495        inline bool GlobalTerminationCriteriaMet(const OspTraversalData &data) const; 
    14951496 
    1496         float SelectSplitPlane(const VspTraversalData &tData, 
    1497                                                                 AxisAlignedPlane &plane, 
    1498                                                                 float &pFront, 
    1499                                                                 float &pBack); 
     1497        float SelectSplitPlane(const OspTraversalData &tData, 
     1498                AxisAlignedPlane &plane, 
     1499                float &pFront, 
     1500                float &pBack); 
    15001501        /** Adds ray sample contributions to the PVS. 
    15011502                @param sampleContributions the number contributions of the samples 
     
    15431544 
    15441545        int PrepareHeuristics(Intersectable *object); 
     1546 
     1547        void PrepareConstruction(const ObjectContainer &objects, 
     1548                AxisAlignedBox3 *forcedBoundingBox); 
     1549 
    15451550 
    15461551protected: 
Note: See TracChangeset for help on using the changeset viewer.