Changeset 2237 for GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
- Timestamp:
- 03/12/07 18:30:52 (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
r2233 r2237 32 32 #define VISUALIZE_SPLIT 0 33 33 #define USE_FIXEDPOINT_T 0 34 #define HACK_PERFORMANCE 1 35 34 36 35 37 ///////////// … … 513 515 ////////////////////////////////////////////// 514 516 // bounding box of view space includes all visibility events 517 515 518 mBoundingBox.Initialize(); 516 519 VssRayContainer::const_iterator rit, rit_end = rays.end(); … … 802 805 VspLeaf *leaf = static_cast<VspLeaf *>(splitCandidate.mParentData.mNode); 803 806 807 ////////////// 808 //-- compute global decrease in render cost 809 810 const AxisAlignedPlane candidatePlane = splitCandidate.mSplitPlane; 811 812 RayInfoContainer::const_iterator rit, rit_end = splitCandidate.mParentData.mRays->end(); 813 814 float frontRenderCost = 0, backRenderCost = 0, totalRenderCost = 0; 815 int frontSize = 0, backSize = 0, totalSize = 0; 816 817 Intersectable::NewMail(3); 818 KdLeaf::NewMail(3); 819 820 for (rit = splitCandidate.mParentData.mRays->begin(); rit != rit_end; ++ rit) 821 { 822 RayInfo rayInf = *rit; 823 824 float t; 825 826 // classify ray 827 const int cf = rayInf.ComputeRayIntersection(candidatePlane.mAxis, 828 candidatePlane.mPosition, 829 t); 830 831 VssRay *ray = rayInf.mRay; 832 #if HACK_PERFORMANCE 833 Intersectable *obj = (*ray).mTerminationObject; 834 835 BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj); 836 837 // evaluate contribution of ray endpoint to front 838 // and back pvs with respect to the classification 839 UpdateContributionsToPvs(leaf, cf, 840 frontRenderCost, backRenderCost, totalRenderCost), 841 frontSize, backSize, totalSize; 842 843 #if COUNT_ORIGIN_OBJECTS 844 845 obj = (*ray).mOriginObject; 846 847 if (obj) 848 { 849 leaf = mBvHierarchy->GetLeaf(obj); 850 851 UpdateContributionsToPvs(leaf, cf, 852 frontRenderCost, backRenderCost, totalRenderCost, 853 frontSize, backSize, totalSize); 854 } 855 #endif 856 857 #else 858 cerr << "TODO classify" << endl; 859 #endif 860 } 861 804 862 ///////////// 805 863 // avg ray contri 806 864 807 const int pvs = EvalPvsEntriesSize(*splitCandidate.mParentData.mRays); 808 809 const float avgRayContri = (float)pvs / 865 const float avgRayContri = (float)totalSize / 810 866 ((float)splitCandidate.mParentData.mRays->size() + Limits::Small); 811 867 … … 813 869 814 870 const float avgRaysPerObject = 815 (float)splitCandidate.mParentData.mRays->size() / ((float) pvs+ Limits::Small);871 (float)splitCandidate.mParentData.mRays->size() / ((float)totalSize + Limits::Small); 816 872 817 873 splitCandidate.SetAvgRayContribution(avgRayContri); 818 874 splitCandidate.SetAvgRaysPerObject(avgRaysPerObject); 819 875 820 // compute global decrease in render cost 876 821 877 float oldRenderCost; 822 const float renderCostDecr = EvalRenderCostDecrease(splitCandidate, oldRenderCost); 878 const float renderCostDecr = EvalRenderCostDecrease(splitCandidate, oldRenderCost, 879 totalRenderCost, frontRenderCost, backRenderCost); 823 880 splitCandidate.SetRenderCostDecrease(renderCostDecr); 824 881 825 882 // the increase in pvs entries num induced by this split 826 const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate );883 const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate, totalSize, frontSize, backSize); 827 884 splitCandidate.SetPvsEntriesIncr(pvsEntriesIncr); 828 885 … … 844 901 845 902 846 int VspTree::EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate) const 847 { 848 float oldPvsSize = 0; 849 float fPvsSize = 0; 850 float bPvsSize = 0; 851 852 const AxisAlignedPlane candidatePlane = splitCandidate.mSplitPlane; 853 854 Intersectable::NewMail(3); 855 KdLeaf::NewMail(3); 856 903 int VspTree::EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate, 904 const float oldPvsSize, 905 const float fPvsSize, 906 const float bPvsSize) const 907 { 908 857 909 RayInfoContainer::const_iterator rit, rit_end = splitCandidate.mParentData.mRays->end(); 858 859 // this is the main ray classification loop!860 for(rit = splitCandidate.mParentData.mRays->begin(); rit != rit_end; ++ rit)861 {862 VssRay *ray = (*rit).mRay;863 RayInfo rayInf = *rit;864 865 float t;866 // classify ray867 const int cf = rayInf.ComputeRayIntersection(candidatePlane.mAxis,868 candidatePlane.mPosition, t);869 870 UpdatePvsEntriesContribution(*ray, true, cf, fPvsSize, bPvsSize, oldPvsSize);871 #if COUNT_ORIGIN_OBJECTS872 UpdatePvsEntriesContribution(*ray, false, cf, fPvsSize, bPvsSize, oldPvsSize);873 #endif874 }875 910 876 911 const float oldPvsRatio = (splitCandidate.mParentData.mPvs > 0) ? … … 1188 1223 1189 1224 1190 int VspTree::EvalMaxEventContribution(KdLeaf *leaf) const1191 { 1192 int pvs = 0;1225 float VspTree::EvalMaxEventContribution(KdLeaf *leaf) const 1226 { 1227 float pvs = 0; 1193 1228 1194 1229 // leaf falls out of right pvs 1195 1230 if (-- leaf->mCounter == 0) 1196 1231 { 1197 pvs -= (( int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());1232 pvs -= ((float)leaf->mObjects.size() - (float)leaf->mMultipleObjects.size()); 1198 1233 } 1199 1234 … … 1217 1252 1218 1253 1219 int VspTree::EvalMinEventContribution(KdLeaf *leaf) const1254 float VspTree::EvalMinEventContribution(KdLeaf *leaf) const 1220 1255 { 1221 1256 if (leaf->Mailed()) … … 1225 1260 1226 1261 // add objects without those which are part of several kd leaves 1227 int pvs = ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());1262 float pvs = ((float)leaf->mObjects.size() - (float)leaf->mMultipleObjects.size()); 1228 1263 1229 1264 // separately handle objects which are part of several kd leaves … … 1644 1679 1645 1680 float VspTree::EvalRenderCostDecrease(VspSubdivisionCandidate &sc, 1646 float &normalizedOldRenderCost) const 1647 { 1648 float pvsFront = 0; 1649 float pvsBack = 0; 1650 float totalPvs = 0; 1651 1681 float &normalizedOldRenderCost, 1682 const float totalPvs, 1683 const float pvsFront, 1684 const float pvsBack) const 1685 { 1652 1686 const float viewSpaceVol = mBoundingBox.GetVolume(); 1653 1687 const VspTraversalData &tData = sc.mParentData; … … 1663 1697 Intersectable::NewMail(3); 1664 1698 KdLeaf::NewMail(3); 1665 1666 RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();1667 1668 for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)1669 {1670 RayInfo rayInf = *rit;1671 1672 float t;1673 1674 // classify ray1675 const int cf = rayInf.ComputeRayIntersection(candidatePlane.mAxis,1676 candidatePlane.mPosition,1677 t);1678 1679 VssRay *ray = rayInf.mRay;1680 1681 // evaluate contribution of ray endpoint to front1682 // and back pvs with respect to the classification1683 UpdateContributionsToPvs(*ray, true, cf, pvsFront, pvsBack, totalPvs);1684 1685 #if COUNT_ORIGIN_OBJECTS1686 UpdateContributionsToPvs(*ray, false, cf, pvsFront, pvsBack, totalPvs);1687 #endif1688 }1689 1699 1690 1700 AxisAlignedBox3 frontBox; … … 1802 1812 if (!obj) return; 1803 1813 1804 const float renderCost = mViewCellsManager->EvalRenderCost(obj);1814 const float renderCost = ViewCellsManager::EvalRenderCost(obj); 1805 1815 1806 1816 // object in none of the pvss => new object … … 1881 1891 backPvs += renderCost; 1882 1892 1893 // already in front pvs => in both pvss 1894 if (leaf->Mailed()) 1895 leaf->Mail(2); 1896 else 1897 leaf->Mail(1); 1898 } 1899 } 1900 } 1901 1902 1903 void VspTree::UpdateContributionsToPvs(BvhLeaf *leaf, 1904 const int cf, 1905 float &frontPvs, 1906 float &backPvs, 1907 float &totalPvs, 1908 int &frontSize, 1909 int &backSize, 1910 int &totalSize) const 1911 { 1912 const float renderCost = mBvHierarchy->EvalAbsCost(leaf->mObjects); 1913 1914 // leaf in no pvs => new 1915 if (!leaf->Mailed() && !leaf->Mailed(1) && !leaf->Mailed(2)) 1916 { 1917 totalPvs += renderCost; 1918 ++ totalSize; 1919 } 1920 1921 if (cf >= 0) // front pvs 1922 { 1923 if (!leaf->Mailed() && !leaf->Mailed(2)) 1924 { 1925 frontPvs += renderCost; 1926 ++ frontSize; 1927 1928 // already in back pvs => in both pvss 1929 if (leaf->Mailed(1)) 1930 leaf->Mail(2); 1931 else 1932 leaf->Mail(); 1933 } 1934 } 1935 1936 if (cf <= 0) // back pvs 1937 { 1938 if (!leaf->Mailed(1) && !leaf->Mailed(2)) 1939 { 1940 backPvs += renderCost; 1941 ++ backSize; 1942 1883 1943 // already in front pvs => in both pvss 1884 1944 if (leaf->Mailed()) … … 2379 2439 2380 2440 { 2381 2441 2382 2442 #if HACK_PERFORMANCE 2383 2384 BvhLeaf *bvhleaf = mBvHierarchy->GetLeaf(mTerminationObject); 2443 Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 2444 2445 if (!obj) return 0; 2446 BvhLeaf *bvhleaf = mBvHierarchy->GetLeaf(obj); 2385 2447 2386 2448 if (!bvhleaf->Mailed()) … … 2389 2451 return 1; 2390 2452 } 2453 2391 2454 #else 2455 2392 2456 Intersectable *obj; 2393 Vector3 pt;2457 static Vector3 pt; 2394 2458 KdNode *node; 2395 2459 2396 2460 ray.GetSampleData(isTermination, pt, &obj, &node); 2397 2461 2398 2462 if (!obj) return 0; 2399 2463 … … 2961 3025 Intersectable::NewMail(); 2962 3026 3027 //////////////// 2963 3028 //-- store rays and objects 3029 3030 VssRay *lastVssRay = NULL; 3031 2964 3032 for (rit = sampleRays.begin(); rit != rit_end; ++ rit) 2965 3033 { 2966 3034 VssRay *ray = *rit; 2967 float minT, maxT; 2968 static Ray hray; 2969 2970 hray.Init(*ray); 3035 3036 // filter out double rays (last ray the same as this ray 3037 if (!lastVssRay || 3038 !(ray->mOrigin == lastVssRay->mTermination) || 3039 !(ray->mTermination == lastVssRay->mOrigin)) 3040 { 3041 lastVssRay = ray; 3042 3043 float minT, maxT; 3044 static Ray hray; 3045 3046 hray.Init(*ray); 2971 3047 2972 // TODO: not very efficient to implictly cast between rays types 2973 if (GetBoundingBox().GetRaySegment(hray, minT, maxT)) 2974 { 2975 float len = ray->Length(); 2976 2977 if (!len) 2978 len = Limits::Small; 2979 2980 rays.push_back(RayInfo(ray, minT / len, maxT / len)); 3048 // TODO: not very efficient to implictly cast between rays types 3049 if (GetBoundingBox().GetRaySegment(hray, minT, maxT)) 3050 { 3051 const float len = ray->Length(); 3052 3053 if (len) // ray not degenerate 3054 { //len = Limits::Small; 3055 rays.push_back(RayInfo(ray, minT / len, maxT / len)); 3056 } 3057 } 3058 } 3059 else 3060 { 3061 // store object only for one ray 3062 lastVssRay->mOriginObject = ray->mTerminationObject; 2981 3063 } 2982 3064 } … … 3086 3168 #if HACK_PERFORMANCE 3087 3169 3170 Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 3171 3172 if (!obj) return; 3173 3174 BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj); 3175 3088 3176 SubdivisionCandidate *candidate; 3089 3090 BvhLeaf *leaf = mBvHierarchy->GetLeaf(ray.mTerminationObject);3091 3177 3092 3178 if (!leaf->Mailed()) … … 3164 3250 RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end(); 3165 3251 3166 // add all kdnodes seen by the rays3252 // add all nodes seen by the rays 3167 3253 for (rit = tData.mRays->begin(); rit != rit_end; ++ rit) 3168 3254 { … … 3170 3256 3171 3257 CollectDirtyCandidate(*ray, true, dirtyList, onlyUnmailed); 3258 3259 #if COUNT_ORIGIN_OBJECTS 3172 3260 CollectDirtyCandidate(*ray, false, dirtyList, onlyUnmailed); 3173 } 3174 } 3175 3176 3177 int VspTree::EvalMaxEventContribution(const VssRay &ray, 3261 #endif 3262 } 3263 } 3264 3265 3266 float VspTree::EvalMaxEventContribution(const VssRay &ray, 3178 3267 const bool isTermination) const 3179 3268 { 3180 int pvs = 0;3181 3182 3269 #if HACK_PERFORMANCE 3183 3270 3184 BvhLeaf *leaf = mBvHierarchy->GetLeaf(ray.mTerminationObject); 3271 Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 3272 3273 if (!obj) return 0.0f; 3274 3275 BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj); 3185 3276 3186 3277 // simple render cost evaluation 3187 3278 if (-- leaf->mCounter == 0) 3188 //pvs += (int)leaf->mObjects.size();3189 pvs += mBvHierarchy::EvalAbsCost((int)leaf->mObjects.size());3190 3279 return BvHierarchy::EvalAbsCost(leaf->mObjects); 3280 else 3281 return 0.0f; 3191 3282 #else 3192 3283 … … 3197 3288 ray.GetSampleData(isTermination, pt, &obj, &node); 3198 3289 3199 if (!obj) return 0; 3290 if (!obj) return 0.0f; 3291 3292 float pvs = 0.0f; 3200 3293 3201 3294 switch (mHierarchyManager->GetObjectSpaceSubdivisionType()) … … 3221 3314 // simple render cost evaluation 3222 3315 if (-- leaf->mCounter == 0) 3223 pvs += (int)leaf->mObjects.size();3224 //pvs += (int)BvHierarchy::EvalAbsCost(leaf->mObjects);3316 //pvs += (int)leaf->mObjects.size(); 3317 pvs += BvHierarchy::EvalAbsCost(leaf->mObjects); 3225 3318 break; 3226 3319 } … … 3228 3321 break; 3229 3322 } 3323 return pvs; 3324 3230 3325 #endif 3231 return pvs;3232 3326 } 3233 3327 … … 3235 3329 float VspTree::PrepareHeuristics(const VssRay &ray, const bool isTermination) 3236 3330 { 3331 3332 #if HACK_PERFORMANCE 3333 3334 Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 3335 3336 if (!obj) return 0.0f; 3337 3338 BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj); 3339 3340 if (!leaf->Mailed()) 3341 { 3342 leaf->Mail(); 3343 leaf->mCounter = 1; 3344 return BvHierarchy::EvalAbsCost(leaf->mObjects); 3345 } 3346 else 3347 { 3348 ++ leaf->mCounter; 3349 return 0.0f; 3350 } 3351 3352 #else 3353 3237 3354 float pvsSize = 0; 3238 3239 #if HACK_PERFORMANCE 3240 BvhLeaf *leaf = mBvHierarchy->GetLeaf(ray.mTerminationObject); 3241 3242 if (!leaf->Mailed()) 3243 { 3244 leaf->Mail(); 3245 leaf->mCounter = 0; 3246 pvsSize += (int)leaf->mObjects.size(); 3247 } 3248 3249 ++ leaf->mCounter; 3250 3251 #else 3252 3355 3253 3356 Intersectable *obj; 3254 3357 Vector3 pt; … … 3257 3360 ray.GetSampleData(isTermination, pt, &obj, &node); 3258 3361 3259 if (!obj) return 0 ;3362 if (!obj) return 0.0f; 3260 3363 3261 3364 switch (mHierarchyManager->GetObjectSpaceSubdivisionType()) … … 3287 3390 leaf->Mail(); 3288 3391 leaf->mCounter = 0; 3289 pvsSize += (int)leaf->mObjects.size();3392 pvsSize += BvHierarchy::EvalAbsCost(leaf->mObjects); 3290 3393 } 3291 3394 … … 3296 3399 break; 3297 3400 } 3401 return pvsSize; 3298 3402 #endif 3299 return pvsSize;3300 } 3301 3302 3303 int VspTree::EvalMinEventContribution(const VssRay &ray,3304 3403 3404 } 3405 3406 3407 float VspTree::EvalMinEventContribution(const VssRay &ray, 3408 const bool isTermination) const 3305 3409 { 3306 3410 #if HACK_PERFORMANCE 3307 3411 3308 BvhLeaf *leaf = mBvHierarchy->GetLeaf(ray.mTerminationObject); 3412 Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 3413 3414 if (!obj) return 0.0f; 3415 3416 BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj); 3309 3417 3310 3418 if (!leaf->Mailed()) 3311 3419 { 3312 3420 leaf->Mail(); 3313 pvs += (int)leaf->mObjects.size(); 3314 } 3315 3421 return BvHierarchy::EvalAbsCost(leaf->mObjects); 3422 } 3423 else 3424 { 3425 return 0.0f; 3426 } 3316 3427 #else 3317 3428 3318 3429 Intersectable *obj; 3319 Vector3 pt;3430 static Vector3 pt; 3320 3431 KdNode *node; 3321 3432 … … 3324 3435 if (!obj) return 0; 3325 3436 3326 int pvs = 0;3437 float pvs = 0.0f; 3327 3438 3328 3439 switch (mHierarchyManager->GetObjectSpaceSubdivisionType()) … … 3350 3461 { 3351 3462 leaf->Mail(); 3352 pvs += (int)leaf->mObjects.size();3463 pvs += BvHierarchy->EvalAbsCost(leaf->mObjects); 3353 3464 } 3354 3465 break; … … 3357 3468 break; 3358 3469 } 3470 return pvs; 3471 3359 3472 #endif 3360 return pvs;3361 3473 } 3362 3474 … … 3377 3489 3378 3490 Intersectable *obj; 3379 Vector3 pt;3491 static Vector3 pt; 3380 3492 KdNode *node; 3381 3493 … … 3421 3533 UpdateContributionsToPvs(leaf, cf, pvsFront, pvsBack, totalPvs, true); 3422 3534 3423 3424 3535 #else 3425 3536 3426 3537 Intersectable *obj; 3427 Vector3 pt;3538 static Vector3 pt; 3428 3539 KdNode *node; 3429 3540 … … 3443 3554 } 3444 3555 default: 3445 UpdateContributionsToPvs(obj, cf, pvsFront, pvsBack, totalPvs); 3446 break; 3556 { 3557 UpdateContributionsToPvs(obj, cf, pvsFront, pvsBack, totalPvs); 3558 break; 3559 } 3447 3560 } 3448 3561 #endif … … 3450 3563 3451 3564 3452 int VspTree::EvalContributionToPvs(const VssRay &ray, const bool isTermination) const3565 float VspTree::EvalContributionToPvs(const VssRay &ray, const bool isTermination) const 3453 3566 { 3454 3567 3455 3568 #if HACK_PERFORMANCE 3456 int pvs = 0; 3457 3458 BvhLeaf *bvhleaf = mBvHierarchy->GetLeaf(ray.mTerminationObject); 3459 3460 if (!bvhleaf->Mailed()) 3461 { 3462 bvhleaf->Mail(); 3463 pvs += (int)bvhleaf->mObjects.size(); 3569 3570 Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 3571 3572 if (!obj) return 0; 3573 3574 BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj); 3575 3576 if (!leaf->Mailed()) 3577 { 3578 leaf->Mail(); 3579 return BvHierarchy::EvalAbsCost(leaf->mObjects); 3580 } 3581 else 3582 { 3583 return 0.0f; 3464 3584 } 3465 3585 3466 3586 #else 3467 3587 3468 3588 Intersectable *obj; 3469 Vector3 pt;3589 static Vector3 pt; 3470 3590 KdNode *node; 3471 3591 … … 3474 3594 if (!obj) return 0; 3475 3595 3476 int pvs = 0;3596 float pvs = 0.0f; 3477 3597 3478 3598 switch (mHierarchyManager->GetObjectSpaceSubdivisionType()) … … 3500 3620 { 3501 3621 bvhleaf->Mail(); 3502 pvs += (int)bvhleaf->mObjects.size();3622 pvs += BvHierarchy::EvalAbsCost(bvhleaf->mObjects); 3503 3623 } 3504 3624 break; … … 3507 3627 break; 3508 3628 } 3629 return pvs; 3630 3509 3631 #endif 3510 return pvs; 3511 } 3512 3513 3514 int VspTree::EvalContributionToPvs(KdLeaf *leaf) const 3632 } 3633 3634 3635 float VspTree::EvalContributionToPvs(KdLeaf *leaf) const 3515 3636 { 3516 3637 if (leaf->Mailed()) // leaf already mailed … … 3520 3641 3521 3642 // this is the pvs which is uniquely part of this kd leaf 3522 int pvs = (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());3643 float pvs = (float)(leaf->mObjects.size() - leaf->mMultipleObjects.size()); 3523 3644 3524 3645 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
Note: See TracChangeset
for help on using the changeset viewer.