diff --git a/examples/osgkeyboardmouse/GNUmakefile b/examples/osgkeyboardmouse/GNUmakefile new file mode 100644 index 000000000..41876cd8b --- /dev/null +++ b/examples/osgkeyboardmouse/GNUmakefile @@ -0,0 +1,27 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgkeyboardmouse.cpp\ + +LIBS += -lProducer -losgFX -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) -lOpenThreads + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgkeyboardmouse + +INC += $(X_INC) +LDFLAGS += -L/usr/X11R6/lib + + +ifeq ($(USE_OPEN_THREAD),1) + DEF += -D_USE_OPEN_THREAD + INC += $(INC_OPEN_THREAD) + LDFLAGS += $(LIB_OPEN_THREAD) + LIBS += -lOpenThread +endif + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgkeyboardmouse/GNUmakefile.inst b/examples/osgkeyboardmouse/GNUmakefile.inst new file mode 100644 index 000000000..9a2e627f9 --- /dev/null +++ b/examples/osgkeyboardmouse/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgkeyboardmouse.cpp\ + +LIBS += -lProducer -losgFX -losgDB --losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgkeyboardmouse + +INC += $(PRODUCER_INCLUDE_DIR) $(X_INC) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgkeyboardmouse/osgkeyboardmouse.cpp b/examples/osgkeyboardmouse/osgkeyboardmouse.cpp new file mode 100644 index 000000000..6bd172cea --- /dev/null +++ b/examples/osgkeyboardmouse/osgkeyboardmouse.cpp @@ -0,0 +1,276 @@ +// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL. +// +// Simple example of use of Producer::RenderSurface + KeyboardMouseCallback + SceneView +// example that provides the user with control over view position with basic picking. + +#include +#include +#include + +#include + +#include +#include + +#include + +#include + + +class MyKeyboardMouseCallback : public Producer::KeyboardMouseCallback +{ +public: + + MyKeyboardMouseCallback(osgUtil::SceneView* sceneView) : + Producer::KeyboardMouseCallback(), + _mx(0.0f),_my(0.0f),_mbutton(0), + _done(false), + _trackBall(new Producer::Trackball), + _sceneView(sceneView) + { + resetTrackball(); + _mouseMovingOnPreviousRelease = false; + } + + virtual void specialKeyPress( Producer::KeyCharacter key ) + { + if (key==Producer::KeyChar_Escape) + shutdown(); + } + + virtual void shutdown() + { + _done = true; + } + + virtual void keyPress( Producer::KeyCharacter key) + { + if (key==' ') resetTrackball(); + } + + virtual void mouseMotion( float mx, float my ) + { + _mx = mx; + _my = my; + } + + virtual void buttonPress( float mx, float my, unsigned int mbutton ) + { + _mx = mx; + _my = my; + _mbutton |= (1<<(mbutton-1)); + + _mx_buttonPress = _mx; + _my_buttonPress = _my; + } + virtual void buttonRelease( float mx, float my, unsigned int mbutton ) + { + _mx = mx; + _my = my; + _mbutton &= ~(1<<(mbutton-1)); + + if (_mx==_mx_buttonPress && _my_buttonPress==_my) + { + if (!_mouseMovingOnPreviousRelease) + { + // button press and release without moving so assume this means + // the users wants to pick. + pick(_mx,_my); + } + _mouseMovingOnPreviousRelease = false; + } + else + { + _mouseMovingOnPreviousRelease = true; + } + } + + bool done() { return _done; } + float mx() { return _mx; } + float my() { return _my; } + unsigned int mbutton() { return _mbutton; } + + void resetTrackball() + { + osg::Node* scene = _sceneView->getSceneData(); + if (scene) + { + const osg::BoundingSphere& bs = scene->getBound(); + _trackBall->reset(); + _trackBall->setOrientation( Producer::Trackball::Z_UP ); + _trackBall->setDistance(bs.radius()*2.0f); + _trackBall->translate(-bs.center().x(),-bs.center().y(),-bs.center().z()); + } + } + + osg::Matrixd getViewMatrix() + { + _trackBall->input( mx(), my(), mbutton() ); + return osg::Matrixd(_trackBall->getMatrix().ptr()); + } + + void pick(float x, float y) + { + osg::Node* scene = _sceneView->getSceneData(); + if (scene) + { + std::cout<<"Picking "<getViewport(origX,origY,width,height); + + // convert Produce's non dimensional x,y coords back into pixel coords. + int winX = (int)((x+1.0f)*0.5f*(float)width); + int winY = (int)((y+1.0f)*0.5f*(float)height); + + osg::Vec3 nearPoint, farPoint; + _sceneView->projectWindowXYIntoObject(winX,winY,nearPoint,farPoint); + + std::cout<<"nearPoint "< lineSegment = new osg::LineSegment(nearPoint,farPoint); + + // create the IntersectVisitor to do the line intersection traversals. + osgUtil::IntersectVisitor intersector; + intersector.addLineSegment(lineSegment.get()); + + scene->accept(intersector); + + osgUtil::IntersectVisitor::HitList& hits=intersector.getHitList(lineSegment.get()); + if (!hits.empty()) + { + std::cout<<"Got hits"<=1)?nodePath[nodePath.size()-1]:0; + osg::Group* parent = (nodePath.size()>=2)?dynamic_cast(nodePath[nodePath.size()-2]):0; + + if (parent && node) + { + + std::cout<<"Hits "<className()<className()<(parent); + if (!parentAsScribe) + { + // node not already picked, so highlight it with an osgFX::Scribe + osgFX::Scribe* scribe = new osgFX::Scribe(); + scribe->addChild(node); + parent->replaceChild(node,scribe); + } + else + { + // node already picked so we want to remove scribe to unpick it. + osg::Node::ParentList parentList = parentAsScribe->getParents(); + for(osg::Node::ParentList::iterator itr=parentList.begin(); + itr!=parentList.end(); + ++itr) + { + (*itr)->replaceChild(parentAsScribe,node); + } + } + } + + } + + } + + } + +private: + + float _mx, _my; + float _mx_buttonPress, _my_buttonPress; + unsigned int _mbutton; + bool _mouseMovingOnPreviousRelease; + + bool _done; + + osg::ref_ptr _trackBall; + osg::ref_ptr _sceneView; +}; + +int main( int argc, char **argv ) +{ + if (argc<2) + { + std::cout << argv[0] <<": requires filename argument." << std::endl; + return 1; + } + + // load the scene. + osg::ref_ptr loadedModel = osgDB::readNodeFile(argv[1]); + if (!loadedModel) + { + std::cout << argv[0] <<": No data loaded." << std::endl; + return 1; + } + + // create the window to draw to. + osg::ref_ptr renderSurface = new Producer::RenderSurface; + renderSurface->setWindowName("osgsimple"); + renderSurface->setWindowRectangle(100,100,800,600); + renderSurface->useBorder(true); + renderSurface->realize(); + + + // create the view of the scene. + osg::ref_ptr sceneView = new osgUtil::SceneView; + sceneView->setDefaults(); + sceneView->setSceneData(loadedModel.get()); + + + // set up a KeyboardMouse to manage the events comming in from the RenderSurface + osg::ref_ptr kbm = new Producer::KeyboardMouse(renderSurface.get()); + + // create a KeyboardMouseCallback to handle the mouse events within this applications + osg::ref_ptr kbmcb = new MyKeyboardMouseCallback(sceneView.get()); + + + // record the timer tick at the start of rendering. + osg::Timer_t start_tick = osg::Timer::instance()->tick(); + + unsigned int frameNum = 0; + + // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) + while( renderSurface->isRealized() && !kbmcb->done()) + { + // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly + osg::FrameStamp* frameStamp = new osg::FrameStamp; + frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); + frameStamp->setFrameNumber(frameNum++); + + // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp + sceneView->setFrameStamp(frameStamp); + + // pass any keyboard mouse events onto the local keyboard mouse callback. + kbm->update( *kbmcb ); + + // set the view + sceneView->setViewMatrix(kbmcb->getViewMatrix()); + + // update the viewport dimensions, incase the window has been resized. + sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight()); + + // do the update traversal the scene graph - such as updating animations + sceneView->update(); + + // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins + sceneView->cull(); + + // draw the rendering bins. + sceneView->draw(); + + // Swap Buffers + renderSurface->swapBuffers(); + } + + return 0; +} + diff --git a/examples/osgsimple/GNUmakefile b/examples/osgsimple/GNUmakefile new file mode 100644 index 000000000..9b3180b6e --- /dev/null +++ b/examples/osgsimple/GNUmakefile @@ -0,0 +1,27 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgsimple.cpp\ + +LIBS += -lProducer -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) -lOpenThreads + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgsimple + +INC += $(X_INC) +LDFLAGS += -L/usr/X11R6/lib + + +ifeq ($(USE_OPEN_THREAD),1) + DEF += -D_USE_OPEN_THREAD + INC += $(INC_OPEN_THREAD) + LDFLAGS += $(LIB_OPEN_THREAD) + LIBS += -lOpenThread +endif + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgsimple/GNUmakefile.inst b/examples/osgsimple/GNUmakefile.inst new file mode 100644 index 000000000..84ff36512 --- /dev/null +++ b/examples/osgsimple/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgsimple.cpp\ + +LIBS += -lProducer -losgDB --losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgsimple + +INC += $(PRODUCER_INCLUDE_DIR) $(X_INC) +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgsimple/osgsimple.cpp b/examples/osgsimple/osgsimple.cpp new file mode 100644 index 000000000..a27373869 --- /dev/null +++ b/examples/osgsimple/osgsimple.cpp @@ -0,0 +1,82 @@ +// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL. +// +// Simple example of use of Producer::RenderSurface to create an OpenGL +// graphics window, and OSG for rendering. + +#include +#include +#include +#include + + +int main( int argc, char **argv ) +{ + if (argc<2) + { + std::cout << argv[0] <<": requires filename argument." << std::endl; + return 1; + } + + // load the scene. + osg::ref_ptr loadedModel = osgDB::readNodeFile(argv[1]); + if (!loadedModel) + { + std::cout << argv[0] <<": No data loaded." << std::endl; + return 1; + } + + // create the window to draw to. + osg::ref_ptr renderSurface = new Producer::RenderSurface; + renderSurface->setWindowName("osgsimple"); + renderSurface->setWindowRectangle(100,100,800,600); + renderSurface->useBorder(true); + renderSurface->realize(); + + // create the view of the scene. + osg::ref_ptr sceneView = new osgUtil::SceneView; + sceneView->setDefaults(); + sceneView->setSceneData(loadedModel.get()); + + // initialize the view to look at the center of the scene graph + const osg::BoundingSphere& bs = loadedModel->getBound(); + osg::Matrix viewMatrix; + viewMatrix.makeLookAt(bs.center()-osg::Vec3(0.0,2.0f*bs.radius(),0.0),bs.center(),osg::Vec3(0.0f,0.0f,1.0f)); + + // record the timer tick at the start of rendering. + osg::Timer_t start_tick = osg::Timer::instance()->tick(); + + unsigned int frameNum = 0; + + // main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.) + while( renderSurface->isRealized() ) + { + // set up the frame stamp for current frame to record the current time and frame number so that animtion code can advance correctly + osg::FrameStamp* frameStamp = new osg::FrameStamp; + frameStamp->setReferenceTime(osg::Timer::instance()->delta_s(start_tick,osg::Timer::instance()->tick())); + frameStamp->setFrameNumber(frameNum++); + + // pass frame stamp to the SceneView so that the update, cull and draw traversals all use the same FrameStamp + sceneView->setFrameStamp(frameStamp); + + // update the viewport dimensions, incase the window has been resized. + sceneView->setViewport(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight()); + + // set the view + sceneView->setViewMatrix(viewMatrix); + + // do the update traversal the scene graph - such as updating animations + sceneView->update(); + + // do the cull traversal, collect all objects in the view frustum into a sorted set of rendering bins + sceneView->cull(); + + // draw the rendering bins. + sceneView->draw(); + + // Swap Buffers + renderSurface->swapBuffers(); + } + + return 0; +} +