Changeset 13041 for OpenSceneGraph/trunk/src/osgUtil/CullVisitor.cpp
- Timestamp:
- 03/21/12 18:36:20 (14 months ago)
- Files:
-
- 1 modified
-
OpenSceneGraph/trunk/src/osgUtil/CullVisitor.cpp (modified) (76 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/src/osgUtil/CullVisitor.cpp
r12833 r13041 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 1 /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield 2 2 * 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 3 * This library is open source and may be redistributed and/or modified under 4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or 5 5 * (at your option) any later version. The full license is in LICENSE file 6 6 * included with this distribution, and on the openscenegraph.org website. 7 * 7 * 8 8 * This library is distributed in the hope that it will be useful, 9 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 11 * OpenSceneGraph Public License for more details. 12 12 */ … … 85 85 CullVisitor* CullVisitor::create() 86 86 { 87 return CullVisitor::prototype().valid() ? 87 return CullVisitor::prototype().valid() ? 88 88 CullVisitor::prototype()->clone() : 89 new CullVisitor; 89 new CullVisitor; 90 90 } 91 91 … … 96 96 // first unref all referenced objects and then empty the containers. 97 97 // 98 98 99 99 CullStack::reset(); 100 100 101 101 _renderBinStack.clear(); 102 102 … … 109 109 _computed_znear = FLT_MAX; 110 110 _computed_zfar = -FLT_MAX; 111 112 111 112 113 113 osg::Vec3 lookVector(0.0,0.0,-1.0); 114 114 115 115 _bbCornerFar = (lookVector.x()>=0?1:0) | 116 116 (lookVector.y()>=0?2:0) | … … 118 118 119 119 _bbCornerNear = (~_bbCornerFar)&7; 120 120 121 121 // Only reset the RenderLeaf objects used last frame. 122 122 for(RenderLeafList::iterator itr=_reuseRenderLeafList.begin(), … … 127 127 (*itr)->reset(); 128 128 } 129 129 130 130 // reset the resuse lists. 131 131 _currentReuseRenderLeafIndex = 0; … … 156 156 const Matrix& matrix = *_modelviewStack.back(); 157 157 float dist = distance(pos,matrix); 158 158 159 159 if (withLODScale) return dist*getLODScale(); 160 160 else return dist; … … 168 168 #if 0 169 169 osg::Timer_t start_t = osg::Timer::instance()->tick(); 170 #endif 170 #endif 171 171 // update near from defferred list of drawables 172 172 unsigned int numTests = 0; … … 183 183 #if 0 184 184 OSG_NOTICE<<" updating znear to "<<d_near<<std::endl; 185 #endif 186 } 187 } 185 #endif 186 } 187 } 188 188 189 189 #if 0 … … 222 222 #if 0 223 223 OSG_NOTICE<<" result _computed_znear="<<_computed_znear<<", _computed_zfar="<<_computed_zfar<<std::endl; 224 #endif 224 #endif 225 225 } 226 226 … … 238 238 // so it doesn't cull them out. 239 239 osg::Matrix& projection = *_projectionStack.back(); 240 240 241 241 value_type tmp_znear = _computed_znear; 242 242 value_type tmp_zfar = _computed_zfar; 243 243 244 244 clampProjectionMatrix(projection, tmp_znear, tmp_zfar); 245 245 } … … 264 264 return false; 265 265 } 266 266 267 267 if (zfar<znear+epsilon) 268 268 { … … 304 304 value_type znearPullRatio = 0.98; 305 305 306 //znearPullRatio = 0.99; 306 //znearPullRatio = 0.99; 307 307 308 308 value_type desired_znear = znear * znearPullRatio; … … 362 362 363 363 Comparator _comparator; 364 364 365 365 CullVisitor::value_type _znear; 366 366 osg::Matrix _matrix; … … 368 368 Polygon _polygonOriginal; 369 369 Polygon _polygonNew; 370 370 371 371 Polygon _pointCache; 372 372 … … 404 404 } 405 405 //OSG_NOTICE<<"Point ok w.r.t plane "<<d1<<std::endl; 406 } 407 406 } 407 408 408 _znear = n1; 409 409 //OSG_NOTICE<<"Near plane updated "<<_znear<<std::endl; … … 455 455 active_mask = active_mask | selector_mask; 456 456 } 457 457 458 458 //OSG_NOTICE<<"Line ok w.r.t plane "<<d1<<"\t"<<d2<<std::endl; 459 459 460 selector_mask <<= 1; 461 } 462 460 selector_mask <<= 1; 461 } 462 463 463 if (active_mask==0) 464 464 { … … 468 468 return; 469 469 } 470 470 471 471 //OSG_NOTICE<<"Using brute force method of line cutting frustum walls"<<std::endl; 472 472 DistancePoint p1(0, v1); 473 473 DistancePoint p2(0, v2); 474 474 475 475 selector_mask = 0x1; 476 476 … … 480 480 { 481 481 if (active_mask & selector_mask) 482 { 482 { 483 483 // clip line to plane 484 484 const osg::Plane& plane = *pitr; … … 497 497 float r = p1.first/(p1.first-p2.first); 498 498 p2 = DistancePoint(0.0f, p1.second*(1.0f-r) + p2.second*r); 499 499 500 500 } 501 501 } … … 509 509 // The case where both are out was handled above. 510 510 } 511 selector_mask <<= 1; 511 selector_mask <<= 1; 512 512 } 513 513 … … 533 533 return; 534 534 } 535 536 535 536 537 537 if (n1 < 0.0 && 538 538 n2 < 0.0 && … … 568 568 active_mask = active_mask | selector_mask; 569 569 } 570 570 571 571 //OSG_NOTICE<<"Triangle ok w.r.t plane "<<d1<<"\t"<<d2<<"\t"<<d3<<std::endl; 572 572 573 selector_mask <<= 1; 574 } 575 573 selector_mask <<= 1; 574 } 575 576 576 if (active_mask==0) 577 577 { … … 582 582 return; 583 583 } 584 584 585 585 //return; 586 586 587 587 // numPartiallyInside>0) so we have a triangle cutting an frustum wall, 588 // this means that use brute force methods for dividing up triangle. 589 588 // this means that use brute force methods for dividing up triangle. 589 590 590 //OSG_NOTICE<<"Using brute force method of triangle cutting frustum walls"<<std::endl; 591 591 _polygonOriginal.clear(); … … 593 593 _polygonOriginal.push_back(DistancePoint(0,v2)); 594 594 _polygonOriginal.push_back(DistancePoint(0,v3)); 595 595 596 596 selector_mask = 0x1; 597 597 598 598 for(pitr = _planes->begin(); 599 599 pitr != _planes->end() && !_polygonOriginal.empty(); … … 601 601 { 602 602 if (active_mask & selector_mask) 603 { 603 { 604 604 // polygon bisects plane so need to divide it up. 605 605 const osg::Plane& plane = *pitr; … … 613 613 polyItr->first = plane.distance(polyItr->second); 614 614 } 615 616 // create the new polygon by clamping against the 615 616 // create the new polygon by clamping against the 617 617 unsigned int psize = _polygonOriginal.size(); 618 618 … … 624 624 { 625 625 _polygonNew.push_back(_polygonOriginal[ci]); 626 626 627 627 if (_polygonOriginal[ni].first<0.0f) computeIntersection = true; 628 628 } … … 639 639 _polygonOriginal.swap(_polygonNew); 640 640 } 641 selector_mask <<= 1; 641 selector_mask <<= 1; 642 642 } 643 643 … … 690 690 osg::TemplatePrimitiveFunctor<ComputeNearestPointFunctor> cnpf; 691 691 cnpf.set(FLT_MAX, matrix, &planes); 692 692 693 693 drawable.accept(cnpf); 694 694 … … 718 718 { 719 719 std::swap(d_near,d_far); 720 if ( !EQUAL_F(d_near, d_far) ) 720 if ( !EQUAL_F(d_near, d_far) ) 721 721 { 722 722 OSG_WARN<<"Warning: CullVisitor::updateCalculatedNearFar(.) near>far in range calculation,"<< std::endl; … … 745 745 if (isBillboard) 746 746 { 747 748 #ifdef TIME_BILLBOARD_NEAR_FAR_CALCULATION 747 748 #ifdef TIME_BILLBOARD_NEAR_FAR_CALCULATION 749 749 static unsigned int lastFrameNumber = getTraversalNumber(); 750 750 static unsigned int numBillboards = 0; … … 759 759 osg::Timer_t start_t = osg::Timer::instance()->tick(); 760 760 #endif 761 761 762 762 osg::Vec3 lookVector(-matrix(0,2),-matrix(1,2),-matrix(2,2)); 763 763 … … 802 802 } 803 803 804 #ifdef TIME_BILLBOARD_NEAR_FAR_CALCULATION 804 #ifdef TIME_BILLBOARD_NEAR_FAR_CALCULATION 805 805 osg::Timer_t end_t = osg::Timer::instance()->tick(); 806 806 807 807 elapsed_time += osg::Timer::instance()->delta_m(start_t,end_t); 808 808 ++numBillboards; … … 816 816 d_far = distance(bb.corner(_bbCornerFar),matrix); 817 817 } 818 818 819 819 if (d_near>d_far) 820 820 { 821 821 std::swap(d_near,d_far); 822 if ( !EQUAL_F(d_near, d_far) ) 822 if ( !EQUAL_F(d_near, d_far) ) 823 823 { 824 824 OSG_WARN<<"Warning: CullVisitor::updateCalculatedNearFar(.) near>far in range calculation,"<< std::endl; … … 865 865 } 866 866 } 867 867 868 868 // use the far point if its nearer than current znear as this is a conservative estimate of the znear 869 869 // while the final computation for this drawable is deferred. … … 929 929 } 930 930 931 if (d<_computed_znear) 931 if (d<_computed_znear) 932 932 { 933 933 _computed_znear = d; … … 935 935 } 936 936 if (d>_computed_zfar) _computed_zfar = d; 937 } 937 } 938 938 939 939 void CullVisitor::apply(Node& node) … … 943 943 // push the culling mode. 944 944 pushCurrentMask(); 945 945 946 946 // push the node's state. 947 947 StateSet* node_state = node.getStateSet(); … … 950 950 handle_cull_callbacks_and_traverse(node); 951 951 952 // pop the node's state off the geostate stack. 952 // pop the node's state off the geostate stack. 953 953 if (node_state) popStateSet(); 954 954 955 955 // pop the culling mode. 956 956 popCurrentMask(); … … 980 980 continue; 981 981 } 982 982 983 983 //else 984 984 { … … 987 987 988 988 989 if (_computeNearFar && bb.valid()) 989 if (_computeNearFar && bb.valid()) 990 990 { 991 991 if (!updateCalculatedNearFar(matrix,*drawable,false)) continue; … … 995 995 unsigned int numPopStateSetRequired = 0; 996 996 997 // push the geoset's state on the geostate stack. 997 // push the geoset's state on the geostate stack. 998 998 StateSet* stateset = drawable->getStateSet(); 999 999 if (stateset) … … 1020 1020 1021 1021 float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f; 1022 1022 1023 1023 if (osg::isNaN(depth)) 1024 1024 { … … 1033 1033 } 1034 1034 else 1035 { 1035 { 1036 1036 addDrawableAndDepth(drawable,&matrix,depth); 1037 1037 } … … 1044 1044 } 1045 1045 1046 // pop the node's state off the geostate stack. 1046 // pop the node's state off the geostate stack. 1047 1047 if (node_state) popStateSet(); 1048 1048 … … 1098 1098 StateSet* stateset = drawable->getStateSet(); 1099 1099 if (stateset) pushStateSet(stateset); 1100 1100 1101 1101 if (osg::isNaN(depth)) 1102 1102 { … … 1111 1111 } 1112 1112 else 1113 { 1113 { 1114 1114 addDrawableAndDepth(drawable,billboard_matrix,depth); 1115 1115 } … … 1119 1119 } 1120 1120 1121 // pop the node's state off the geostate stack. 1121 // pop the node's state off the geostate stack. 1122 1122 if (node_state) popStateSet(); 1123 1123 … … 1148 1148 handle_cull_callbacks_and_traverse(node); 1149 1149 1150 // pop the node's state off the geostate stack. 1150 // pop the node's state off the geostate stack. 1151 1151 if (node_state) popStateSet(); 1152 1152 } … … 1177 1177 handle_cull_callbacks_and_traverse(node); 1178 1178 1179 // pop the node's state off the geostate stack. 1179 // pop the node's state off the geostate stack. 1180 1180 if (node_state) popStateSet(); 1181 1181 } … … 1197 1197 addPositionedTextureAttribute(node.getTextureUnit(), 0 ,node.getTexGen()); 1198 1198 } 1199 1199 1200 1200 handle_cull_callbacks_and_traverse(node); 1201 1201 1202 // pop the node's state off the geostate stack. 1202 // pop the node's state off the geostate stack. 1203 1203 if (node_state) popStateSet(); 1204 1204 } … … 1217 1217 handle_cull_callbacks_and_traverse(node); 1218 1218 1219 // pop the node's state off the render graph stack. 1219 // pop the node's state off the render graph stack. 1220 1220 if (node_state) popStateSet(); 1221 1221 … … 1238 1238 node.computeLocalToWorldMatrix(*matrix,this); 1239 1239 pushModelViewMatrix(matrix.get(), node.getReferenceFrame()); 1240 1240 1241 1241 handle_cull_callbacks_and_traverse(node); 1242 1242 1243 1243 popModelViewMatrix(); 1244 1244 1245 // pop the node's state off the render graph stack. 1245 // pop the node's state off the render graph stack. 1246 1246 if (node_state) popStateSet(); 1247 1247 … … 1264 1264 float previous_znear = _computed_znear; 1265 1265 float previous_zfar = _computed_zfar; 1266 1266 1267 1267 // take a copy of the current near plane candidates 1268 1268 DistanceMatrixDrawableMap previousNearPlaneCandidateMap; … … 1278 1278 ref_ptr<RefMatrix> matrix = createOrReuseMatrix(node.getMatrix()); 1279 1279 pushProjectionMatrix(matrix.get()); 1280 1280 1281 1281 //OSG_INFO<<"Push projection "<<*matrix<<std::endl; 1282 1282 1283 1283 // note do culling check after the frustum has been updated to ensure 1284 1284 // that the node is not culled prematurely. … … 1299 1299 previousFarPlaneCandidateMap.swap(_farPlaneCandidateMap); 1300 1300 1301 // pop the node's state off the render graph stack. 1301 // pop the node's state off the render graph stack. 1302 1302 if (node_state) popStateSet(); 1303 1303 … … 1325 1325 handle_cull_callbacks_and_traverse(node); 1326 1326 1327 // pop the node's state off the render graph stack. 1327 // pop the node's state off the render graph stack. 1328 1328 if (node_state) popStateSet(); 1329 1329 … … 1353 1353 handle_cull_callbacks_and_traverse(node); 1354 1354 1355 // pop the node's state off the render graph stack. 1355 // pop the node's state off the render graph stack. 1356 1356 if (node_state) popStateSet(); 1357 1357 … … 1364 1364 { 1365 1365 public: 1366 1366 1367 1367 RenderStageCache() {} 1368 1368 RenderStageCache(const RenderStageCache&, const osg::CopyOp&) {} 1369 1369 1370 1370 META_Object(osgUtil, RenderStageCache); 1371 1371 1372 1372 void setRenderStage(CullVisitor* cv, RenderStage* rs) 1373 1373 { 1374 1374 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); 1375 1375 _renderStageMap[cv] = rs; 1376 } 1376 } 1377 1377 1378 1378 RenderStage* getRenderStage(osgUtil::CullVisitor* cv) … … 1381 1381 return _renderStageMap[cv].get(); 1382 1382 } 1383 1383 1384 1384 typedef std::map<CullVisitor*, osg::ref_ptr<RenderStage> > RenderStageMap; 1385 1385 1386 1386 /** Resize any per context GLObject buffers to specified size. */ 1387 1387 virtual void resizeGLObjectBuffers(unsigned int maxSize) … … 1479 1479 modelview = createOrReuseMatrix(*getModelViewMatrix()*camera.getViewMatrix()); 1480 1480 } 1481 else // pre multiply 1481 else // pre multiply 1482 1482 { 1483 1483 projection = createOrReuseMatrix(camera.getProjectionMatrix()*(*getProjectionMatrix())); … … 1498 1498 value_type previous_znear = _computed_znear; 1499 1499 value_type previous_zfar = _computed_zfar; 1500 1500 1501 1501 // take a copy of the current near plane candidates 1502 1502 DistanceMatrixDrawableMap previousNearPlaneCandidateMap; … … 1510 1510 1511 1511 pushProjectionMatrix(projection); 1512 pushModelViewMatrix(modelview, camera.getReferenceFrame()); 1512 pushModelViewMatrix(modelview, camera.getReferenceFrame()); 1513 1513 1514 1514 … … 1534 1534 camera.setRenderingCache(rsCache.get()); 1535 1535 } 1536 1536 1537 1537 osg::ref_ptr<osgUtil::RenderStage> rtts = rsCache->getRenderStage(this); 1538 1538 if (!rtts) 1539 1539 { 1540 1540 OpenThreads::ScopedLock<OpenThreads::Mutex> lock(*(camera.getDataChangeMutex())); 1541 1541 1542 1542 rtts = new osgUtil::RenderStage; 1543 1543 rsCache->setRenderStage(this,rtts.get()); … … 1554 1554 rtts->setDrawBuffer(camera.getDrawBuffer()); 1555 1555 } 1556 1556 1557 1557 if ( camera.getInheritanceMask() & READ_BUFFER ) 1558 1558 { … … 1571 1571 } 1572 1572 1573 // set up clera masks/values 1573 // set up clera masks/values 1574 1574 rtts->setClearDepth(camera.getClearDepth()); 1575 1575 rtts->setClearAccum(camera.getClearAccum()); … … 1596 1596 } 1597 1597 1598 1598 1599 1599 // set the color mask. 1600 1600 osg::ColorMask* colorMask = camera.getColorMask()!=0 ? camera.getColorMask() : previous_stage->getColorMask(); … … 1604 1604 osg::Viewport* viewport = camera.getViewport()!=0 ? camera.getViewport() : previous_stage->getViewport(); 1605 1605 rtts->setViewport( viewport ); 1606 1606 1607 1607 // set initial view matrix 1608 1608 rtts->setInitialViewMatrix(modelview); … … 1629 1629 // restore the previous renderbin. 1630 1630 setCurrentRenderBin(previousRenderBin); 1631 1631 1632 1632 1633 1633 if (rtts->getStateGraphList().size()==0 && rtts->getRenderBinList().size()==0) … … 1651 1651 1652 1652 } 1653 1653 1654 1654 // restore the previous model view matrix. 1655 1655 popModelViewMatrix(); … … 1676 1676 setCullSettings(saved_cull_settings); 1677 1677 1678 // pop the node's state off the render graph stack. 1678 // pop the node's state off the render graph stack. 1679 1679 if (node_state) popStateSet(); 1680 1680 … … 1686 1686 // list, if so disable the appropriate ShadowOccluderVolume 1687 1687 disableAndPushOccludersCurrentMask(_nodePath); 1688 1688 1689 1689 1690 1690 if (isCulled(node)) … … 1705 1705 handle_cull_callbacks_and_traverse(node); 1706 1706 1707 // pop the node's state off the render graph stack. 1707 // pop the node's state off the render graph stack. 1708 1708 if (node_state) popStateSet(); 1709 1709 … … 1728 1728 1729 1729 osg::Camera* camera = getCurrentCamera(); 1730 1730 1731 1731 // If previous query indicates visible, then traverse as usual. 1732 1732 if (node.getPassed( camera, *this )) … … 1740 1740 1741 1741 1742 // pop the node's state off the render graph stack. 1742 // pop the node's state off the render graph stack. 1743 1743 if (node_state) popStateSet(); 1744 1744
