|
楼主 |
发表于 2013-1-8 20:49:19
|
显示全部楼层
以下为测试代码:- #include <osg/Geometry>
- #include <osg/DisplaySettings>
- #include <osg/MatrixTransform>
- #include <osg/LineWidth>
- #include <osgDB/ReadFile>
- #include <osgViewer/CompositeViewer>
- #include <osgGA/TrackballManipulator>
- // 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.osgt" instead." << std::endl;
- if ( !(scene = osgDB::readNodeFile( std::string( "axes.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() ) );
- double pitch= osg::PI_4;
- double heading = osg::PI_4;
- static double roll = osg::PI_4;
- /**roll递增,用于测试roll的变化,
- *pitch,heading同理可测
- *注意测试pitch时区间限制: (-osg::PI_2, osg::PI_2)开区间
- *heading的限制: [-osg::PI, osg::PI)左闭右开
- */
- roll+=0.01;
- osg::Vec3d foward = osg::Y_AXIS*osg::Matrix::rotate(pitch,osg::X_AXIS);
- foward = foward*osg::Matrix::rotate(heading, osg::Z_AXIS);
- foward.normalize();
- //最后roll变换
- osg::Vec3d up = osg::Z_AXIS*osg::Matrix::rotate(pitch,osg::X_AXIS);
- up = up*osg::Matrix::rotate(heading, osg::Z_AXIS);
- up = up*osg::Matrix::rotate(roll, foward);
- up.normalize();
- osg::Vec3d eye;
- osg::Vec3d center = foward+eye;
- viewer.getView(0)->getCamera()->setViewMatrixAsLookAt(eye,center,up);
- viewer.frame();
- }
- return 0;
- }
复制代码 |
|