root/OpenSceneGraph/trunk/examples/osgthirdpersonview/osgthirdpersonview.cpp @ 13981

Revision 13574, 7.0 kB (checked in by robert, 10 hours ago)

Improved support for controlling the ShadingModel? via the VolumeSettings? object

  • Property svn:eol-style set to native
Line 
1/* OpenSceneGraph example, osgthirdpersonview.
2*
3*  Permission is hereby granted, free of charge, to any person obtaining a copy
4*  of this software and associated documentation files (the "Software"), to deal
5*  in the Software without restriction, including without limitation the rights
6*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7*  copies of the Software, and to permit persons to whom the Software is
8*  furnished to do so, subject to the following conditions:
9*
10*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
16*  THE SOFTWARE.
17*/
18// This code is originally Copyright (c) 2008 Skew Matrix  Software LLC,
19// but you may use the code under the terms of the OSGPL as described above.
20
21// This example demonstrates how CompositeViewer can be used to
22// provide a third person view of another view, including eyepoint and
23// view frustum.
24//
25// The code creates a CompositeViewer with two Views. Each of the two
26// Views has its own window. One View is the typical scene view,
27// showing the loaded model(s).
28//
29// The second View is a third person view showing not just the loaded
30// model(s), but also a wireframe representation of the first View's
31// frustum. Interactions with the first View are reflect5ed in the
32// second View's displayed frustum.
33//
34// Command line arguments are taken to be models for display. If you
35// specify no command line arguments, the code attempts to load cow.osgt.
36
37
38#include <osg/Geometry>
39#include <osg/DisplaySettings>
40#include <osg/MatrixTransform>
41#include <osg/LineWidth>
42#include <osgDB/ReadFile>
43#include <osgViewer/CompositeViewer>
44#include <osgGA/TrackballManipulator>
45
46
47// Given a Camera, create a wireframe representation of its
48// view frustum. Create a default representation if camera==NULL.
49osg::Node*
50makeFrustumFromCamera( osg::Camera* camera )
51{
52    // Projection and ModelView matrices
53    osg::Matrixd proj;
54    osg::Matrixd mv;
55    if (camera)
56    {
57        proj = camera->getProjectionMatrix();
58        mv = camera->getViewMatrix();
59    }
60    else
61    {
62        // Create some kind of reasonable default Projection matrix.
63        proj.makePerspective( 30., 1., 1., 10. );
64        // leave mv as identity
65    }
66
67    // Get near and far from the Projection matrix.
68    const double near = proj(3,2) / (proj(2,2)-1.0);
69    const double far = proj(3,2) / (1.0+proj(2,2));
70
71    // Get the sides of the near plane.
72    const double nLeft = near * (proj(2,0)-1.0) / proj(0,0);
73    const double nRight = near * (1.0+proj(2,0)) / proj(0,0);
74    const double nTop = near * (1.0+proj(2,1)) / proj(1,1);
75    const double nBottom = near * (proj(2,1)-1.0) / proj(1,1);
76
77    // Get the sides of the far plane.
78    const double fLeft = far * (proj(2,0)-1.0) / proj(0,0);
79    const double fRight = far * (1.0+proj(2,0)) / proj(0,0);
80    const double fTop = far * (1.0+proj(2,1)) / proj(1,1);
81    const double fBottom = far * (proj(2,1)-1.0) / proj(1,1);
82
83    // Our vertex array needs only 9 vertices: The origin, and the
84    // eight corners of the near and far planes.
85    osg::Vec3Array* v = new osg::Vec3Array;
86    v->resize( 9 );
87    (*v)[0].set( 0., 0., 0. );
88    (*v)[1].set( nLeft, nBottom, -near );
89    (*v)[2].set( nRight, nBottom, -near );
90    (*v)[3].set( nRight, nTop, -near );
91    (*v)[4].set( nLeft, nTop, -near );
92    (*v)[5].set( fLeft, fBottom, -far );
93    (*v)[6].set( fRight, fBottom, -far );
94    (*v)[7].set( fRight, fTop, -far );
95    (*v)[8].set( fLeft, fTop, -far );
96
97    osg::Geometry* geom = new osg::Geometry;
98    geom->setUseDisplayList( false );
99    geom->setVertexArray( v );
100
101    osg::Vec4Array* c = new osg::Vec4Array;
102    c->push_back( osg::Vec4( 1., 1., 1., 1. ) );
103    geom->setColorArray( c, osg::Array::BIND_OVERALL );
104
105    GLushort idxLines[8] = {
106        0, 5, 0, 6, 0, 7, 0, 8 };
107    GLushort idxLoops0[4] = {
108        1, 2, 3, 4 };
109    GLushort idxLoops1[4] = {
110        5, 6, 7, 8 };
111    geom->addPrimitiveSet( new osg::DrawElementsUShort( osg::PrimitiveSet::LINES, 8, idxLines ) );
112    geom->addPrimitiveSet( new osg::DrawElementsUShort( osg::PrimitiveSet::LINE_LOOP, 4, idxLoops0 ) );
113    geom->addPrimitiveSet( new osg::DrawElementsUShort( osg::PrimitiveSet::LINE_LOOP, 4, idxLoops1 ) );
114
115    osg::Geode* geode = new osg::Geode;
116    geode->addDrawable( geom );
117
118    geode->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
119
120
121    // Create parent MatrixTransform to transform the view volume by
122    // the inverse ModelView matrix.
123    osg::MatrixTransform* mt = new osg::MatrixTransform;
124    mt->setMatrix( osg::Matrixd::inverse( mv ) );
125    mt->addChild( geode );
126
127    return mt;
128}
129
130
131int
132main( int argc,
133      char ** argv )
134{
135    osg::ArgumentParser arguments( &argc, argv );
136
137    osg::ref_ptr< osg::Group > root = new osg::Group;
138
139    // Child 0: We'll replace this every frame with an updated representation
140    //   of the view frustum.
141    root->addChild( makeFrustumFromCamera( NULL ) );
142
143    osg::ref_ptr< osg::Node > scene;
144    scene = osgDB::readNodeFiles( arguments );
145    if (!scene)
146    {
147        // User didn't specify anything, or file(s) didn't exist.
148        // Try to load the cow...
149        osg::notify( osg::WARN ) << arguments.getApplicationName() << ": Could not find specified files. Trying \"cow.osgt\" instead." << std::endl;
150        if ( !(scene = osgDB::readNodeFile( std::string( "cow.osgt" ) ) ) )
151        {
152            osg::notify( osg::FATAL ) << arguments.getApplicationName() << ": No data loaded." << std::endl;
153            return 1;
154        }
155    }
156    root->addChild( scene.get() );
157
158
159    osgViewer::CompositeViewer viewer( arguments );
160    // Turn on FSAA, makes the lines look better.
161    osg::DisplaySettings::instance()->setNumMultiSamples( 4 );
162
163    // Create View 0 -- Just the loaded model.
164    {
165        osgViewer::View* view = new osgViewer::View;
166        viewer.addView( view );
167
168        view->setUpViewInWindow( 10, 10, 640, 480 );
169        view->setSceneData( scene.get() );
170        view->setCameraManipulator( new osgGA::TrackballManipulator );
171    }
172
173    // Create view 1 -- Contains the loaded moel, as well as a wireframe frustum derived from View 0's Camera.
174    {
175        osgViewer::View* view = new osgViewer::View;
176        viewer.addView( view );
177
178        view->setUpViewInWindow( 10, 510, 640, 480 );
179        view->setSceneData( root.get() );
180        view->setCameraManipulator( new osgGA::TrackballManipulator );
181    }
182
183    while (!viewer.done())
184    {
185        // Update the wireframe frustum
186        root->removeChild( 0, 1 );
187        root->insertChild( 0, makeFrustumFromCamera(
188                viewer.getView( 0 )->getCamera() ) );
189
190        viewer.frame();
191    }
192    return 0;
193}
Note: See TracBrowser for help on using the browser.