OpenSceneGraph Katia Oleinik: [email protected] based on materials from http://www.openscenegraph.org/
Dec 13, 2015
OpenSceneGraph
Katia Oleinik: [email protected]
based on materials from http://www.openscenegraph.org/
Agenda:• Introduction to OpenSceneGraph• Hardware requirements• Overview of OSG structure• First example – displaying a model• Building primitives• Transformations• Using OpenGL primitives• Texture• Special nodes
Introduction to OpenSceneGraph
OpenSceneGraph
• an open source 3D graphics API (application programming interface)• used for
- visual simulation, - computer games,- scientific visualization, - modeling,- training, etc.
OpenSceneGraph
• written in C++ (encourages object oriented programming);• runs on a number of operating systems, including:
- MS Windows- Max OS X- Linux- IRIX- Solaris- Sony Playstation
uses OpenGL for rendering (allows for high performance graphics);supports the standard template library (STL);
Introduction to OpenSceneGraph
OpenSceneGraph 3.0 Features:
• Support for performance increasing featureso View frustum, small feature and occlusion cullingo Level of detail (LOD)o State sorting and lazy state updatingo OpenGL latest extensionso Multi-threading and database optimization
• Support for OpenGL, from 1.1 through 2.0 including the latest extensions• Support for OpenGL Shading Language• Support for a wide range of 2D image and 3D database formats• Loaders available for OpenFlight, TerraPage, OBJ, 3DS, JPEG, PNG and GeoTIFF• Particle effects• Support for anti-aliased TrueType text• Multi-threaded and configurable support for multiple CPU/multiple GPU machines
Introduction to OpenSceneGraph
OpenSceneGraph 3.0 latest updates:
• Support for Windows MS Visual Studio• Support for Android on tablets and phones• Support for IOS (iPhone OS) on tablets and phones• Improvements to osgVolume class enabling high quality volume rendering
Introduction to OpenSceneGraph
FightGear Flight Simulator
FightGear Flight Simulator
FightGear Flight Simulator
Hardware requirements
Processor• OSG runs on most contemporary CPUs. • OSG is thread-safe and can take advantage of multi-processor and
dual core architectures. • OSG runs on both 32- and 64-bit processors.
Graphics• OSG requires graphics hardware with robust OpenGL support• 256 MB of graphics RAM – good starting point
RAM• 1GB – good enough for many application, but you might need more,
depending on your datasetDisc
• Depends on your data requirements
Overview of OSG structure
Matrix
Matrix
Overview of OSG structure
Root
Transformation
Geode
Drawable
Transformation
Geode
Drawable
Geode
Drawable
First example – displaying a model
• ex_simple_viewer.cpp
// load the nodes from the command line arguments.
osg::Node* model = osgDB::readNodeFile(argv[1]);
// initialize the viewer and set the scene to render
osgViewer::Viewer viewer;viewer.setSceneData(model);
// run viewer
return viewer.run();
Root Node
First example – displaying a model
• ex_simple_viewer.cpp: compiling, linking and running
To compile and link% make ex_simple_viewer
To run the viewer% ex_simple_viewer cow.obj
First button – rotate the modelSecond button – translateThird button – scale
Press “q” (“Esc” for Windows) button to exit
First example – displaying a model
• ex_viewer_args.cpp
// call argument parser
osg::ArgumentParser arguments (&argc, argv);std::string filename;
// define the argument line option
arguments.read("--model", filename);
// load the nodes from the command line arguments
osg::Node* model = osgDB::readNodeFile(filename);
First example – displaying a model
• ex_viewer_args.cpp: running
To compile and link% make ex_viewer_args
To run the viewer% ex_viewer_args –-model cow.obj
Try a few different models:dumptruck.osgteapot.osg
First example – displaying a model
• Input OSG model file structureGeode { name "teapot.osg" nodeMask 0xffffffff cullingActive TRUE num_drawables 1 Geometry { DataVariance STATIC useDisplayList FALSE useVertexBufferObjects TRUE PrimitiveSets 1 { DrawArrays TRIANGLES 0 9744 }
VertexArray Vec3Array 9744 { 0.367875 -0 0.237053 0.375 -0 0.225 0.365248 0.086895 0.225
..... } ColorBinding OVERALL ColorArray Vec4Array 1 { 1 1 1 1 } }}
Building geometric primitives
• ex_simple_cone.cpp
// Create a vector to represent the "center of the cone"Vec3 vcen(xcen, ycen, zcen);osg::Cone* cone = new Cone(vcen, radius, height);
// Create a drawable object based on the coneosg::ShapeDrawable *drawable = new ShapeDrawable(cone);
// create a new geode (root node)
osg::Geode* geode = new Geode();geode->addDrawable(drawable);
Root Node
Geode
Drawable
cone
Building geometric primitives
• Improving ex_simple_cone.cpp
// Create a vector to represent the "center of the cone"osg:: Vec3 vcen(xcen, ycen, zcen);osg::Cone* cone = new Cone(vcen, radius, height);
// Create a drawable object based on the coneosg:: ShapeDrawable *drawable = new ShapeDrawable(cone);drawable->setColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
// create a new geode osg:: Geode* geode = new Geode();geode->addDrawable(drawable);
// create a root nodeosg::Group *root = new osg::Group();root->addChild(geode);
Root Node
Geode
Drawable
cone
Building geometric primitives
To compile and link% make ex_simple_cone
To run the viewer% ex_simple_cone
• ex_simple_cone.cpp
Building geometric primitives
OSG comes with a number of primitives
Box Sphere Cone Cylinder Capsule Special shapes (e.g. InfinitePlane)
• ex_simple_cone.cpp
Matrix
Matrix
Building geometric primitives• ex_arrow.cpp
// Create a cone and a cylinderGeode *make_cone( float xcen, …){}Geode *make_cylinder( float xcen, …){}
// create an arrow, as a transform node MatrixTransform* arrow = new MatrixTransform;arrow->setMatrix(Matrix::scale(1.0, 1.0, 1.0));arrow->addChild(cone); arrow->addChild(cylinder);
// add the arrow to the upper transformMatrixTransform* mt = new MatrixTransform();mt->setMatrix( Matrix::rotate(inDegrees(30.0), 1.0, 0.0, 0.0));mt->addChild(arrow);
// create a root nodeosg::Group *root = new osg::Group();root->addChild(mt);
Root Node
cone
cylinder
Transform
Transform
Building geometric primitives• Exercise Building 3 arrows
Matrix
Root Node
Transform
Matrix
cone
cylinder
TransformMatrix
cone
cylinder
TransformMatrix
cone
cylinder
Transform
Building geometric primitives• Exercise: Building 3 arrows
Group *make_vec_arrow(float shaft_radius, float total_length, float r, float g, float b)
{ float cone_radius = 2*shaft_radius; float cone_height = cone_radius; float shaft_length = total_length - cone_height; osg::Geode *cylinder = make_cylinder(0.0, 0.0, shaft_length/2.0, shaft_radius, shaft_length, r,g,b,1.0); osg::Geode *cone = make_cone(0.0, 0.0, shaft_length + cone_height/4.0, cone_radius, cone_height, r, g, b, 1.0); osg::Group* vec_arrow = new Group; vec_arrow->addChild(cylinder); vec_arrow->addChild(cone);
return vec_arrow;}
osg::Group *red_arrow = make_vec_arrow(…);osg::MatrixTransform* xaxis = new MatrixTransform;xaxis->addChild(red_arrow);xaxis->setMatrix(…);
Building geometric primitives• Reusing the geometry
Matrix
Root Node
Transform
MatrixTransform
MatrixTransform
MatrixTransform
Geode 3Geode 2Geode 1
GeometryVertices
FacesColors
Using OpenGL primitives• PrimitiveSet Class
21
4
30
Points2
1 4
3
Lines
4
32
10LineStrip
4
32
10LineLoop
Polygon
0 1
2
3
4
Triangles0 1
2
Quads
3
0
2
1
0 2 4
1 3 5
TriangleStrip
13
5 7
0 2 46
QuadStrip
0
1 2
3
4
56
TriangleFan
Using OpenGL primitives• PrimitiveSet Class
Group
Geode
Geometry
Vertices Faces Colors Texture
osg::Group *root = new osg::Group();
…
osg::Geode* primGeode = new osg::Geode();root->addChild(primGeode);
…
osg::Geometry* primGeom = new osg::Geometry();primGeode->addDrawable(primGeom);
…
viewer.setSceneData(root)
Using OpenGL primitives• PrimitiveSet Class
osg::Vec3Array* pyramidVertices = new osg::Vec3Array;pyramidVertices->push_back( osg::Vec3( 0, 0, 0) ); // front left pyramidVertices->push_back( osg::Vec3(10, 0, 0) ); // front right pyramidVertices->push_back( osg::Vec3(10,10, 0) ); // back right pyramidVertices->push_back( osg::Vec3( 0,10, 0) ); // back left pyramidVertices->push_back( osg::Vec3( 5, 5,10) ); // peak
// create primitives: quad for the baseosg::DrawElementsUInt* pyramidBase = new osg::DrawElementsUInt(osg::PrimitiveSet::QUADS, 0);pyramidBase->push_back(3);pyramidBase->push_back(2);pyramidBase->push_back(1);pyramidBase->push_back(0);
// create primitives: triangles for the sides osg::DrawElementsUInt* pyramidFaceOne = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, 0);pyramidFaceOne->push_back(0);pyramidFaceOne->push_back(1);pyramidFaceOne->push_back(4);
Using OpenGL primitives• PrimitiveSet Class
// assign all primitives to the Geometry nodeosg::Geometry* pyramidGeometry = new osg::Geometry();pyramidGeometry->setVertexArray( pyramidVertices );pyramidGeometry->addPrimitiveSet(pyramidBase);pyramidGeometry->addPrimitiveSet(pyramidFaceOne);pyramidGeometry->addPrimitiveSet(pyramidFaceTwo);pyramidGeometry->addPrimitiveSet(pyramidFaceThree);pyramidGeometry->addPrimitiveSet(pyramidFaceFour);
// create a geode and add the geometry to the geodeosg::Geode* pyramidGeode = new osg::Geode();pyramidGeode->addDrawable(pyramidGeometry);
// Create a root node and add the geodeosg::Group* root = new osg::Group();root->addChild(pyramidGeode);
Root Node
Geode
geometry
Using OpenGL primitives• PrimitiveSet Class
// create an array of colorsosg::Vec4Array* colors = new osg::Vec4Array;colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); //index 0 redcolors->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f) ); //index 1 greencolors->push_back(osg::Vec4(0.0f, 0.0f, 1.0f, 1.0f) ); //index 2 bluecolors->push_back(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f) ); //index 3 white
// create an index arrayosg::TemplateIndexArray <unsigned int, osg::Array::UIntArrayType,4,4> *colorIndexArray;colorIndexArray = new osg::TemplateIndexArray<unsigned int, osg::Array::UIntArrayType,4,4>;colorIndexArray->push_back(0); // vertex 0 assigned color array element 0colorIndexArray->push_back(1); // vertex 1 assigned color array element 1colorIndexArray->push_back(2); // vertex 2 assigned color array element 2colorIndexArray->push_back(3); // vertex 3 assigned color array element 3colorIndexArray->push_back(0); // vertex 4 assigned color array element 0
// assign the arrays to the geometrypyramidGeometry->setColorArray(colors);pyramidGeometry->setColorIndices(colorIndexArray);pyramidGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
Transformations
OSG allows for hierarchies of transformation node. Such structure makes it much easier to control the motions of each limb, part or the whole body.
transform
transform transform
transform
geode
geodegeode
transform
transform
transform
transform
geode
geode
geode
geode geode
Transformations
OSG MatrixTransform Class:
// direct transformation specificationtransform->getMatrix();transform->setMatrix();
// set identityIdentity();
// navigationosg::Matrix mt1 = osg::Matrix::Translate(x, y, z);osg::Matrix mt2 = osg::Matrix::Rotate(angle, x, y, z);osg::Matrix mt3 = osg::Matrix:: Scale(x, y, z);
// for multiplying matricesosg::Matrix resultMat = mt1 * t2 * mt3;
// invert matrixosg::Matrix::Invert();
AddingTexture
// initialize texture classosg::Texture2D* texture = new osg::Texture2D;texture->setDataVariance(osg::Object::DYNAMIC);
// load the texture image from the file: osg::Image* texImage = osgDB::readImageFile(texture_file);if (! texImage){ std::cout << " couldn't find texture, quiting." << std::endl; return -1;}
// Assign the texture to the image we read from file: texture->setImage(texImage);
// Create a new StateSet with default settings: osg::StateSet* stateTex = new osg::StateSet();
// Assign texture unit 0 of our new StateSet to the texture // enable the texture.stateTex->setTextureAttributeAndModes(0,texture,osg::StateAttribute::ON);
// Associate this state set with the Geode that contains// the primitive: geode->setStateSet(stateTex);
Any file format supported by the plugins
AddingTexture
// Add parsing texture option from a command line
// call argument parserosg::ArgumentParser arguments (&argc, argv);std::string filename;
// define the argument line optionarguments.read("--texture", texfilename);
osg::Texture2D* texture = new osg::Texture2D;texture->setDataVariance(osg::Object::DYNAMIC);
// load the texture image from the file: osg::Image* texImage = osgDB::readImageFile(texture_file);if (! texImage){ std::cout << " couldn't find texture, quiting." << std::endl; return -1;}…
• Exercise: Reading texture from the command line
Special Nodes
Switch node - Node for switching between different states of an object
LOD node - Rendering Optimization node
Billboard node – rendering optimization node
Text node – node for presenting text on the screen
Special Nodes
LOD (“level of detail” node - Rendering Optimization node
This node “switches” based on the distance from the viewer to the object.
It works like a regular group node: load.addChild(detailedNode);
Set the visible range from the viewer to the object:load.setRange(childNumber, near, far);
Special Nodes
LOD lod = new LOD();
Lod.addChild(detailedNode);Lod.setRange(0, 0, 10);
Lod.addChild(NotSodetailedNode);Lod.setRange(1, 10, 100);
Lod.addChild(CorseNode);Lod.setRange(2, 100, 1000);
Lod.addChild(NoDetailNode);Lod.setRange(2,1000,10000);
For up-to-date information on the project, in-depth details on how to compile and run libraries and examples, see the documentation on the OpenSceneGraph website: http://www.openscenegraph.org For support subscribe to OSG public mailing list: http://www.openscenegraph.org/projects/osg/wiki/MailingLists
or forum: http://forum.openscenegraph.org
Contact me: Katia Oleinik: [email protected]
Tutorial presentations and examples online:www.bu.edu/tech/research/training/presentations/list/
Online evaluation:http://scv.bu.edu/survey/tutorial_evaluation.html
Autodesk Maya
Resources
• BU Scientific Computing and Visualization:
http://www.bu.edu/tech/research/scv/
• OpenSceneGraph: http://www.openscenegraph.org/