Show
Ignore:
Timestamp:
03/03/11 16:52:19 (3 years ago)
Author:
robert
Message:

Moved intial cut of depth partition support into osgViewer::View via two new methods:

/** Convenience method for setting up multiple slave cameras that depth partition the specified camera.*/
bool setUpDepthPartitionForCamera(osg::Camera* cameraToPartition, DepthPartitionSettings?* dps=0);

/** Convenience method for setting up multiple slave cameras that depth partition each of the view's active cameras.*/
bool setUpDepthPartition(DepthPartitionSettings?* dsp=0);

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgshadow/osgshadow.cpp

    r12202 r12203  
    570570} 
    571571 
    572 struct DepthPartitionSettings : public osg::Referenced 
    573 { 
    574     DepthPartitionSettings() {} 
    575  
    576     enum DepthMode 
    577     { 
    578         FIXED_RANGE, 
    579         BOUNDING_VOLUME 
    580     }; 
    581  
    582     bool getDepthRange(osg::View& view, unsigned int partition, double& zNear, double& zFar) 
    583     { 
    584         switch(_mode) 
    585         { 
    586             case(FIXED_RANGE): 
    587             { 
    588                 if (partition==0) 
    589                 { 
    590                     zNear = _zNear; 
    591                     zFar = _zMid; 
    592                     return true; 
    593                 } 
    594                 else if (partition==1) 
    595                 { 
    596                     zNear = _zMid; 
    597                     zFar = _zFar; 
    598                     return true; 
    599                 } 
    600                 return false; 
    601             } 
    602             case(BOUNDING_VOLUME): 
    603             { 
    604                 osgViewer::View* view_withSceneData = dynamic_cast<osgViewer::View*>(&view); 
    605                 const osg::Node* node = view_withSceneData ? view_withSceneData->getSceneData() : 0; 
    606                 if (!node) return false; 
    607  
    608                 const osg::Camera* masterCamera = view.getCamera(); 
    609                 if (!masterCamera) return false; 
    610  
    611                 osg::BoundingSphere bs = node->getBound(); 
    612                 const osg::Matrixd& viewMatrix = masterCamera->getViewMatrix(); 
    613                 //osg::Matrixd& projectionMatrix = masterCamera->getProjectionMatrix(); 
    614  
    615                 osg::Vec3d lookVectorInWorldCoords = osg::Matrixd::transform3x3(viewMatrix,osg::Vec3d(0.0,0.0,-1.0)); 
    616                 lookVectorInWorldCoords.normalize(); 
    617  
    618                 osg::Vec3d nearPointInWorldCoords = bs.center() - lookVectorInWorldCoords*bs.radius(); 
    619                 osg::Vec3d farPointInWorldCoords = bs.center() + lookVectorInWorldCoords*bs.radius(); 
    620  
    621                 osg::Vec3d nearPointInEyeCoords = nearPointInWorldCoords * viewMatrix; 
    622                 osg::Vec3d farPointInEyeCoords = farPointInWorldCoords * viewMatrix; 
    623  
    624 #if 0 
    625                 OSG_NOTICE<<std::endl; 
    626                 OSG_NOTICE<<"viewMatrix = "<<viewMatrix<<std::endl; 
    627                 OSG_NOTICE<<"lookVectorInWorldCoords = "<<lookVectorInWorldCoords<<std::endl; 
    628                 OSG_NOTICE<<"nearPointInWorldCoords = "<<nearPointInWorldCoords<<std::endl; 
    629                 OSG_NOTICE<<"farPointInWorldCoords = "<<farPointInWorldCoords<<std::endl; 
    630                 OSG_NOTICE<<"nearPointInEyeCoords = "<<nearPointInEyeCoords<<std::endl; 
    631                 OSG_NOTICE<<"farPointInEyeCoords = "<<farPointInEyeCoords<<std::endl; 
    632 #endif 
    633                 double minZNearRatio = 0.001; 
    634  
    635  
    636                 if (masterCamera->getDisplaySettings()) 
    637                 { 
    638                     OSG_NOTICE<<"Has display settings"<<std::endl; 
    639                 } 
    640  
    641                 double scene_zNear = -nearPointInEyeCoords.z(); 
    642                 double scene_zFar = -farPointInEyeCoords.z(); 
    643                 if (scene_zNear<=0.0) scene_zNear = minZNearRatio * scene_zFar; 
    644  
    645                 double scene_zMid = sqrt(scene_zFar*scene_zNear); 
    646  
    647 #if 0 
    648                 OSG_NOTICE<<"scene_zNear = "<<scene_zNear<<std::endl; 
    649                 OSG_NOTICE<<"scene_zMid = "<<scene_zMid<<std::endl; 
    650                 OSG_NOTICE<<"scene_zFar = "<<scene_zFar<<std::endl; 
    651 #endif 
    652                 if (partition==0) 
    653                 { 
    654                     zNear = scene_zNear; 
    655                     zFar = scene_zMid; 
    656                     return true; 
    657                 } 
    658                 else if (partition==1) 
    659                 { 
    660                     zNear = scene_zMid; 
    661                     zFar = scene_zFar; 
    662                     return true; 
    663                 } 
    664  
    665                 return false; 
    666             } 
    667         } 
    668     } 
    669  
    670     DepthMode _mode; 
    671     double _zNear; 
    672     double _zMid; 
    673     double _zFar; 
    674 }; 
    675  
    676 struct MyUpdateSlaveCallback : public osg::View::Slave::UpdateSlaveCallback 
    677 { 
    678     MyUpdateSlaveCallback(DepthPartitionSettings* dps, unsigned int partition):_dps(dps), _partition(partition) {} 
    679      
    680     virtual void updateSlave(osg::View& view, osg::View::Slave& slave) 
    681     { 
    682         slave.updateSlaveImplementation(view); 
    683  
    684         if (!_dps) return; 
    685  
    686         osg::Camera* camera = slave._camera.get(); 
    687  
    688         double computed_zNear; 
    689         double computed_zFar; 
    690         if (!_dps->getDepthRange(view, _partition, computed_zNear, computed_zFar)) 
    691         { 
    692             OSG_NOTICE<<"Switching off Camera "<<camera<<std::endl; 
    693             camera->setNodeMask(0x0); 
    694             return; 
    695         } 
    696         else 
    697         { 
    698             camera->setNodeMask(0xffffff); 
    699         } 
    700  
    701         if (camera->getProjectionMatrix()(0,3)==0.0 && 
    702             camera->getProjectionMatrix()(1,3)==0.0 && 
    703             camera->getProjectionMatrix()(2,3)==0.0) 
    704         { 
    705             double left, right, bottom, top, zNear, zFar; 
    706             camera->getProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar); 
    707             camera->setProjectionMatrixAsOrtho(left, right, bottom, top, computed_zNear, computed_zFar); 
    708         } 
    709         else 
    710         { 
    711             double left, right, bottom, top, zNear, zFar; 
    712             camera->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar); 
    713  
    714             double nr = computed_zNear / zNear; 
    715             camera->setProjectionMatrixAsFrustum(left * nr, right * nr, bottom * nr, top * nr, computed_zNear, computed_zFar); 
    716         } 
    717     } 
    718  
    719     osg::ref_ptr<DepthPartitionSettings> _dps; 
    720     unsigned int _partition; 
    721 }; 
    722  
    723  
    724 bool setUpDepthPartitionForCamera(osg::View& view, osg::Camera* cameraToPartition, DepthPartitionSettings* dps) 
    725 { 
    726     osg::ref_ptr<osg::GraphicsContext> context = cameraToPartition->getGraphicsContext(); 
    727     if (!context) return false; 
    728  
    729     osg::ref_ptr<osg::Viewport> viewport = cameraToPartition->getViewport(); 
    730     if (!viewport) return false; 
    731  
    732     cameraToPartition->setGraphicsContext(0); 
    733     cameraToPartition->setViewport(0); 
    734  
    735     bool useMastersSceneData = true; 
    736     osg::Matrixd projectionOffset; 
    737     osg::Matrixd viewOffset; 
    738  
    739     if (view.getCamera()==cameraToPartition) 
    740     { 
    741         // replace main camera with depth partition cameras 
    742         OSG_NOTICE<<"Replacing main Camera"<<std::endl; 
    743     } 
    744     else 
    745     { 
    746         unsigned int i = view.findSlaveIndexForCamera(cameraToPartition); 
    747         if (i>=view.getNumSlaves()) return false; 
    748  
    749         osg::View::Slave& slave = view.getSlave(i); 
    750  
    751         useMastersSceneData = slave._useMastersSceneData; 
    752         projectionOffset = slave._projectionOffset; 
    753         viewOffset = slave._viewOffset; 
    754  
    755         OSG_NOTICE<<"Replacing slave Camera"<<i<<std::endl; 
    756         view.removeSlave(i); 
    757     } 
    758  
    759     // far camera 
    760     { 
    761         osg::ref_ptr<osg::Camera> camera = new osg::Camera; 
    762         camera->setGraphicsContext(context.get()); 
    763         camera->setViewport(viewport.get()); 
    764  
    765         camera->setDrawBuffer(cameraToPartition->getDrawBuffer()); 
    766         camera->setReadBuffer(cameraToPartition->getReadBuffer()); 
    767  
    768         camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); 
    769         camera->setCullingMode(osg::Camera::ENABLE_ALL_CULLING); 
    770  
    771         view.addSlave(camera.get()); 
    772  
    773         osg::View::Slave& slave = view.getSlave(view.getNumSlaves()-1); 
    774  
    775         slave._useMastersSceneData = useMastersSceneData; 
    776         slave._projectionOffset = projectionOffset; 
    777         slave._viewOffset = viewOffset; 
    778         slave._updateSlaveCallback =  new MyUpdateSlaveCallback(dps, 1); 
    779     } 
    780  
    781     // near camera 
    782     { 
    783         osg::ref_ptr<osg::Camera> camera = new osg::Camera; 
    784         camera->setGraphicsContext(context.get()); 
    785         camera->setViewport(viewport.get()); 
    786  
    787         camera->setDrawBuffer(cameraToPartition->getDrawBuffer()); 
    788         camera->setReadBuffer(cameraToPartition->getReadBuffer()); 
    789  
    790         camera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); 
    791         camera->setCullingMode(osg::Camera::ENABLE_ALL_CULLING); 
    792         camera->setClearMask(GL_DEPTH_BUFFER_BIT); 
    793  
    794         view.addSlave(camera.get()); 
    795  
    796         osg::View::Slave& slave = view.getSlave(view.getNumSlaves()-1); 
    797         slave._useMastersSceneData = useMastersSceneData; 
    798         slave._projectionOffset = projectionOffset; 
    799         slave._viewOffset = viewOffset; 
    800         slave._updateSlaveCallback =  new MyUpdateSlaveCallback(dps, 0); 
    801     } 
    802  
    803     return true; 
    804 } 
    805  
    806  
    807 typedef std::list< osg::ref_ptr<osg::Camera> > Cameras; 
    808  
    809 Cameras getActiveCameras(osg::View& view) 
    810 { 
    811     Cameras activeCameras; 
    812  
    813     if (view.getCamera() && view.getCamera()->getGraphicsContext()) 
    814     { 
    815         activeCameras.push_back(view.getCamera()); 
    816     } 
    817  
    818     for(unsigned int i=0; i<view.getNumSlaves(); ++i) 
    819     { 
    820         osg::View::Slave& slave = view.getSlave(i); 
    821         if (slave._camera.valid() && slave._camera->getGraphicsContext()) 
    822         { 
    823             activeCameras.push_back(slave._camera.get()); 
    824         } 
    825     } 
    826     return activeCameras; 
    827 } 
    828  
    829  
    830 bool setUpDepthPartition(osgViewer::View& view, DepthPartitionSettings* dsp) 
    831 { 
    832     OSG_NOTICE<<"setUpDepthPartition(View,..)"<<std::endl; 
    833  
    834     Cameras originalCameras = getActiveCameras(view); 
    835     if (originalCameras.empty()) 
    836     { 
    837         OSG_NOTICE<<"setUpDepthPartition(View,..) doing view.setUpViewAcrossAllScreens()"<<std::endl; 
    838         view.setUpViewAcrossAllScreens(); 
    839  
    840         originalCameras = getActiveCameras(view); 
    841         if (originalCameras.empty()) 
    842         { 
    843             OSG_NOTICE<<"setUpDepthPartition(View,..) Unable to set up windows for viewer."<<std::endl; 
    844             return false; 
    845         } 
    846     } 
    847  
    848     bool threadsWereRunning = view.getViewerBase()->areThreadsRunning(); 
    849     if (threadsWereRunning) view.getViewerBase()->stopThreading(); 
    850  
    851     for(Cameras::iterator itr = originalCameras.begin(); 
    852         itr != originalCameras.end(); 
    853         ++itr) 
    854     { 
    855         setUpDepthPartitionForCamera(view, itr->get(), dsp); 
    856     } 
    857  
    858     if (threadsWereRunning) view.getViewerBase()->startThreading(); 
    859      
    860     return true; 
    861 } 
    862  
    863572 
    864573int main(int argc, char** argv) 
     
    920629    } 
    921630 
    922     double partitionPosition = 5.0; 
    923     if (arguments.read("--depth-partition",partitionPosition) || arguments.read("--dp")) 
     631    double zNear=1.0, zMid=10.0, zFar=1000.0; 
     632    if (arguments.read("--depth-partition",zNear, zMid, zFar)) 
    924633    { 
    925634        // set up depth partitioning 
    926         osg::ref_ptr<DepthPartitionSettings> dps = new DepthPartitionSettings; 
    927         dps->_mode = DepthPartitionSettings::BOUNDING_VOLUME; 
    928         dps->_zNear = 0.5; 
    929         dps->_zMid = partitionPosition; 
    930         dps->_zFar = 1000.0; 
    931         setUpDepthPartition(viewer, dps.get()); 
     635        osg::ref_ptr<osgViewer::DepthPartitionSettings> dps = new osgViewer::DepthPartitionSettings; 
     636        dps->_mode = osgViewer::DepthPartitionSettings::FIXED_RANGE; 
     637        dps->_zNear = zNear; 
     638        dps->_zMid = zMid; 
     639        dps->_zFar = zFar; 
     640        viewer.setUpDepthPartition(dps.get()); 
     641    } 
     642 
     643    if (arguments.read("--dp")) 
     644    { 
     645        // set up depth partitioning 
     646        viewer.setUpDepthPartition(); 
    932647    } 
    933648