Show
Ignore:
Timestamp:
03/02/11 17:09:50 (3 years ago)
Author:
robert
Message:

Implemented first cut of more flexible depth partitioning code.

Files:
1 modified

Legend:

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

    r12198 r12199  
    4848#include <osgDB/WriteFile> 
    4949 
     50#include <osg/io_utils> 
    5051#include <iostream> 
    5152 
     
    569570} 
    570571 
     572struct 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 
    571676struct MyUpdateSlaveCallback : public osg::View::Slave::UpdateSlaveCallback 
    572677{ 
    573     MyUpdateSlaveCallback(double nr, double fr):_zNear(nr),_zFar(fr) {} 
     678    MyUpdateSlaveCallback(DepthPartitionSettings* dps, unsigned int partition):_dps(dps), _partition(partition) {} 
    574679     
    575680    virtual void updateSlave(osg::View& view, osg::View::Slave& slave) 
    576681    { 
    577682        slave.updateSlaveImplementation(view); 
     683 
     684        if (!_dps) return; 
     685 
    578686        osg::Camera* camera = slave._camera.get(); 
    579687 
    580         //camera->setProjectionMatrixAsOrtho(-1,1,-1,1,1,1000); 
     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        } 
    581700 
    582701        if (camera->getProjectionMatrix()(0,3)==0.0 && 
     
    584703            camera->getProjectionMatrix()(2,3)==0.0) 
    585704        { 
    586             //OSG_NOTICE<<"MyUpdateSlaveCallback othographic camera"<<std::endl; 
    587705            double left, right, bottom, top, zNear, zFar; 
    588706            camera->getProjectionMatrixAsOrtho(left, right, bottom, top, zNear, zFar); 
    589             camera->setProjectionMatrixAsOrtho(left, right, bottom, top, _zNear, _zFar); 
     707            camera->setProjectionMatrixAsOrtho(left, right, bottom, top, computed_zNear, computed_zFar); 
    590708        } 
    591709        else 
     
    593711            double left, right, bottom, top, zNear, zFar; 
    594712            camera->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar); 
    595             //OSG_NOTICE<<"MyUpdateSlaveCallback perpective camera zNear="<<zNear<<", zFar="<<zFar<<std::endl; 
    596             double nr = _zNear / zNear; 
    597             camera->setProjectionMatrixAsFrustum(left * nr, right * nr, bottom * nr, top * nr, _zNear, _zFar); 
    598         } 
    599     } 
    600  
    601     double _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; 
    602721}; 
    603722 
     
    645764    } 
    646765 
    647     double zNear = 0.5; 
    648     double zMid = partitionPosition; 
    649     double zFar = 200.0; 
     766    osg::ref_ptr<DepthPartitionSettings> dps = new DepthPartitionSettings; 
     767 
     768    dps->_mode = DepthPartitionSettings::BOUNDING_VOLUME; 
     769    dps->_zNear = 0.5; 
     770    dps->_zMid = partitionPosition; 
     771    dps->_zFar = 1000.0; 
    650772 
    651773    // far camera 
     
    668790 
    669791        osg::View::Slave& slave = viewer.getSlave(viewer.getNumSlaves()-1); 
    670         slave._updateSlaveCallback =  new MyUpdateSlaveCallback(zMid, zFar); 
     792        slave._updateSlaveCallback =  new MyUpdateSlaveCallback(dps.get(), 1); 
    671793    } 
    672794 
     
    691813 
    692814        osg::View::Slave& slave = viewer.getSlave(viewer.getNumSlaves()-1); 
    693         slave._updateSlaveCallback =  new MyUpdateSlaveCallback(zNear, zMid); 
     815        slave._updateSlaveCallback =  new MyUpdateSlaveCallback(dps.get(), 0); 
    694816    } 
    695817} 
     
    825947 
    826948    osg::ref_ptr<osgShadow::MinimalShadowMap> msm = NULL; 
    827     if (arguments.read("--sv")) 
     949    if (arguments.read("--no-shadows")) 
     950    { 
     951        OSG_NOTICE<<"Not using a ShadowTechnique"<<std::endl; 
     952        shadowedScene->setShadowTechnique(0); 
     953    } 
     954    else if (arguments.read("--sv")) 
    828955    { 
    829956        // hint to tell viewer to request stencil buffer when setting up windows 
     
    9511078        msm->setBaseTextureUnit( baseTexUnit ); 
    9521079    } 
     1080 
     1081    OSG_NOTICE<<"shadowedScene->getShadowTechnique()="<<shadowedScene->getShadowTechnique()<<std::endl; 
    9531082 
    9541083    osg::ref_ptr<osg::Node> model = osgDB::readNodeFiles(arguments);