diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index a9834b99a..9204b92a0 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -24,8 +24,8 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgcamera) ADD_SUBDIRECTORY(osgcatch) ADD_SUBDIRECTORY(osgclip) - ADD_SUBDIRECTORY(osgcopy) ADD_SUBDIRECTORY(osgcompositeviewer) + ADD_SUBDIRECTORY(osgcopy) ADD_SUBDIRECTORY(osgcubemap) ADD_SUBDIRECTORY(osgdelaunay) ADD_SUBDIRECTORY(osgdepthpartition) @@ -36,6 +36,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgfxbrowser) ADD_SUBDIRECTORY(osggeodemo) ADD_SUBDIRECTORY(osggeometry) + ADD_SUBDIRECTORY(osggeometryshaders) ADD_SUBDIRECTORY(osghangglide) ADD_SUBDIRECTORY(osghud) ADD_SUBDIRECTORY(osgimpostor) @@ -71,20 +72,19 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgscribe) ADD_SUBDIRECTORY(osgsequence) ADD_SUBDIRECTORY(osgshaders) - ADD_SUBDIRECTORY(osggeometryshaders) ADD_SUBDIRECTORY(osgshaderterrain) ADD_SUBDIRECTORY(osgshadow) ADD_SUBDIRECTORY(osgshape) + ADD_SUBDIRECTORY(osgsharedarray) ADD_SUBDIRECTORY(osgsimplifier) ADD_SUBDIRECTORY(osgsimulation) - ADD_SUBDIRECTORY(osgterrain) ADD_SUBDIRECTORY(osgslice) ADD_SUBDIRECTORY(osgspacewarp) ADD_SUBDIRECTORY(osgspheresegment) - ADD_SUBDIRECTORY(osgsharedarray) ADD_SUBDIRECTORY(osgspotlight) ADD_SUBDIRECTORY(osgstereoimage) ADD_SUBDIRECTORY(osgteapot) + ADD_SUBDIRECTORY(osgterrain) ADD_SUBDIRECTORY(osgtessellate)#) ADD_SUBDIRECTORY(osgtext) ADD_SUBDIRECTORY(osgtext3D) @@ -92,6 +92,7 @@ IF(DYNAMIC_OPENSCENEGRAPH) ADD_SUBDIRECTORY(osgtexture2D) ADD_SUBDIRECTORY(osgtexture3D) ADD_SUBDIRECTORY(osgtexturerectangle) + ADD_SUBDIRECTORY(osgthirdpersonview) ADD_SUBDIRECTORY(osgunittests) ADD_SUBDIRECTORY(osgvertexprogram) ADD_SUBDIRECTORY(osgvolume) diff --git a/examples/osgthirdpersonview/CMakeLists.txt b/examples/osgthirdpersonview/CMakeLists.txt new file mode 100644 index 000000000..d4ec4e154 --- /dev/null +++ b/examples/osgthirdpersonview/CMakeLists.txt @@ -0,0 +1,6 @@ +#this file is automatically generated + + +SET(TARGET_SRC osgthirdpersonview.cpp ) +#### end var setup ### +SETUP_EXAMPLE(osgthirdpersonview) diff --git a/examples/osgthirdpersonview/osgthirdpersonview.cpp b/examples/osgthirdpersonview/osgthirdpersonview.cpp new file mode 100644 index 000000000..e74148abb --- /dev/null +++ b/examples/osgthirdpersonview/osgthirdpersonview.cpp @@ -0,0 +1,195 @@ +/* OpenSceneGraph example, osgthirdpersonview. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ +// This code is originally Copyright (c) 2008 Skew Matrix Software LLC, +// but you may use the code under the terms of the OSGPL as described above. + +// This example demonstrates how CompositeViewer can be used to +// provide a third person view of another view, including eyepoint and +// view frustum. +// +// The code creates a CompositeViewer with two Views. Each of the two +// Views has its own window. One View is the typical scene view, +// showing the loaded model(s). +// +// The second View is a third person view showing not just the loaded +// model(s), but also a wireframe representation of the first View's +// frustum. Interactions with the first View are reflect5ed in the +// second View's displayed frustum. +// +// Command line arguments are taken to be models for display. If you +// specify no command line arguments, the code attempts to load cow.osg. + + +#include +#include +#include +#include +#include +#include +#include + + +// Given a Camera, create a wireframe representation of its +// view frustum. Create a default representation if camera==NULL. +osg::Node* +makeFrustumFromCamera( osg::Camera* camera ) +{ + // Projection and ModelView matrices + osg::Matrixd proj; + osg::Matrixd mv; + if (camera) + { + proj = camera->getProjectionMatrix(); + mv = camera->getViewMatrix(); + } + else + { + // Create some kind of reasonable default Projection matrix. + proj.makePerspective( 30., 1., 1., 10. ); + // leave mv as identity + } + + // Get near and far from the Projection matrix. + const double near = proj(3,2) / (proj(2,2)-1.0); + const double far = proj(3,2) / (1.0+proj(2,2)); + + // Get the sides of the near plane. + const double nLeft = near * (proj(2,0)-1.0) / proj(0,0); + const double nRight = near * (1.0+proj(2,0)) / proj(0,0); + const double nTop = near * (1.0+proj(2,1)) / proj(1,1); + const double nBottom = near * (proj(2,1)-1.0) / proj(1,1); + + // Get the sides of the far plane. + const double fLeft = far * (proj(2,0)-1.0) / proj(0,0); + const double fRight = far * (1.0+proj(2,0)) / proj(0,0); + const double fTop = far * (1.0+proj(2,1)) / proj(1,1); + const double fBottom = far * (proj(2,1)-1.0) / proj(1,1); + + // Our vertex array needs only 9 vertices: The origin, and the + // eight corners of the near and far planes. + osg::Vec3Array* v = new osg::Vec3Array; + v->resize( 9 ); + (*v)[0].set( 0., 0., 0. ); + (*v)[1].set( nLeft, nBottom, -near ); + (*v)[2].set( nRight, nBottom, -near ); + (*v)[3].set( nRight, nTop, -near ); + (*v)[4].set( nLeft, nTop, -near ); + (*v)[5].set( fLeft, fBottom, -far ); + (*v)[6].set( fRight, fBottom, -far ); + (*v)[7].set( fRight, fTop, -far ); + (*v)[8].set( fLeft, fTop, -far ); + + osg::Geometry* geom = new osg::Geometry; + geom->setUseDisplayList( false ); + geom->setVertexArray( v ); + + osg::Vec4Array* c = new osg::Vec4Array; + c->push_back( osg::Vec4( 1., 1., 1., 1. ) ); + geom->setColorArray( c ); + geom->setColorBinding( osg::Geometry::BIND_OVERALL ); + + GLushort idxLines[8] = { + 0, 5, 0, 6, 0, 7, 0, 8 }; + GLushort idxLoops0[4] = { + 1, 2, 3, 4 }; + GLushort idxLoops1[4] = { + 5, 6, 7, 8 }; + geom->addPrimitiveSet( new osg::DrawElementsUShort( osg::PrimitiveSet::LINES, 8, idxLines ) ); + geom->addPrimitiveSet( new osg::DrawElementsUShort( osg::PrimitiveSet::LINE_LOOP, 4, idxLoops0 ) ); + geom->addPrimitiveSet( new osg::DrawElementsUShort( osg::PrimitiveSet::LINE_LOOP, 4, idxLoops1 ) ); + + osg::Geode* geode = new osg::Geode; + geode->addDrawable( geom ); + + geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED ); + + + // Create parent MatrixTransform to transform the view volume by + // the inverse ModelView matrix. + osg::MatrixTransform* mt = new osg::MatrixTransform; + mt->setMatrix( osg::Matrixd::inverse( mv ) ); + mt->addChild( geode ); + + return mt; +} + + +int +main( int argc, + char ** argv ) +{ + osg::ArgumentParser arguments( &argc, argv ); + + osg::ref_ptr< osg::Group > root = new osg::Group; + + // Child 0: We'll replace this every frame with an updated representation + // of the view frustum. + root->addChild( makeFrustumFromCamera( NULL ) ); + + osg::ref_ptr< osg::Node > scene; + scene = osgDB::readNodeFiles( arguments ); + if (!scene) + { + // User didn't specify anything, or file(s) didn't exist. + // Try to load the cow... + osg::notify( osg::WARN ) << arguments.getApplicationName() << ": Could not find specified files. Trying \"cow.osg\" instead." << std::endl; + if ( !(scene = osgDB::readNodeFile( std::string( "cow.osg" ) ) ) ) + { + osg::notify( osg::FATAL ) << arguments.getApplicationName() << ": No data loaded." << std::endl; + return 1; + } + } + root->addChild( scene.get() ); + + + osgViewer::CompositeViewer viewer( arguments ); + // Turn on FSAA, makes the lines look better. + osg::DisplaySettings::instance()->setNumMultiSamples( 4 ); + + // Create View 0 -- Just the loaded model. + { + osgViewer::View* view = new osgViewer::View; + viewer.addView( view ); + + view->setUpViewInWindow( 10, 10, 640, 480 ); + view->setSceneData( scene.get() ); + view->setCameraManipulator( new osgGA::TrackballManipulator ); + } + + // Create view 1 -- Contains the loaded moel, as well as a wireframe frustum derived from View 0's Camera. + { + osgViewer::View* view = new osgViewer::View; + viewer.addView( view ); + + view->setUpViewInWindow( 10, 510, 640, 480 ); + view->setSceneData( root.get() ); + view->setCameraManipulator( new osgGA::TrackballManipulator ); + } + + while (!viewer.done()) + { + // Update the wireframe frustum + root->removeChild( 0, 1 ); + root->insertChild( 0, makeFrustumFromCamera( + viewer.getView( 0 )->getCamera() ) ); + + viewer.frame(); + } + return 0; +} +