Show
Ignore:
Timestamp:
12/16/08 21:29:00 (6 years ago)
Author:
robert
Message:

From Cedric Pinson and Jeremey Moles, Changes to OpenSceneGraph-osgWidget-dev branch.

Notes from Robert Osfield, Merged changes to OpenSceneGraph-osgWidget-dev r9367 (prior to my botched attempt at merged svn/trunk into the branch).

Files:
1 modified

Legend:

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

    r9289 r9370  
    1616// Here we create (and later demonstrate) the use of a simple function callback. 
    1717bool windowClicked(osgWidget::Event& ev) { 
    18         std::cout << "windowClicked: " << ev.getWindow()->getName() << std::endl; 
    19  
    20         if(ev.getData()) { 
    21                 std::string* s = static_cast<std::string*>(ev.getData()); 
    22  
    23                 std::cout << "This is data attached to the event: " << *s << std::endl; 
    24         } 
    25  
    26         return true; 
     18    std::cout << "windowClicked: " << ev.getWindow()->getName() << std::endl; 
     19 
     20    if(ev.getData()) { 
     21        std::string* s = static_cast<std::string*>(ev.getData()); 
     22 
     23        std::cout << "This is data attached to the event: " << *s << std::endl; 
     24    } 
     25 
     26    return true; 
    2727} 
    2828 
    2929bool windowScrolled(osgWidget::Event& ev) { 
    30         osgWidget::warn() 
    31                 << "scrolling up? " << ev.getWindowManager()->isMouseScrollingUp() 
    32                 << std::endl 
    33         ; 
    34  
    35         return true; 
     30    osgWidget::warn() 
     31        << "scrolling up? " << ev.getWindowManager()->isMouseScrollingUp() 
     32        << std::endl 
     33    ; 
     34 
     35    return true; 
    3636} 
    3737 
     
    3939// a function callback in that we are required to also pass the "this" argument). 
    4040struct Object { 
    41         bool windowClicked(osgWidget::Event& ev) { 
    42                 std::cout << "Object::windowClicked " << ev.getWindow()->getName() << std::endl; 
    43  
    44                 return true; 
    45         } 
     41    bool windowClicked(osgWidget::Event& ev) { 
     42        std::cout << "Object::windowClicked " << ev.getWindow()->getName() << std::endl; 
     43 
     44        return true; 
     45    } 
    4646}; 
    4747 
    4848// This is the more "traditional" method of creating a callback. 
    4949struct CallbackObject: public osgWidget::Callback { 
    50         CallbackObject(osgWidget::EventType evType): 
    51         osgWidget::Callback(evType) { 
    52         } 
    53  
    54         virtual bool operator()(osgWidget::Event& ev) { 
    55                 std::cout << "here" << std::endl; 
    56                  
    57                 return false; 
    58         } 
     50    CallbackObject(osgWidget::EventType evType): 
     51    osgWidget::Callback(evType) { 
     52    } 
     53 
     54    virtual bool operator()(osgWidget::Event& ev) { 
     55        std::cout << "here" << std::endl; 
     56         
     57        return false; 
     58    } 
    5959}; 
    6060 
    6161int main(int argc, char** argv) { 
    62         osgViewer::Viewer viewer; 
    63          
    64         // Let's get busy! The WindowManager class is actually an osg::Switch, 
    65         // so you can add it to (ideally) an orthographic camera and have it behave as 
    66         // expected. Note that you create a WindowManager with a NodeMask--it is very important 
    67         // that this be unique for picking to work properly. This also makes it possible to have 
    68         // multiple WindowManagers each operating on their own, unique set of Window objects. 
    69         // The final bool argument is a group of flags that introduce optional functionality 
    70         // for the WindowManager. In our case we include the flags USE_PYTHON and USE_LUA, 
    71         // to demonstrate (and test) their usage. Finally, we pass the temporary WM_NO_BETA_WARN 
    72         // argument, which prevents creating the orange warning window. :) It will be shown 
    73         // in other examples... 
    74         osgWidget::WindowManager* wm = new osgWidget::WindowManager( 
    75                 &viewer, 
    76                 1280.0f, 
    77                 1024.0f, 
    78                 MASK_2D, 
    79                 osgWidget::WindowManager::WM_USE_LUA | 
    80                 osgWidget::WindowManager::WM_USE_PYTHON | 
    81                 osgWidget::WindowManager::WM_PICK_DEBUG 
    82         ); 
    83  
    84         // An actual osgWidget::Window is pure virtual, so we've got to use the osgWidget::Box 
    85         // implementation for now. At a later time, support for Tables and other kinds of 
    86         // advanced layout Window types will be added. 
    87         osgWidget::Window* box = new osgWidget::Box("box", osgWidget::Box::HORIZONTAL); 
    88  
    89         // Now we actually attach our two types of callbacks to the box instance. The first 
    90         // uses the simple function signature, the second uses a bound method, passing "this" 
    91         // as the second argument to the Callback constructor. 
    92         Object obj; 
    93  
    94         static std::string data = "lol ur face!"; 
    95  
    96         /* 
    97         box->addCallback(new osgWidget::Callback(&windowClicked, osgWidget::EVENT_MOUSE_PUSH, &data)); 
    98         box->addCallback(new osgWidget::Callback(&windowScrolled, osgWidget::EVENT_MOUSE_SCROLL)); 
    99         box->addCallback(osgWidget::Callback( 
    100                 &Object::windowClicked, 
    101                 &obj, 
    102                 osgWidget::EVENT_MOUSE_PUSH 
    103         )); 
    104         */ 
    105  
    106         box->addCallback(new CallbackObject(osgWidget::EVENT_MOUSE_PUSH)); 
    107  
    108         // Create some of our "testing" Widgets; included are two Widget subclasses I made 
    109         // during testing which I've kept around for testing purposes. You'll notice 
    110         // that you cannot move the box using the NullWidget, and that the NotifyWidget 
    111         // is a bit verbose. :) 
    112         osgWidget::Widget* widget1 = new osgWidget::NotifyWidget("widget1", 300.0f, 100.0f); 
    113         osgWidget::Widget* widget2 = new osgWidget::NullWidget("widget2", 400.0f, 75.0f); 
    114         osgWidget::Widget* widget3 = new osgWidget::Widget("widget3", 100.0f, 100.0f); 
    115         // Set the colors of widget1 and widget3 to green. 
    116         widget1->setColor(0.0f, 1.0f, 0.0f, 1.0f); 
    117         widget1->setCanFill(true); 
    118         widget3->setColor(0.0f, 1.0f, 0.0f, 1.0f); 
    119  
    120         widget1->setImage(osgDB::readImageFile("Images/Saturn.TGA"), true); 
    121  
    122         // Set the color of widget2, to differentiate it and make it sassy. This is 
    123         // like a poor man's gradient! 
    124         widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_LEFT); 
    125         widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_RIGHT); 
    126         widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_RIGHT); 
    127         widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_LEFT); 
    128  
    129         // Now add our newly created widgets to our box. 
    130         box->addWidget(widget1); 
    131         box->addWidget(widget2); 
    132         box->addWidget(widget3); 
    133  
    134         // For maximum efficiency, Windows don't automatically reallocate their geometry 
    135         // and internal positioning every time a widget is added. Thus, we either have to 
    136         // call the WindowManger::resizeAllWindows method or manually call 
    137         // Window::resize when we're ready. 
    138         box->resize(); 
    139  
    140         // Now, lets clone our existing box and create a new copy of of it, also adding that 
    141         // to the WindowManager. This demonstrates the usages of OSG's ->clone() support, 
    142         // though that is abstracted by our META_UIObject macro. 
    143         osgWidget::Window* boxCopy = osg::clone(box, "newBox", osg::CopyOp::DEEP_COPY_ALL); 
    144  
    145         // Move our copy to make it visible. 
    146         boxCopy->setOrigin(0.0f, 125.0f); 
    147  
    148         boxCopy->getByName("widget1")->setColor(0.5f, 0.0f, 1.0f, 1.0f); 
    149         boxCopy->getByName("widget3")->setColor(0.5f, 0.0f, 1.0f, 1.0f); 
    150  
    151         // Add the successfully created Box (if we get this far) into the WindowManager, so 
    152         // that they can receive events. 
    153         wm->addChild(box); 
    154         wm->addChild(boxCopy); 
    155  
    156         // Now, ask our new box to be 100% the width of the WindowManager. 
    157         boxCopy->resizePercent(100.0f, 0.0f); 
    158  
    159         // Here we demonstrate the use of osgWidget/io_utils. This is really only useful for 
    160         // debugging at the moment, but later I'll make it more generic for .osg and .ive 
    161         // creation. 
    162         // std::cout << *box << std::endl << *boxCopy << std::endl; 
    163  
    164         // Setup our OSG objects for our scene; note the use of the utility function 
    165         // createOrthoCamera, which is just a helper for setting up a proper viewing area. 
    166         // An alternative (and a MUCH easier alternative at that!) is to 
    167         // simply use the createParentOrthoCamera method of the WindowManager class, 
    168         // which will wrap the calls to createOrthoCamera and addChild for us! Check out 
    169         // some of the other examples to see this in action... 
    170         osg::Group*  group  = new osg::Group(); 
    171         osg::Camera* camera = osgWidget::createOrthoCamera(1280.0f, 1024.0f); 
    172         osg::Node*   model  = osgDB::readNodeFile("cow.osg"); 
    173  
    174         // Add our event handler; is this better as a MatrixManipulator? Add a few other 
    175         // helpful ViewerEventHandlers. 
    176         viewer.addEventHandler(new osgWidget::MouseHandler(wm)); 
    177         viewer.addEventHandler(new osgWidget::KeyboardHandler(wm)); 
    178         viewer.addEventHandler(new osgWidget::ResizeHandler(wm, camera)); 
    179         viewer.addEventHandler(new osgWidget::CameraSwitchHandler(wm, camera)); 
    180         viewer.addEventHandler(new osgViewer::StatsHandler()); 
    181         viewer.addEventHandler(new osgViewer::WindowSizeHandler()); 
    182         viewer.addEventHandler(new osgGA::StateSetManipulator( 
    183                 viewer.getCamera()->getOrCreateStateSet() 
    184         )); 
    185  
    186         // Set our first non-UI node to be something other than the mask we created our 
    187         // WindowManager with to avoid picking. 
    188         // TODO: Do I need to create a mechanism for doing this automatically, or should 
    189         // that be the responsibility of the users of osgWidget? 
    190         model->setNodeMask(MASK_3D); 
    191  
    192         // Add the WindowManager instance to the 2D camera. This isn't strictly necessary, 
    193         // and you can get some cool results putting the WindowManager directly into a 
    194         // 3D scene. This is not necessary if you use WindowManager::createParentOrthoCamera. 
    195         camera->addChild(wm); 
    196  
    197         // Add our camera and a testing 3D model to the scene. 
    198         group->addChild(camera); 
    199         group->addChild(model); 
    200  
    201         // Here we show how to both run simple strings of code AND run entire files. These 
    202         // assume that you're running the osgwidgetwindow example from the build directory, 
    203         // otherwise you'll need to adjust the file path below in the call to runFile(). 
    204         wm->getLuaEngine()->eval("window = osgwidget.newWindow()"); 
    205         wm->getLuaEngine()->runFile("osgWidget/osgwidgetwindow.lua"); 
    206  
    207         wm->getPythonEngine()->eval("import osgwidget"); 
    208         wm->getPythonEngine()->runFile("osgWidget/osgwidgetwindow.py"); 
    209  
    210         viewer.setUpViewInWindow(0, 0, 1280, 1024); 
    211         viewer.setSceneData(group); 
    212  
    213         /* 
    214         osgViewer::Viewer::Cameras cameras;  
    215         viewer.getCameras(cameras); 
    216         osg::Camera* c = cameras[0]; 
    217         osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f); 
    218         c->setProjectionMatrix(s * c->getProjectionMatrix()); 
    219         */ 
    220  
    221         return viewer.run(); 
     62    osgViewer::Viewer viewer; 
     63     
     64    // Let's get busy! The WindowManager class is actually an osg::Switch, 
     65    // so you can add it to (ideally) an orthographic camera and have it behave as 
     66    // expected. Note that you create a WindowManager with a NodeMask--it is very important 
     67    // that this be unique for picking to work properly. This also makes it possible to have 
     68    // multiple WindowManagers each operating on their own, unique set of Window objects. 
     69    // The final bool argument is a group of flags that introduce optional functionality 
     70    // for the WindowManager. In our case we include the flags USE_PYTHON and USE_LUA, 
     71    // to demonstrate (and test) their usage. Finally, we pass the temporary WM_NO_BETA_WARN 
     72    // argument, which prevents creating the orange warning window. :) It will be shown 
     73    // in other examples... 
     74    osgWidget::WindowManager* wm = new osgWidget::WindowManager( 
     75        &viewer, 
     76        1280.0f, 
     77        1024.0f, 
     78        MASK_2D, 
     79        osgWidget::WindowManager::WM_USE_LUA | 
     80        osgWidget::WindowManager::WM_USE_PYTHON | 
     81        osgWidget::WindowManager::WM_PICK_DEBUG 
     82    ); 
     83 
     84    // An actual osgWidget::Window is pure virtual, so we've got to use the osgWidget::Box 
     85    // implementation for now. At a later time, support for Tables and other kinds of 
     86    // advanced layout Window types will be added. 
     87    osgWidget::Window* box = new osgWidget::Box("box", osgWidget::Box::HORIZONTAL); 
     88 
     89    // Now we actually attach our two types of callbacks to the box instance. The first 
     90    // uses the simple function signature, the second uses a bound method, passing "this" 
     91    // as the second argument to the Callback constructor. 
     92    Object obj; 
     93 
     94    static std::string data = "lol ur face!"; 
     95 
     96    /* 
     97    box->addCallback(new osgWidget::Callback(&windowClicked, osgWidget::EVENT_MOUSE_PUSH, &data)); 
     98    box->addCallback(new osgWidget::Callback(&windowScrolled, osgWidget::EVENT_MOUSE_SCROLL)); 
     99    box->addCallback(osgWidget::Callback( 
     100        &Object::windowClicked, 
     101        &obj, 
     102        osgWidget::EVENT_MOUSE_PUSH 
     103    )); 
     104    */ 
     105 
     106    box->addCallback(new CallbackObject(osgWidget::EVENT_MOUSE_PUSH)); 
     107 
     108    // Create some of our "testing" Widgets; included are two Widget subclasses I made 
     109    // during testing which I've kept around for testing purposes. You'll notice 
     110    // that you cannot move the box using the NullWidget, and that the NotifyWidget 
     111    // is a bit verbose. :) 
     112    osgWidget::Widget* widget1 = new osgWidget::NotifyWidget("widget1", 300.0f, 100.0f); 
     113    osgWidget::Widget* widget2 = new osgWidget::NullWidget("widget2", 400.0f, 75.0f); 
     114    osgWidget::Widget* widget3 = new osgWidget::Widget("widget3", 100.0f, 100.0f); 
     115    // Set the colors of widget1 and widget3 to green. 
     116    widget1->setColor(0.0f, 1.0f, 0.0f, 1.0f); 
     117    widget1->setCanFill(true); 
     118    widget3->setColor(0.0f, 1.0f, 0.0f, 1.0f); 
     119 
     120    widget1->setImage(osgDB::readImageFile("Images/Saturn.TGA"), true); 
     121 
     122    // Set the color of widget2, to differentiate it and make it sassy. This is 
     123    // like a poor man's gradient! 
     124    widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_LEFT); 
     125    widget2->setColor(0.9f, 0.0f, 0.0f, 0.9f, osgWidget::Widget::LOWER_RIGHT); 
     126    widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_RIGHT); 
     127    widget2->setColor(0.0f, 0.0f, 0.9f, 0.9f, osgWidget::Widget::UPPER_LEFT); 
     128 
     129    // Now add our newly created widgets to our box. 
     130    box->addWidget(widget1); 
     131    box->addWidget(widget2); 
     132    box->addWidget(widget3); 
     133 
     134    // For maximum efficiency, Windows don't automatically reallocate their geometry 
     135    // and internal positioning every time a widget is added. Thus, we either have to 
     136    // call the WindowManger::resizeAllWindows method or manually call 
     137    // Window::resize when we're ready. 
     138    box->resize(); 
     139 
     140    // Now, lets clone our existing box and create a new copy of of it, also adding that 
     141    // to the WindowManager. This demonstrates the usages of OSG's ->clone() support, 
     142    // though that is abstracted by our META_UIObject macro. 
     143    osgWidget::Window* boxCopy = osg::clone(box, "newBox", osg::CopyOp::DEEP_COPY_ALL); 
     144 
     145    // Move our copy to make it visible. 
     146    boxCopy->setOrigin(0.0f, 125.0f); 
     147 
     148    boxCopy->getByName("widget1")->setColor(0.5f, 0.0f, 1.0f, 1.0f); 
     149    boxCopy->getByName("widget3")->setColor(0.5f, 0.0f, 1.0f, 1.0f); 
     150 
     151    // Add the successfully created Box (if we get this far) into the WindowManager, so 
     152    // that they can receive events. 
     153    wm->addChild(box); 
     154    wm->addChild(boxCopy); 
     155 
     156    // Now, ask our new box to be 100% the width of the WindowManager. 
     157    boxCopy->resizePercent(100.0f, 0.0f); 
     158 
     159    // Here we demonstrate the use of osgWidget/io_utils. This is really only useful for 
     160    // debugging at the moment, but later I'll make it more generic for .osg and .ive 
     161    // creation. 
     162    // std::cout << *box << std::endl << *boxCopy << std::endl; 
     163 
     164    // Setup our OSG objects for our scene; note the use of the utility function 
     165    // createOrthoCamera, which is just a helper for setting up a proper viewing area. 
     166    // An alternative (and a MUCH easier alternative at that!) is to 
     167    // simply use the createParentOrthoCamera method of the WindowManager class, 
     168    // which will wrap the calls to createOrthoCamera and addChild for us! Check out 
     169    // some of the other examples to see this in action... 
     170    osg::Group*  group  = new osg::Group(); 
     171    osg::Camera* camera = osgWidget::createOrthoCamera(1280.0f, 1024.0f); 
     172    osg::Node*   model  = osgDB::readNodeFile("cow.osg"); 
     173 
     174    // Add our event handler; is this better as a MatrixManipulator? Add a few other 
     175    // helpful ViewerEventHandlers. 
     176    viewer.addEventHandler(new osgWidget::MouseHandler(wm)); 
     177    viewer.addEventHandler(new osgWidget::KeyboardHandler(wm)); 
     178    viewer.addEventHandler(new osgWidget::ResizeHandler(wm, camera)); 
     179    viewer.addEventHandler(new osgWidget::CameraSwitchHandler(wm, camera)); 
     180    viewer.addEventHandler(new osgViewer::StatsHandler()); 
     181    viewer.addEventHandler(new osgViewer::WindowSizeHandler()); 
     182    viewer.addEventHandler(new osgGA::StateSetManipulator( 
     183        viewer.getCamera()->getOrCreateStateSet() 
     184    )); 
     185 
     186    // Set our first non-UI node to be something other than the mask we created our 
     187    // WindowManager with to avoid picking. 
     188    // TODO: Do I need to create a mechanism for doing this automatically, or should 
     189    // that be the responsibility of the users of osgWidget? 
     190    model->setNodeMask(MASK_3D); 
     191 
     192    // Add the WindowManager instance to the 2D camera. This isn't strictly necessary, 
     193    // and you can get some cool results putting the WindowManager directly into a 
     194    // 3D scene. This is not necessary if you use WindowManager::createParentOrthoCamera. 
     195    camera->addChild(wm); 
     196 
     197    // Add our camera and a testing 3D model to the scene. 
     198    group->addChild(camera); 
     199    group->addChild(model); 
     200 
     201    // Here we show how to both run simple strings of code AND run entire files. These 
     202    // assume that you're running the osgwidgetwindow example from the build directory, 
     203    // otherwise you'll need to adjust the file path below in the call to runFile(). 
     204    wm->getLuaEngine()->eval("window = osgwidget.newWindow()"); 
     205    wm->getLuaEngine()->runFile("osgWidget/osgwidgetwindow.lua"); 
     206 
     207    wm->getPythonEngine()->eval("import osgwidget"); 
     208    wm->getPythonEngine()->runFile("osgWidget/osgwidgetwindow.py"); 
     209 
     210    viewer.setUpViewInWindow(0, 0, 1280, 1024); 
     211    viewer.setSceneData(group); 
     212 
     213    /* 
     214    osgViewer::Viewer::Cameras cameras;  
     215    viewer.getCameras(cameras); 
     216    osg::Camera* c = cameras[0]; 
     217    osg::Matrix s = osg::Matrix::scale(1.0f, -1.0f, 1.0f); 
     218    c->setProjectionMatrix(s * c->getProjectionMatrix()); 
     219    */ 
     220 
     221    return viewer.run(); 
    222222}