Show
Ignore:
Timestamp:
11/17/05 21:22:55 (8 years ago)
Author:
robert
Message:

Replaced tabs with spaces in examples.

Files:
1 modified

Legend:

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

    r4119 r4805  
    2929class RotateCallback: public osg::NodeCallback { 
    3030public: 
    31         RotateCallback(): osg::NodeCallback(), enabled_(true) {} 
    32         void operator()(osg::Node* node, osg::NodeVisitor *nv) 
    33         { 
    34                 osg::MatrixTransform *xform = dynamic_cast<osg::MatrixTransform *>(node); 
    35                 if (xform && enabled_) { 
    36                         double t = nv->getFrameStamp()->getReferenceTime(); 
    37                         xform->setMatrix(osg::Matrix::rotate(t, osg::Vec3(0, 0, 1))); 
    38                 } 
    39                 traverse(node, nv); 
    40         } 
    41  
    42         bool enabled_; 
     31    RotateCallback(): osg::NodeCallback(), enabled_(true) {} 
     32    void operator()(osg::Node* node, osg::NodeVisitor *nv) 
     33    { 
     34        osg::MatrixTransform *xform = dynamic_cast<osg::MatrixTransform *>(node); 
     35        if (xform && enabled_) { 
     36            double t = nv->getFrameStamp()->getReferenceTime(); 
     37            xform->setMatrix(osg::Matrix::rotate(t, osg::Vec3(0, 0, 1))); 
     38        } 
     39        traverse(node, nv); 
     40    } 
     41 
     42    bool enabled_; 
    4343}; 
    4444 
     
    5252public: 
    5353 
    54         class KeyboardHandler: public osgGA::GUIEventHandler { 
    55         public: 
    56                 KeyboardHandler(EffectPanel* ep): ep_(ep) {} 
    57  
    58                 bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &) 
    59                 { 
    60                         if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) { 
    61                                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right) { 
    62                                         ep_->setEffectIndex(ep_->getEffectIndex()+1); 
    63                                         return true; 
    64                                 } 
    65                                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left) { 
    66                                         ep_->setEffectIndex(ep_->getEffectIndex()-1); 
    67                                         return true; 
    68                                 } 
    69                                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Return) { 
    70                                         ep_->setNodeMask(0xffffffff - ep_->getNodeMask()); 
    71                                         return true; 
    72                                 } 
    73                                 if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Delete) { 
    74                                         ep_->setEffectsEnabled(!ep_->getEffectsEnabled()); 
    75                                         return true; 
    76                                 } 
    77                                 if (ea.getKey() == 'x') { 
    78                                         osgDB::writeNodeFile(*ep_->getRoot(), "osgfx_model.osg"); 
    79                                         std::cout << "written nodes to \"osgfx_model.osg\"\n"; 
    80                                         return true; 
    81                                 } 
    82                                 if (ea.getKey() == 'r') { 
    83                                         rotate_cb->enabled_ = !rotate_cb->enabled_; 
    84                                         return true; 
    85                                 } 
    86                         } 
    87  
    88                         return false; 
    89                 } 
    90  
    91         private: 
    92                 osg::ref_ptr<EffectPanel> ep_; 
    93         }; 
    94  
    95         EffectPanel() 
    96         :       osgfxbrowser::Frame(), 
    97                 _selected_fx(-1), 
    98                 _fxen(true), 
    99                 _root(new osg::Group), 
    100                 _hints_color(0.75f, 0.75f, 0.75f, 1.0f), 
    101                 _name_color(1, 1, 1, 1), 
    102                 _desc_color(1, 1, 0.7f, 1) 
    103         { 
    104                 setBackgroundColor(osg::Vec4(0.3f, 0.1f, 0.15f, 0.75f)); 
    105  
    106                 std::cout << "INFO: available osgFX effects:\n"; 
    107                 osgFX::Registry::EffectMap emap = osgFX::Registry::instance()->getEffectMap(); 
    108                 for (osgFX::Registry::EffectMap::const_iterator i=emap.begin(); i!=emap.end(); ++i) { 
    109                         std::cout << "INFO: \t" << i->first << "\n"; 
    110                         osg::ref_ptr<osgFX::Effect> effect = static_cast<osgFX::Effect *>(i->second->cloneType()); 
    111                         _effects.push_back(effect.get());                        
    112                 } 
    113  
    114                 std::cout << "INFO: " << emap.size() << " effect(s) ready.\n"; 
    115  
    116                 if (!_effects.empty()) { 
    117                         _selected_fx = 0; 
    118                 } 
    119         } 
    120  
    121         inline osg::Group* getRoot() { return _root.get(); } 
    122         inline void setRoot(osg::Group* node) { _root = node; } 
    123  
    124         inline osg::Node* getScene() { return _scene.get(); } 
    125         inline void setScene(osg::Node* node) { _scene = node; } 
    126  
    127         inline bool getEffectsEnabled() const { return _fxen; } 
    128         inline void setEffectsEnabled(bool v)  
    129         {  
    130                 _fxen = v;  
    131                 if (getSelectedEffect()) { 
    132                         getSelectedEffect()->setEnabled(_fxen); 
    133                 } 
    134         } 
    135  
    136         inline int getEffectIndex() const { return _selected_fx; } 
    137         inline void setEffectIndex(int i) 
    138         { 
    139                 if (i >= static_cast<int>(_effects.size())) i = 0; 
    140                 if (i < 0) i = static_cast<int>(_effects.size()-1);              
    141                 _selected_fx = i; 
    142                 rebuild(); 
    143         } 
    144  
    145         inline osgFX::Effect *getSelectedEffect() 
    146         { 
    147                 if (_selected_fx >= 0 && _selected_fx < static_cast<int>(_effects.size())) { 
    148                         return _effects[_selected_fx].get(); 
    149                 } 
    150                 return 0; 
    151         } 
     54    class KeyboardHandler: public osgGA::GUIEventHandler { 
     55    public: 
     56        KeyboardHandler(EffectPanel* ep): ep_(ep) {} 
     57 
     58        bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &) 
     59        { 
     60            if (ea.getEventType() == osgGA::GUIEventAdapter::KEYDOWN) { 
     61                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right) { 
     62                    ep_->setEffectIndex(ep_->getEffectIndex()+1); 
     63                    return true; 
     64                } 
     65                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left) { 
     66                    ep_->setEffectIndex(ep_->getEffectIndex()-1); 
     67                    return true; 
     68                } 
     69                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Return) { 
     70                    ep_->setNodeMask(0xffffffff - ep_->getNodeMask()); 
     71                    return true; 
     72                } 
     73                if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Delete) { 
     74                    ep_->setEffectsEnabled(!ep_->getEffectsEnabled()); 
     75                    return true; 
     76                } 
     77                if (ea.getKey() == 'x') { 
     78                    osgDB::writeNodeFile(*ep_->getRoot(), "osgfx_model.osg"); 
     79                    std::cout << "written nodes to \"osgfx_model.osg\"\n"; 
     80                    return true; 
     81                } 
     82                if (ea.getKey() == 'r') { 
     83                    rotate_cb->enabled_ = !rotate_cb->enabled_; 
     84                    return true; 
     85                } 
     86            } 
     87 
     88            return false; 
     89        } 
     90 
     91    private: 
     92        osg::ref_ptr<EffectPanel> ep_; 
     93    }; 
     94 
     95    EffectPanel() 
     96    :    osgfxbrowser::Frame(), 
     97        _selected_fx(-1), 
     98        _fxen(true), 
     99        _root(new osg::Group), 
     100        _hints_color(0.75f, 0.75f, 0.75f, 1.0f), 
     101        _name_color(1, 1, 1, 1), 
     102        _desc_color(1, 1, 0.7f, 1) 
     103    { 
     104        setBackgroundColor(osg::Vec4(0.3f, 0.1f, 0.15f, 0.75f)); 
     105 
     106        std::cout << "INFO: available osgFX effects:\n"; 
     107        osgFX::Registry::EffectMap emap = osgFX::Registry::instance()->getEffectMap(); 
     108        for (osgFX::Registry::EffectMap::const_iterator i=emap.begin(); i!=emap.end(); ++i) { 
     109            std::cout << "INFO: \t" << i->first << "\n"; 
     110            osg::ref_ptr<osgFX::Effect> effect = static_cast<osgFX::Effect *>(i->second->cloneType()); 
     111            _effects.push_back(effect.get());             
     112        } 
     113 
     114        std::cout << "INFO: " << emap.size() << " effect(s) ready.\n"; 
     115 
     116        if (!_effects.empty()) { 
     117            _selected_fx = 0; 
     118        } 
     119    } 
     120 
     121    inline osg::Group* getRoot() { return _root.get(); } 
     122    inline void setRoot(osg::Group* node) { _root = node; } 
     123 
     124    inline osg::Node* getScene() { return _scene.get(); } 
     125    inline void setScene(osg::Node* node) { _scene = node; } 
     126 
     127    inline bool getEffectsEnabled() const { return _fxen; } 
     128    inline void setEffectsEnabled(bool v)  
     129    {  
     130        _fxen = v;  
     131        if (getSelectedEffect()) { 
     132            getSelectedEffect()->setEnabled(_fxen); 
     133        } 
     134    } 
     135 
     136    inline int getEffectIndex() const { return _selected_fx; } 
     137    inline void setEffectIndex(int i) 
     138    { 
     139        if (i >= static_cast<int>(_effects.size())) i = 0; 
     140        if (i < 0) i = static_cast<int>(_effects.size()-1);         
     141        _selected_fx = i; 
     142        rebuild(); 
     143    } 
     144 
     145    inline osgFX::Effect *getSelectedEffect() 
     146    { 
     147        if (_selected_fx >= 0 && _selected_fx < static_cast<int>(_effects.size())) { 
     148            return _effects[_selected_fx].get(); 
     149        } 
     150        return 0; 
     151    } 
    152152 
    153153protected: 
    154         void rebuild_client_area(const osgfxbrowser::Rect &client_rect) 
    155         { 
     154    void rebuild_client_area(const osgfxbrowser::Rect &client_rect) 
     155    { 
    156156                float zPos = -0.1; // note from Robert, was 0.1f, but now must be -0.1f to keep text visible??#!? due 
    157157                                   // to some other change in the OSG not tracked down yet... 
    158158         
    159                 osg::ref_ptr<osgText::Font> arial = osgText::readFontFile("fonts/arial.ttf"); 
    160  
    161                 osg::ref_ptr<osgText::Text> hints = new osgText::Text; 
    162                 hints->setFont(arial.get()); 
    163                 hints->setColor(_hints_color); 
    164                 hints->setAlignment(osgText::Text::CENTER_BOTTOM); 
    165                 hints->setCharacterSize(13); 
    166                 hints->setFontResolution(13, 13); 
    167                 hints->setPosition(osg::Vec3((client_rect.x0+client_rect.x1)/2, client_rect.y0 + 4, zPos)); 
    168                 hints->setText("<RETURN> show/hide this panel      <LEFT> previous effect      <RIGHT> next effect      <DEL> enable/disable effects      'x' save to file      'r' rotate/stop"); 
    169                 addDrawable(hints.get()); 
    170  
    171                 std::string effect_name = "No Effect Selected"; 
    172                 std::string effect_description = ""; 
    173  
    174                 if (_selected_fx >= 0 && _selected_fx < static_cast<int>(_effects.size())) { 
    175                         effect_name = _effects[_selected_fx]->effectName(); 
    176                         std::string author_name = _effects[_selected_fx]->effectAuthor(); 
    177                         if (!author_name.empty()) { 
    178                                 effect_description = author_name = "AUTHOR: " + std::string(_effects[_selected_fx]->effectAuthor()) + std::string("\n\n"); 
    179                         } 
    180                         effect_description += "DESCRIPTION:\n" + std::string(_effects[_selected_fx]->effectDescription());                       
    181  
    182                         if (_scene.valid() && _root.valid()) { 
    183                                 _root->removeChild(0, _root->getNumChildren()); 
    184                                 osg::ref_ptr<osgFX::Effect> effect = _effects[_selected_fx].get(); 
    185                                 effect->setEnabled(_fxen); 
    186                                 effect->removeChild(0, effect->getNumChildren()); 
    187                                 effect->addChild(_scene.get()); 
    188                                 effect->setUpDemo(); 
    189                                 _root->addChild(effect.get()); 
    190                         } 
    191                 } 
    192  
    193                 osg::ref_ptr<osgText::Text> ename = new osgText::Text; 
    194                 ename->setFont(arial.get()); 
    195                 ename->setColor(_name_color); 
    196                 ename->setAlignment(osgText::Text::CENTER_TOP); 
    197                 ename->setCharacterSize(32); 
    198                 ename->setFontResolution(32, 32); 
    199                 ename->setPosition(osg::Vec3((client_rect.x0 + client_rect.x1) / 2, client_rect.y1 - 22, zPos)); 
    200                 ename->setText(effect_name); 
    201                 addDrawable(ename.get()); 
    202  
    203                 osg::ref_ptr<osgText::Text> edesc = new osgText::Text; 
    204                 edesc->setMaximumWidth(client_rect.width() - 16); 
    205                 edesc->setFont(arial.get()); 
    206                 edesc->setColor(_desc_color); 
    207                 edesc->setAlignment(osgText::Text::LEFT_TOP); 
    208                 edesc->setCharacterSize(16); 
    209                 edesc->setFontResolution(16, 16); 
    210                 edesc->setPosition(osg::Vec3(client_rect.x0 + 8, client_rect.y1 - 60, zPos)); 
    211                 edesc->setText(effect_description); 
    212                 addDrawable(edesc.get()); 
    213         } 
     159        osg::ref_ptr<osgText::Font> arial = osgText::readFontFile("fonts/arial.ttf"); 
     160 
     161        osg::ref_ptr<osgText::Text> hints = new osgText::Text; 
     162        hints->setFont(arial.get()); 
     163        hints->setColor(_hints_color); 
     164        hints->setAlignment(osgText::Text::CENTER_BOTTOM); 
     165        hints->setCharacterSize(13); 
     166        hints->setFontResolution(13, 13); 
     167        hints->setPosition(osg::Vec3((client_rect.x0+client_rect.x1)/2, client_rect.y0 + 4, zPos)); 
     168        hints->setText("<RETURN> show/hide this panel      <LEFT> previous effect      <RIGHT> next effect      <DEL> enable/disable effects      'x' save to file      'r' rotate/stop"); 
     169        addDrawable(hints.get()); 
     170 
     171        std::string effect_name = "No Effect Selected"; 
     172        std::string effect_description = ""; 
     173 
     174        if (_selected_fx >= 0 && _selected_fx < static_cast<int>(_effects.size())) { 
     175            effect_name = _effects[_selected_fx]->effectName(); 
     176            std::string author_name = _effects[_selected_fx]->effectAuthor(); 
     177            if (!author_name.empty()) { 
     178                effect_description = author_name = "AUTHOR: " + std::string(_effects[_selected_fx]->effectAuthor()) + std::string("\n\n"); 
     179            } 
     180            effect_description += "DESCRIPTION:\n" + std::string(_effects[_selected_fx]->effectDescription());             
     181 
     182            if (_scene.valid() && _root.valid()) { 
     183                _root->removeChild(0, _root->getNumChildren()); 
     184                osg::ref_ptr<osgFX::Effect> effect = _effects[_selected_fx].get(); 
     185                effect->setEnabled(_fxen); 
     186                effect->removeChild(0, effect->getNumChildren()); 
     187                effect->addChild(_scene.get()); 
     188                effect->setUpDemo(); 
     189                _root->addChild(effect.get()); 
     190            } 
     191        } 
     192 
     193        osg::ref_ptr<osgText::Text> ename = new osgText::Text; 
     194        ename->setFont(arial.get()); 
     195        ename->setColor(_name_color); 
     196        ename->setAlignment(osgText::Text::CENTER_TOP); 
     197        ename->setCharacterSize(32); 
     198        ename->setFontResolution(32, 32); 
     199        ename->setPosition(osg::Vec3((client_rect.x0 + client_rect.x1) / 2, client_rect.y1 - 22, zPos)); 
     200        ename->setText(effect_name); 
     201        addDrawable(ename.get()); 
     202 
     203        osg::ref_ptr<osgText::Text> edesc = new osgText::Text; 
     204        edesc->setMaximumWidth(client_rect.width() - 16); 
     205        edesc->setFont(arial.get()); 
     206        edesc->setColor(_desc_color); 
     207        edesc->setAlignment(osgText::Text::LEFT_TOP); 
     208        edesc->setCharacterSize(16); 
     209        edesc->setFontResolution(16, 16); 
     210        edesc->setPosition(osg::Vec3(client_rect.x0 + 8, client_rect.y1 - 60, zPos)); 
     211        edesc->setText(effect_description); 
     212        addDrawable(edesc.get()); 
     213    } 
    214214 
    215215private: 
    216         int _selected_fx; 
    217         typedef std::vector<osg::ref_ptr<osgFX::Effect> > Effect_list; 
    218         Effect_list _effects; 
    219         bool _fxen; 
    220         osg::ref_ptr<osg::Group> _root; 
    221         osg::ref_ptr<osg::Node> _scene; 
    222         osg::Vec4 _hints_color; 
    223         osg::Vec4 _name_color; 
    224         osg::Vec4 _desc_color; 
     216    int _selected_fx; 
     217    typedef std::vector<osg::ref_ptr<osgFX::Effect> > Effect_list; 
     218    Effect_list _effects; 
     219    bool _fxen; 
     220    osg::ref_ptr<osg::Group> _root; 
     221    osg::ref_ptr<osg::Node> _scene; 
     222    osg::Vec4 _hints_color; 
     223    osg::Vec4 _name_color; 
     224    osg::Vec4 _desc_color; 
    225225}; 
    226226 
     
    228228osg::Group* build_hud_base(osg::Group* root) 
    229229{ 
    230         osg::ref_ptr<osg::Projection> proj = new osg::Projection(osg::Matrix::ortho2D(0, 1024, 0, 768)); 
    231         proj->setCullingActive(false); 
    232         root->addChild(proj.get()); 
    233  
    234         osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform(osg::Matrix::identity()); 
    235         xform->setReferenceFrame(osg::Transform::ABSOLUTE_RF); 
    236         proj->addChild(xform.get()); 
    237  
    238         osg::StateSet *ss = xform->getOrCreateStateSet(); 
    239         ss->setRenderBinDetails(100, "RenderBin"); 
    240         ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); 
    241         ss->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); 
    242  
    243         osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc; 
    244         ss->setAttributeAndModes(bf.get()); 
    245  
    246         return xform.take(); 
     230    osg::ref_ptr<osg::Projection> proj = new osg::Projection(osg::Matrix::ortho2D(0, 1024, 0, 768)); 
     231    proj->setCullingActive(false); 
     232    root->addChild(proj.get()); 
     233 
     234    osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform(osg::Matrix::identity()); 
     235    xform->setReferenceFrame(osg::Transform::ABSOLUTE_RF); 
     236    proj->addChild(xform.get()); 
     237 
     238    osg::StateSet *ss = xform->getOrCreateStateSet(); 
     239    ss->setRenderBinDetails(100, "RenderBin"); 
     240    ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF); 
     241    ss->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); 
     242 
     243    osg::ref_ptr<osg::BlendFunc> bf = new osg::BlendFunc; 
     244    ss->setAttributeAndModes(bf.get()); 
     245 
     246    return xform.take(); 
    247247} 
    248248 
    249249EffectPanel* build_gui(osg::Group* root) 
    250250{ 
    251         osg::ref_ptr<osg::Group> hud = build_hud_base(root); 
    252  
    253         osg::ref_ptr<EffectPanel> effect_panel = new EffectPanel; 
    254         effect_panel->setCaption("osgFX Effect Browser"); 
    255         effect_panel->setRect(osgfxbrowser::Rect(20, 20, 1000, 280));    
    256  
    257         hud->addChild(effect_panel.get()); 
    258  
    259         return effect_panel.take(); 
     251    osg::ref_ptr<osg::Group> hud = build_hud_base(root); 
     252 
     253    osg::ref_ptr<EffectPanel> effect_panel = new EffectPanel; 
     254    effect_panel->setCaption("osgFX Effect Browser"); 
     255    effect_panel->setRect(osgfxbrowser::Rect(20, 20, 1000, 280));     
     256 
     257    hud->addChild(effect_panel.get()); 
     258 
     259    return effect_panel.take(); 
    260260} 
    261261 
    262262void build_world(osg::Group* root, osg::Node* scene, osgProducer::Viewer& viewer) 
    263263{ 
    264         osg::ref_ptr<EffectPanel> effect_panel = build_gui(root); 
    265         effect_panel->setScene(scene); 
    266         effect_panel->rebuild(); 
    267  
    268         viewer.getEventHandlerList().push_front(new EffectPanel::KeyboardHandler(effect_panel.get())); 
    269  
    270         root->addChild(effect_panel->getRoot()); 
     264    osg::ref_ptr<EffectPanel> effect_panel = build_gui(root); 
     265    effect_panel->setScene(scene); 
     266    effect_panel->rebuild(); 
     267 
     268    viewer.getEventHandlerList().push_front(new EffectPanel::KeyboardHandler(effect_panel.get())); 
     269 
     270    root->addChild(effect_panel->getRoot()); 
    271271} 
    272272 
     
    281281    arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName() + " [options] filename ..."); 
    282282    arguments.getApplicationUsage()->addCommandLineOption("-h or --help", "Display this information"); 
    283         arguments.getApplicationUsage()->addKeyboardMouseBinding("Left", "Apply previous effect"); 
    284         arguments.getApplicationUsage()->addKeyboardMouseBinding("Right", "Apply next effect"); 
    285         arguments.getApplicationUsage()->addKeyboardMouseBinding("Del", "Enable or disable osgFX"); 
    286         arguments.getApplicationUsage()->addKeyboardMouseBinding("Return", "Show or hide the effect information panel"); 
    287         arguments.getApplicationUsage()->addKeyboardMouseBinding("x", "Save the scene graph with current effect applied"); 
     283    arguments.getApplicationUsage()->addKeyboardMouseBinding("Left", "Apply previous effect"); 
     284    arguments.getApplicationUsage()->addKeyboardMouseBinding("Right", "Apply next effect"); 
     285    arguments.getApplicationUsage()->addKeyboardMouseBinding("Del", "Enable or disable osgFX"); 
     286    arguments.getApplicationUsage()->addKeyboardMouseBinding("Return", "Show or hide the effect information panel"); 
     287    arguments.getApplicationUsage()->addKeyboardMouseBinding("x", "Save the scene graph with current effect applied"); 
    288288 
    289289 
     
    337337    optimizer.optimize(loadedModel.get()); 
    338338 
    339         // set up a transform to rotate the model 
    340         osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform; 
    341         rotate_cb = new RotateCallback; 
    342         xform->setUpdateCallback(rotate_cb); 
    343         xform->addChild(loadedModel.get()); 
    344  
    345         osg::ref_ptr<osg::Light> light = new osg::Light; 
    346         light->setLightNum(0); 
    347         light->setDiffuse(osg::Vec4(1, 1, 1, 1)); 
    348         light->setSpecular(osg::Vec4(1, 1, 0.8f, 1)); 
    349         light->setAmbient(osg::Vec4(0.2f, 0.2f, 0.2f, 0.2f)); 
    350         light->setPosition(osg::Vec4(1, -1, 1, 0)); 
    351  
    352         osg::ref_ptr<osg::LightSource> root = new osg::LightSource; 
    353         root->setLight(light.get()); 
    354         root->setLocalStateSetModes(); 
    355  
    356         build_world(root.get(), xform.get(), viewer); 
     339    // set up a transform to rotate the model 
     340    osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform; 
     341    rotate_cb = new RotateCallback; 
     342    xform->setUpdateCallback(rotate_cb); 
     343    xform->addChild(loadedModel.get()); 
     344 
     345    osg::ref_ptr<osg::Light> light = new osg::Light; 
     346    light->setLightNum(0); 
     347    light->setDiffuse(osg::Vec4(1, 1, 1, 1)); 
     348    light->setSpecular(osg::Vec4(1, 1, 0.8f, 1)); 
     349    light->setAmbient(osg::Vec4(0.2f, 0.2f, 0.2f, 0.2f)); 
     350    light->setPosition(osg::Vec4(1, -1, 1, 0)); 
     351 
     352    osg::ref_ptr<osg::LightSource> root = new osg::LightSource; 
     353    root->setLight(light.get()); 
     354    root->setLocalStateSetModes(); 
     355 
     356    build_world(root.get(), xform.get(), viewer); 
    357357 
    358358    // set the scene to render