Show
Ignore:
Timestamp:
01/14/11 13:08:46 (3 years ago)
Author:
robert
Message:

From Wang Rui, "I'd like to submit a small new feature to the osgmanipulator example
which could fix the dragger size in screen, so that no matter how we
zoom in/out the camera, the dragger will never be scaled.

This is what 3D graphics software like 3dsmax and maya behave, which
helps users select and manipulate draggers more easily.

You may turn on the feature with the new --fixedDraggerSize argument:

# osgmanipulator.exe --fixedDraggerSize --dragger TranslateAxisDragger?
cessna.osg
"

Files:
1 modified

Legend:

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

    r10523 r12088  
    9696} 
    9797 
    98  
    99 osg::Node* addDraggerToScene(osg::Node* scene, const std::string& name) 
     98// The DraggerContainer node is used to fix the dragger's size on the screen 
     99class DraggerContainer : public osg::Group 
     100{ 
     101public: 
     102    DraggerContainer() : _draggerSize(240.0f), _active(true) {} 
     103     
     104    DraggerContainer( const DraggerContainer& copy, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY ) 
     105    :   osg::Group(copy, copyop), 
     106        _dragger(copy._dragger), _draggerSize(copy._draggerSize), _active(copy._active) 
     107    {} 
     108     
     109    META_Node( osgManipulator, DraggerContainer ); 
     110     
     111    void setDragger( osgManipulator::Dragger* dragger ) 
     112    { 
     113        _dragger = dragger; 
     114        if ( !containsNode(dragger) ) addChild( dragger ); 
     115    } 
     116     
     117    osgManipulator::Dragger* getDragger() { return _dragger.get(); } 
     118    const osgManipulator::Dragger* getDragger() const { return _dragger.get(); } 
     119     
     120    void setDraggerSize( float size ) { _draggerSize = size; } 
     121    float getDraggerSize() const { return _draggerSize; } 
     122     
     123    void setActive( bool b ) { _active = b; } 
     124    bool getActive() const { return _active; } 
     125     
     126    void traverse( osg::NodeVisitor& nv ) 
     127    { 
     128        if ( _dragger.valid() ) 
     129        { 
     130            if ( _active && nv.getVisitorType()==osg::NodeVisitor::CULL_VISITOR ) 
     131            { 
     132                osgUtil::CullVisitor* cv = static_cast<osgUtil::CullVisitor*>(&nv); 
     133                 
     134                float pixelSize = cv->pixelSize(_dragger->getBound().center(), 0.48f); 
     135                if ( pixelSize!=_draggerSize ) 
     136                { 
     137                    float pixelScale = pixelSize>0.0f ? _draggerSize/pixelSize : 1.0f; 
     138                    osg::Vec3d scaleFactor(pixelScale, pixelScale, pixelScale); 
     139                     
     140                    osg::Vec3 trans = _dragger->getMatrix().getTrans(); 
     141                    _dragger->setMatrix( osg::Matrix::scale(scaleFactor) * osg::Matrix::translate(trans) ); 
     142                } 
     143            } 
     144        } 
     145        osg::Group::traverse(nv); 
     146    } 
     147     
     148protected: 
     149    osg::ref_ptr<osgManipulator::Dragger> _dragger; 
     150    float _draggerSize; 
     151    bool _active; 
     152}; 
     153 
     154osg::Node* addDraggerToScene(osg::Node* scene, const std::string& name, bool fixedSizeInScreen) 
    100155{ 
    101156    scene->getOrCreateStateSet()->setMode(GL_NORMALIZE, osg::StateAttribute::ON); 
     
    106161    osgManipulator::Dragger* dragger = createDragger(name); 
    107162 
    108  
    109163    osg::Group* root = new osg::Group; 
    110     root->addChild(dragger); 
    111164    root->addChild(selection); 
     165 
     166    if ( fixedSizeInScreen ) 
     167    { 
     168        DraggerContainer* draggerContainer = new DraggerContainer; 
     169        draggerContainer->setDragger( dragger ); 
     170        root->addChild(draggerContainer); 
     171    } 
     172    else 
     173        root->addChild(dragger); 
    112174 
    113175    float scale = scene->getBound().radius() * 1.6; 
     
    131193} 
    132194 
    133 osg::Node* createDemoScene() { 
     195osg::Node* createDemoScene(bool fixedSizeInScreen) { 
    134196  
    135197    osg::Group* root = new osg::Group; 
     
    207269    root->getOrCreateStateSet()->setAttributeAndModes(matirial.get(), osg::StateAttribute::ON); 
    208270 
    209       transform_1.get()->addChild(addDraggerToScene(geode_1.get(),"TabBoxDragger")); 
    210     transform_2.get()->addChild(addDraggerToScene(geode_2.get(),"TabPlaneDragger")); 
    211     transform_3.get()->addChild(addDraggerToScene(geode_3.get(),"TabBoxTrackballDragger")); 
    212     transform_4.get()->addChild(addDraggerToScene(geode_4.get(),"TrackballDragger")); 
    213     transform_5.get()->addChild(addDraggerToScene(geode_5.get(),"Translate1DDragger")); 
    214     transform_6.get()->addChild(addDraggerToScene(geode_6.get(),"Translate2DDragger")); 
    215     transform_7.get()->addChild(addDraggerToScene(geode_7.get(),"TranslateAxisDragger")); 
     271      transform_1.get()->addChild(addDraggerToScene(geode_1.get(),"TabBoxDragger",fixedSizeInScreen)); 
     272    transform_2.get()->addChild(addDraggerToScene(geode_2.get(),"TabPlaneDragger",fixedSizeInScreen)); 
     273    transform_3.get()->addChild(addDraggerToScene(geode_3.get(),"TabBoxTrackballDragger",fixedSizeInScreen)); 
     274    transform_4.get()->addChild(addDraggerToScene(geode_4.get(),"TrackballDragger",fixedSizeInScreen)); 
     275    transform_5.get()->addChild(addDraggerToScene(geode_5.get(),"Translate1DDragger",fixedSizeInScreen)); 
     276    transform_6.get()->addChild(addDraggerToScene(geode_6.get(),"Translate2DDragger",fixedSizeInScreen)); 
     277    transform_7.get()->addChild(addDraggerToScene(geode_7.get(),"TranslateAxisDragger",fixedSizeInScreen)); 
    216278 
    217279    root->addChild(transform_1.get()); 
     
    245307 
    246308    arguments.getApplicationUsage()->addCommandLineOption("--dragger <draggername>","Use the specified dragger for manipulation [TabPlaneDragger,TabPlaneTrackballDragger,TrackballDragger,Translate1DDragger,Translate2DDragger,TranslateAxisDragger,TabBoxDragger]"); 
    247      
     309    arguments.getApplicationUsage()->addCommandLineOption("--fixedDraggerSize","Fix the size of the dragger geometry in the screen space"); 
     310     
     311    bool fixedSizeInScreen = false; 
     312    while (arguments.read("--fixedDraggerSize")) { fixedSizeInScreen = true; } 
    248313 
    249314    // construct the viewer. 
     
    285350        //std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; 
    286351        //return 1; 
    287         loadedModel = createDemoScene(); 
     352        loadedModel = createDemoScene(fixedSizeInScreen); 
    288353        tragger2Scene=false; 
    289354    } 
     
    310375    // pass the loaded scene graph to the viewer. 
    311376    if ( tragger2Scene ) { 
    312         viewer.setSceneData(addDraggerToScene(loadedModel.get(), dragger_name)); 
     377        viewer.setSceneData(addDraggerToScene(loadedModel.get(), dragger_name, fixedSizeInScreen)); 
    313378    } else {  
    314379        viewer.setSceneData(loadedModel.get());