diff --git a/Make/makedirdefs b/Make/makedirdefs index 07020264a..759dc71fb 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -135,7 +135,6 @@ EXAMPLE_DIRS = \ osgshadowtexture\ osgshape\ osgstereoimage\ - osgstereoimage\ osgteapot\ osgtext\ osgtexture1D\ @@ -148,7 +147,8 @@ EXAMPLE_DIRS = \ osgvertexprogram\ osgviewer\ osgprerendercubemap\ - + osgslideshow\ + # osgsimulation\ # osgdemeter\ # osgjigsaw\ diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 93adabb15..7ffd27dd9 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -421,10 +421,6 @@ SOURCE=..\..\src\osg\Transform.cpp # End Source File # Begin Source File -SOURCE=..\..\src\osg\TransformAttributeFunctor.cpp -# End Source File -# Begin Source File - SOURCE=..\..\src\osg\BlendFunc.cpp # End Source File # Begin Source File @@ -841,11 +837,6 @@ SOURCE=..\..\Include\Osg\Transform # End Source File # Begin Source File -SOURCE=..\..\Include\Osg\TransformAttributeFunctor -# End Source File -# Begin Source File - - SOURCE=..\..\Include\Osg\TriangleFunctor # End Source File # Begin Source File diff --git a/VisualStudio/osgPlugins/osg/dot_osg.dsp b/VisualStudio/osgPlugins/osg/dot_osg.dsp index 8d8d1bb03..d3d2b614c 100755 --- a/VisualStudio/osgPlugins/osg/dot_osg.dsp +++ b/VisualStudio/osgPlugins/osg/dot_osg.dsp @@ -270,6 +270,10 @@ SOURCE=..\..\..\src\osgPlugins\osg\Switch.cpp # End Source File # Begin Source File +SOURCE=..\..\..\src\osgPlugins\osg\TessellationHints.cpp +# End Source File +# Begin Source File + SOURCE=..\..\..\src\osgPlugins\osg\TexEnv.cpp # End Source File # Begin Source File diff --git a/VisualStudio/osgUtil/osgUtil.dsp b/VisualStudio/osgUtil/osgUtil.dsp index 1fd1a09df..55eb196f8 100755 --- a/VisualStudio/osgUtil/osgUtil.dsp +++ b/VisualStudio/osgUtil/osgUtil.dsp @@ -177,6 +177,10 @@ SOURCE=..\..\src\osgUtil\TransformCallback.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osgUtil\TransformAttributeFunctor.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osgUtil\TriStripVisitor.cpp # End Source File # Begin Source File @@ -285,6 +289,10 @@ SOURCE=..\..\include\osgUtil\TransformCallback # End Source File # Begin Source File +SOURCE=..\..\include\osgUtil\TransformAttributeFunctor +# End Source File +# Begin Source File + SOURCE=..\..\include\osgUtil\TriStripVisitor # End Source File # Begin Source File diff --git a/examples/osgdemeter/GNUmakefile b/examples/osgdemeter/GNUmakefile new file mode 100644 index 000000000..c891faeb9 --- /dev/null +++ b/examples/osgdemeter/GNUmakefile @@ -0,0 +1,19 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgdemeter.cpp\ + +LIBS += -lDemeterOSG -lDemeter -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgdemeter + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgdemeter/GNUmakefile.inst b/examples/osgdemeter/GNUmakefile.inst new file mode 100644 index 000000000..fe676374b --- /dev/null +++ b/examples/osgdemeter/GNUmakefile.inst @@ -0,0 +1,14 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + osgviewer.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgviewer + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgdemeter/osgdemeter.cpp b/examples/osgdemeter/osgdemeter.cpp new file mode 100644 index 000000000..ef203a687 --- /dev/null +++ b/examples/osgdemeter/osgdemeter.cpp @@ -0,0 +1,205 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial applications, + * as long as this copyright notice is maintained. + * + * This application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#include +#include +#include +#include + +#include +#include +#include + +Demeter::Terrain* loadTerrain() +{ + +#ifdef _WIN32 + char fileSeparator = '\\'; +#else + char fileSeparator = '/'; +#endif + char szMediaPath[17]; + sprintf(szMediaPath,"..%cdata%cLlano",fileSeparator,fileSeparator); + Demeter::Settings::GetInstance()->SetMediaPath(szMediaPath); + + // Load a terrain that was generated in the Demeter Texture Editor + Demeter::Terrain* pTerrain = new Demeter::Terrain(); + try + { +#ifdef _DEBUG + Demeter::Loader::GetInstance()->LoadElevations("DemeterElevationLoaderDebug","Llano.terrain",pTerrain); + Demeter::Loader::GetInstance()->LoadTerrainTexture("DemeterTextureLoaderDebug","Llano.terrain",pTerrain); +#else + Demeter::Loader::GetInstance()->LoadElevations("DemeterElevationLoader","Llano.terrain",pTerrain); + Demeter::Loader::GetInstance()->LoadTerrainTexture("DemeterTextureLoader","Llano.terrain",pTerrain); +#endif + } + catch(Demeter::DemeterException* pEx) + { + std::cerr<GetErrorMessage()<SetTerrain(pTerrain); + + osg::Geode* pGeode = new osg::Geode; + pGeode->addDrawable(pDrawable); + + float detailThreshold = 9.0f; + pTerrain->SetDetailThreshold(detailThreshold); + + return pGeode; +} + +class KeyboardEventHandler : public osgGA::GUIEventHandler +{ +public: + + KeyboardEventHandler(Demeter::Terrain* pTerrain): + _pTerrain(pTerrain) {} + + virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&) + { + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYDOWN): + { + if (ea.getKey()=='n') + { + _pTerrain->SetDetailThreshold(_pTerrain->GetDetailThreshold()+0.1f); + std::cout << "_pTerrain->GetDetailThreshold() = "<<_pTerrain->GetDetailThreshold() << std::endl; + return true; + } + else if (ea.getKey()=='n') + { + _pTerrain->SetDetailThreshold(_pTerrain->GetDetailThreshold()-0.1f); + std::cout << "_pTerrain->GetDetailThreshold() = "<<_pTerrain->GetDetailThreshold() << std::endl; + return true; + } + break; + } + default: + break; + } + return false; + } + + virtual void accept(osgGA::GUIEventHandlerVisitor& v) + { + v.visit(*this); + } + + Demeter::Terrain* _pTerrain; + +}; + + +int main( int argc, char **argv ) +{ + + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + + // construct the viewer. + osgProducer::Viewer viewer(arguments); + + // set up the value with sensible default event handlers. + viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + + // get details on keyboard and mouse bindings used by the viewer. + viewer.getUsage(*arguments.getApplicationUsage()); + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } +// +// if (arguments.argc()<=1) +// { +// arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); +// return 1; +// } + + osg::Timer timer; + osg::Timer_t start_tick = timer.tick(); + + + Demeter::Terrain* pTerrain = loadTerrain(); + + // read the scene from the list of file specified commandline args. + osg::ref_ptr loadedModel = createSceneWithTerrain(pTerrain); + + + // if no model has been successfully loaded report failure. + if (!loadedModel) + { + std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; + return 1; + } + + osg::Timer_t end_tick = timer.tick(); + + std::cout << "Time to load = "< +#include +#include + +#include + +class KeyboardEventHandler : public osgGA::GUIEventHandler +{ +public: + + KeyboardEventHandler(osg::StateSet* stateset): + _stateset(stateset) + { + _point = new osg::Point; + _point->setDistanceAttenuation(osg::Vec3(0.0,0.0005,0.0f)); + _point->setDistanceAttenuation(osg::Vec3(0.0,0.0000,0.000005f)); + _stateset->setAttribute(_point.get()); + } + + virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&) + { + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYDOWN): + { + if (ea.getKey()=='+' || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Add) + { + changePointSize(1.0f); + return true; + } + else if (ea.getKey()=='-' || ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Subtract) + { + changePointSize(-1.0f); + return true; + } + break; + } + default: + break; + } + return false; + } + + virtual void accept(osgGA::GUIEventHandlerVisitor& v) + { + v.visit(*this); + } + + + float getPointSize() const + { + return _point->getSize(); + } + + void setPointSize(float psize) + { + if (psize>0.0) + { + _point->setSize(psize); + } + std::cout<<"Point size "< _stateset; + osg::ref_ptr _point; + +}; + +int main( int argc, char **argv ) +{ + + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + + // construct the viewer. + osgProducer::Viewer viewer(arguments); + + // set up the value with sensible default event handlers. + viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + + // get details on keyboard and mouse bindings used by the viewer. + viewer.getUsage(*arguments.getApplicationUsage()); + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + if (arguments.argc()<=1) + { + arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); + return 1; + } + + osg::Timer timer; + osg::Timer_t start_tick = timer.tick(); + + // read the scene from the list of file specified commandline args. + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + + // if no model has been successfully loaded report failure. + if (!loadedModel) + { + std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; + return 1; + } + + osg::Timer_t end_tick = timer.tick(); + + std::cout << "Time to load = "< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + + +//#define UPDATE_ONE_IMAGE_PER_FRAME 1 + + +class PrerenderAppCallback : public osg::NodeCallback +{ + public: + + PrerenderAppCallback(osg::Node* subgraph): + _subgraph(subgraph) {} + + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { + // traverse the subgraph to update any nodes. + if (_subgraph.valid()) _subgraph->accept(*nv); + + // must traverse the Node's subgraph + traverse(node,nv); + } + + osg::ref_ptr _subgraph; +}; + + +class PrerenderCullCallback : public osg::NodeCallback +{ + public: + + PrerenderCullCallback(osg::Node* subgraph, osg::TextureCubeMap* cubemap, osg::TexMat* texmat): + _subgraph(subgraph), + _cubemap(cubemap), + _texmat(texmat) + { + _updateCubemapFace = 0; + _clearColor = osg::Vec4(1,1,1,1); + _localState[0] = new osg::StateSet; + _localState[1] = new osg::StateSet; + _localState[2] = new osg::StateSet; + _localState[3] = new osg::StateSet; + _localState[4] = new osg::StateSet; + _localState[5] = new osg::StateSet; + } + + virtual void operator()(osg::Node* node, osg::NodeVisitor* nv) + { + osgUtil::CullVisitor* cv = dynamic_cast(nv); + if (cv && _cubemap.valid() && _subgraph.valid()) + { + const osg::Vec4 clearColArray[] = + { + osg::Vec4(0, 0, 1, 1), // +X + osg::Vec4(1, 0.7f, 0, 1), // -X + osg::Vec4(0, 1, 1, 1), // +Y + osg::Vec4(1, 1, 0, 1), // -Y + osg::Vec4(1, 0, 0, 1), // +Z + osg::Vec4(0, 1, 0, 1) // -Z + }; + + osg::Quat q; + q.set(cv->getModelViewMatrix()); + const osg::Matrix C = osg::Matrix::rotate( q.inverse() ); + _texmat->setMatrix(C); + +#if UPDATE_ONE_IMAGE_PER_FRAME + if ((_updateCubemapFace >= 0) && (_updateCubemapFace <= 5)) + { + _clearColor = clearColArray[_updateCubemapFace]; + doPreRender(*cv, _updateCubemapFace++); + } +#else + while (_updateCubemapFace<6) + { + _clearColor = clearColArray[_updateCubemapFace]; + doPreRender(*cv, _updateCubemapFace++); + } +#endif + } + + // must traverse the subgraph + traverse(node,nv); + } + + void doPreRender(osgUtil::CullVisitor& cv, const int nFace); + + struct ImageData + { + ImageData(const osg::Vec3& dir, const osg::Vec3& up) : _dir(dir), _up(up) {} + osg::Vec3 _dir; + osg::Vec3 _up; + }; + + osg::ref_ptr _subgraph; + osg::ref_ptr _cubemap; + osg::ref_ptr _localState[6]; + osg::ref_ptr _texmat; + osg::Vec4 _clearColor; + int _updateCubemapFace; +}; + + +void PrerenderCullCallback::doPreRender(osgUtil::CullVisitor& cv, const int nFace) +{ + const ImageData id[] = + { + ImageData( osg::Vec3( 1, 0, 0), osg::Vec3( 0, -1, 0) ), // +X + ImageData( osg::Vec3(-1, 0, 0), osg::Vec3( 0, -1, 0) ), // -X + ImageData( osg::Vec3( 0, 1, 0), osg::Vec3( 0, 0, 1) ), // +Y + ImageData( osg::Vec3( 0, -1, 0), osg::Vec3( 0, 0, -1) ), // -Y + ImageData( osg::Vec3( 0, 0, 1), osg::Vec3( 0, -1, 0) ), // +Z + ImageData( osg::Vec3( 0, 0, -1), osg::Vec3( 0, -1, 0) ) // -Z + }; + + osg::Image* image = _cubemap->getImage((osg::TextureCubeMap::Face)nFace); + osg::Vec3 dir = id[nFace]._dir; + osg::Vec3 up = id[nFace]._up; + + const osg::BoundingSphere& bs = _subgraph->getBound(); + if (!bs.valid()) + { + osg::notify(osg::WARN) << "bb invalid"<<_subgraph.get()< rtts = new osgUtil::RenderToTextureStage; + + // set up lighting. + // currently ignore lights in the scene graph itself.. + // will do later. + osgUtil::RenderStage* previous_stage = cv.getCurrentRenderBin()->_stage; + + // set up the background color and clear mask. + rtts->setClearColor(_clearColor); + + // ABJ: use default (color+depth) + rtts->setClearMask(previous_stage->getClearMask()); + + // set up to charge the same RenderStageLighting is the parent previous stage. + rtts->setRenderStageLighting(previous_stage->getRenderStageLighting()); + + // record the render bin, to be restored after creation + // of the render to text + osgUtil::RenderBin* previousRenderBin = cv.getCurrentRenderBin(); + + // set the current renderbin to be the newly created stage. + cv.setCurrentRenderBin(rtts.get()); + + + float znear = 1.0f*bs.radius(); + float zfar = 3.0f*bs.radius(); + + znear *= 0.9f; + zfar *= 1.1f; + + // set up projection. + const double fovy = 90.0; + const double aspectRatio = 1.0; + osg::RefMatrix* projection = new osg::RefMatrix; + projection->makePerspective(fovy, aspectRatio, znear, zfar); + + cv.pushProjectionMatrix(projection); + + osg::RefMatrix* matrix = new osg::RefMatrix; + osg::Vec3 eye = bs.center(); eye.z() = 0.0f; + osg::Vec3 center = eye + dir; + matrix->makeLookAt(eye, center, up); + + cv.pushModelViewMatrix(matrix); + + cv.pushStateSet(_localState[nFace].get()); + + { + // traverse the subgraph + _subgraph->accept(cv); + } + + cv.popStateSet(); + + // restore the previous model view matrix. + cv.popModelViewMatrix(); + + // restore the previous model view matrix. + cv.popProjectionMatrix(); + + // restore the previous renderbin. + cv.setCurrentRenderBin(previousRenderBin); + + if (rtts->_renderGraphList.size()==0 && rtts->_bins.size()==0) + { + // getting to this point means that all the subgraph has been + // culled by small feature culling or is beyond LOD ranges. + return; + } + + int height = 128; + int width = 128; + + const osg::Viewport& viewport = *cv.getViewport(); + + // offset the impostor viewport from the center of the main window + // viewport as often the edges of the viewport might be obscured by + // other windows, which can cause image/reading writing problems. + int center_x = viewport.x()+viewport.width()/2; + int center_y = viewport.y()+viewport.height()/2; + + osg::Viewport* new_viewport = new osg::Viewport; + new_viewport->setViewport(center_x-width/2,center_y-height/2,width,height); + rtts->setViewport(new_viewport); + + _localState[nFace]->setAttribute(new_viewport); + + // and the render to texture stage to the current stages + // dependancy list. + cv.getCurrentRenderBin()->_stage->addToDependencyList(rtts.get()); + + // if one exist attach image to the RenderToTextureStage. +// if (_image.valid()) rtts->setImage(_image.get()); + if (image) rtts->setImage(image); +} + + +osg::Drawable* makeGeometry() +{ + const float radius = 20; + return new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius)); +} + + +osg::Node* createPreRenderSubGraph(osg::Node* subgraph) +{ + if (!subgraph) return 0; + + // create the quad to visualize. + osg::Drawable* geom = makeGeometry(); + geom->setSupportsDisplayList(false); + + // new we need to add the texture to the Drawable, we do so by creating a + // StateSet to contain the Texture StateAttribute. + osg::StateSet* stateset = new osg::StateSet; + + osg::TextureCubeMap* cubemap = new osg::TextureCubeMap; + + // set up the textures + osg::Image* imagePosX = new osg::Image; + osg::Image* imageNegX = new osg::Image; + osg::Image* imagePosY = new osg::Image; + osg::Image* imageNegY = new osg::Image; + osg::Image* imagePosZ = new osg::Image; + osg::Image* imageNegZ = new osg::Image; + + imagePosX->setInternalTextureFormat(GL_RGB); + imageNegX->setInternalTextureFormat(GL_RGB); + imagePosY->setInternalTextureFormat(GL_RGB); + imageNegY->setInternalTextureFormat(GL_RGB); + imagePosZ->setInternalTextureFormat(GL_RGB); + imageNegZ->setInternalTextureFormat(GL_RGB); + + cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX); + cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX); + cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY); + cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY); + cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ); + cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ); + + cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE); + cubemap->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); + cubemap->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); + stateset->setTextureAttributeAndModes(0, cubemap, osg::StateAttribute::ON); + + osg::TexGen *texgen = new osg::TexGen; + texgen->setMode(osg::TexGen::REFLECTION_MAP); + stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON); + + osg::TexMat* texmat = new osg::TexMat; + stateset->setTextureAttribute(0, texmat); + + stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + + geom->setStateSet(stateset); + + osg::Geode* geode = new osg::Geode; + geode->addDrawable(geom); + + // Geodes can't have cull callback so create extra Group to attach cullcallback. + osg::Group* parent = new osg::Group; + + parent->setUpdateCallback(new PrerenderAppCallback(subgraph)); + + parent->setCullCallback(new PrerenderCullCallback(subgraph, cubemap, texmat)); + + parent->addChild(geode); + + return parent; +} + + +struct DrawableCullCallback : public osg::Drawable::CullCallback +{ + DrawableCullCallback(osg::TexMat* texmat) : _texmat(texmat) + {} + + virtual bool cull(osg::NodeVisitor* nv, osg::Drawable* /*drawable*/, osg::State* /*state*/) const + { + osgUtil::CullVisitor* cv = dynamic_cast(nv); + if (cv) + { + osg::Quat q; + q.set(cv->getModelViewMatrix()); + const osg::Matrix C = osg::Matrix::rotate( q.inverse() ); + _texmat->setMatrix(C); + } + return false; + } + + mutable osg::ref_ptr _texmat; +}; + +osg::Node* createReferenceSphere() +{ + const float radius = 10; + osg::Drawable* sphere = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius)); + + osg::StateSet* stateset = new osg::StateSet; + sphere->setStateSet(stateset); + + osg::TextureCubeMap* cubemap = new osg::TextureCubeMap; + #define CUBEMAP_FILENAME(face) "Cubemap_axis/" #face ".png" + + osg::Image* imagePosX = osgDB::readImageFile(CUBEMAP_FILENAME(posx)); + osg::Image* imageNegX = osgDB::readImageFile(CUBEMAP_FILENAME(negx)); + osg::Image* imagePosY = osgDB::readImageFile(CUBEMAP_FILENAME(posy)); + osg::Image* imageNegY = osgDB::readImageFile(CUBEMAP_FILENAME(negy)); + osg::Image* imagePosZ = osgDB::readImageFile(CUBEMAP_FILENAME(posz)); + osg::Image* imageNegZ = osgDB::readImageFile(CUBEMAP_FILENAME(negz)); + + if (imagePosX && imageNegX && imagePosY && imageNegY && imagePosZ && imageNegZ) + { + cubemap->setImage(osg::TextureCubeMap::POSITIVE_X, imagePosX); + cubemap->setImage(osg::TextureCubeMap::NEGATIVE_X, imageNegX); + cubemap->setImage(osg::TextureCubeMap::POSITIVE_Y, imagePosY); + cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Y, imageNegY); + cubemap->setImage(osg::TextureCubeMap::POSITIVE_Z, imagePosZ); + cubemap->setImage(osg::TextureCubeMap::NEGATIVE_Z, imageNegZ); + + cubemap->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); + cubemap->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); + cubemap->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_EDGE); + cubemap->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR); + cubemap->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR); + stateset->setTextureAttributeAndModes(0, cubemap, osg::StateAttribute::ON); + } + + osg::TexGen *texgen = new osg::TexGen; + texgen->setMode(osg::TexGen::REFLECTION_MAP); + stateset->setTextureAttributeAndModes(0, texgen, osg::StateAttribute::ON); + + osg::TexMat* texmat = new osg::TexMat; + stateset->setTextureAttribute(0, texmat); + + stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + + + sphere->setCullCallback(new DrawableCullCallback(texmat)); + + osg::Geode* geode = new osg::Geode(); + geode->addDrawable(sphere); + + return geode; +} + +int main( int argc, char **argv ) +{ + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the example which demonstrates pre rendering of scene to a texture, and then apply this texture to geometry."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + // construct the viewer. + osgProducer::Viewer viewer(arguments); + + // set up the value with sensible default event handlers. + viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + + // get details on keyboard and mouse bindings used by the viewer. + viewer.getUsage(*arguments.getApplicationUsage()); + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } +/* + if (arguments.argc()<=1) + { + arguments.getApplicationUsage()->write(std::cout,osg::ApplicationUsage::COMMAND_LINE_OPTION); + return 1; + } +*/ + + osg::Group* rootNode = new osg::Group(); + +#if 1 + osg::Node* sky = osgDB::readNodeFile("skydome.osg"); + if (sky) + rootNode->addChild(createPreRenderSubGraph(sky)); +#endif + +#if 1 + osg::PositionAttitudeTransform* pat = new osg::PositionAttitudeTransform; + pat->setPosition(osg::Vec3(0,0,50)); + pat->addChild(createReferenceSphere()); + rootNode->addChild(pat); +#endif + // load the nodes from the commandline arguments. + osg::Node* loadedModel = osgDB::readNodeFiles(arguments); + if (loadedModel) + rootNode->addChild(loadedModel); + + + // add model to the viewer. + viewer.setSceneData( rootNode ); + + + // create the windows and run the threads. + viewer.realize(); + + while( !viewer.done() ) + { + // wait for all cull and draw threads to complete. + viewer.sync(); + + // update the scene by traversing it with the the update visitor which will + // call all node update callbacks and animations. + viewer.update(); + + // fire off the cull and draw traversals of the scene. + viewer.frame(); + + } + + // wait for all cull and draw threads to complete before exit. + viewer.sync(); + + return 0; +} + diff --git a/examples/osgshape/osgshape.cpp b/examples/osgshape/osgshape.cpp index bba75cb42..6412fdaf7 100644 --- a/examples/osgshape/osgshape.cpp +++ b/examples/osgshape/osgshape.cpp @@ -34,10 +34,13 @@ osg::Geode* createShapes() float radius = 0.8f; float height = 1.0f; - geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius))); - geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(2.0f,0.0f,0.0f),2*radius))); - geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height))); - geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(6.0f,0.0f,0.0f),radius,height))); + osg::TessellationHints* hints = new osg::TessellationHints; + hints->setDetailRatio(0.5f); + + geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0f,0.0f,0.0f),radius),hints)); + geode->addDrawable(new osg::ShapeDrawable(new osg::Box(osg::Vec3(2.0f,0.0f,0.0f),2*radius),hints)); + geode->addDrawable(new osg::ShapeDrawable(new osg::Cone(osg::Vec3(4.0f,0.0f,0.0f),radius,height),hints)); + geode->addDrawable(new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(6.0f,0.0f,0.0f),radius,height),hints)); osg::Grid* grid = new osg::Grid; grid->allocateGrid(38,39); diff --git a/examples/osgslideshow/DefaultPresentation.cpp b/examples/osgslideshow/DefaultPresentation.cpp new file mode 100644 index 000000000..d6b2fdfbd --- /dev/null +++ b/examples/osgslideshow/DefaultPresentation.cpp @@ -0,0 +1,131 @@ +#include + +#include +#include +#include +#include +#include +#include + +osg::MatrixTransform* createPositionedAndScaledModel(osg::Node* model,const osg::Vec3& pos, float radius, osg::Quat rotation) +{ + osg::MatrixTransform* transform = new osg::MatrixTransform; + + const osg::BoundingSphere& bs = model->getBound(); + + transform->setDataVariance(osg::Object::STATIC); + transform->setMatrix(osg::Matrix::translate(-bs.center())* + osg::Matrix::scale(radius/bs.radius(),radius/bs.radius(),radius/bs.radius())* + osg::Matrix::rotate(rotation)* + osg::Matrix::translate(pos)); + + transform->addChild(model); + + return transform; +} + + +osg::Node* createDefaultPresentation() +{ + osg::Switch* presentation = new osg::Switch; + presentation->setName("Presentation default"); + + float width = 1280.0f; + float height = 1024.0f; + + osg::Geometry* backgroundQuad = osg::createTexturedQuadGeometry(osg::Vec3(0.0f,0.0f,0.0f), + osg::Vec3(width,0.0f,0.0f), + osg::Vec3(0.0f,0.0f,height)); + + osg::Geode* background = new osg::Geode; + + background->getOrCreateStateSet()->setTextureAttributeAndModes(0, + new osg::Texture2D(osgDB::readImageFile("lz.rgb")), + osg::StateAttribute::ON); + + background->addDrawable(backgroundQuad); + + osg::Geode* background2 = new osg::Geode; + + background2->getOrCreateStateSet()->setTextureAttributeAndModes(0, + new osg::Texture2D(osgDB::readImageFile("reflect.rgb")), + osg::StateAttribute::ON); + + background2->addDrawable(backgroundQuad); + + { + osg::Switch* slide = new osg::Switch; + slide->setName("Slide 0"); + + { + osg::Group* group = new osg::Group; + group->setName("Layer 0"); + + group->addChild(background); + + + slide->addChild(group); + } + + { + osg::Group* group = new osg::Group; + group->setName("Layer 1"); + + group->addChild(background2); + + slide->addChild(group); + } + + { + osg::Group* group = new osg::Group; + group->setName("Layer 2"); + + group->addChild(background); + + group->addChild(createPositionedAndScaledModel(osgDB::readNodeFile("cow.osg"), + osg::Vec3(600.0f,0.0f,600.0f),500.0f, + osg::Quat())); + + slide->addChild(group); + } + + presentation->addChild(slide); + + } + + { + osg::Switch* slide = new osg::Switch; + slide->setName("Slide 1"); + + { + osg::Group* group = new osg::Group; + group->setName("Layer 0"); + + group->addChild(background); + + group->addChild(createPositionedAndScaledModel(osgDB::readNodeFile("glider.osg"), + osg::Vec3(600.0f,0.0f,600.0f),500.0f, + osg::Quat())); + + slide->addChild(group); + } + + { + osg::Group* group = new osg::Group; + group->setName("Layer 1"); + + group->addChild(background2); + + group->addChild(createPositionedAndScaledModel(osgDB::readNodeFile("Town.osg"), + osg::Vec3(600.0f,0.0f,600.0f),500.0f, + osg::Quat())); + + slide->addChild(group); + } + + presentation->addChild(slide); + + } + + return presentation; +} diff --git a/examples/osgslideshow/GNUmakefile b/examples/osgslideshow/GNUmakefile new file mode 100644 index 000000000..f59a0bd2f --- /dev/null +++ b/examples/osgslideshow/GNUmakefile @@ -0,0 +1,21 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + SlideEventHandler.cpp\ + DefaultPresentation.cpp\ + osgslideshow.cpp\ + +LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +INSTFILES = \ + $(CXXFILES)\ + GNUmakefile.inst=GNUmakefile + +EXEC = osgslideshow + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules + diff --git a/examples/osgslideshow/GNUmakefile.inst b/examples/osgslideshow/GNUmakefile.inst new file mode 100644 index 000000000..c41b1d2f5 --- /dev/null +++ b/examples/osgslideshow/GNUmakefile.inst @@ -0,0 +1,16 @@ +TOPDIR = ../.. +include $(TOPDIR)/Make/makedefs + +CXXFILES =\ + SlideEventHandler.cpp\ + DefaultPresentation.cpp\ + osgviewer.cpp\ + +LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) + +EXEC = osgslideshow + +INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include +LDFLAGS += $(PRODUCER_LIB_DIR) + +include $(TOPDIR)/Make/makerules diff --git a/examples/osgslideshow/SlideEventHandler.cpp b/examples/osgslideshow/SlideEventHandler.cpp new file mode 100644 index 000000000..9366708c6 --- /dev/null +++ b/examples/osgslideshow/SlideEventHandler.cpp @@ -0,0 +1,274 @@ +#include "SlideEventHandler.h" + +class FindNamedSwitchVisitor : public osg::NodeVisitor +{ +public: + + FindNamedSwitchVisitor(const std::string& name): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _name(name), + _switch(0) {} + + void apply(osg::Switch& sw) + { + if (sw.getName().find(_name)!=std::string::npos) + { + _switch = &sw; + return; // note, no need to do traverse now we've located the relevant switch + } + + traverse(sw); + } + + std::string _name; + osg::Switch* _switch; + +}; + + +SlideEventHandler::SlideEventHandler(): + _presentationSwitch(0), + _activeSlide(0), + _slideSwitch(0), + _activeLayer(0), + _firstTraversal(true), + _previousTime(-1.0f), + _timePerSlide(1.0), + _autoSteppingActive(false), + _loopPresentation(true), + _pause(false) +{ +} + +void SlideEventHandler::set(osg::Node* model) +{ + FindNamedSwitchVisitor findPresentation("Presentation"); + model->accept(findPresentation); + + if (findPresentation._switch) + { + std::cout<<"Found presenation '"<getName()<<"'"<accept(findSlide); + + if (findSlide._switch) + { + std::cout<<"Found presenation slide"<getName()<_timePerSlide) + { + _previousTime = time; + + nextLayerOrSlide(); + } + + } + } + case(osgGA::GUIEventAdapter::KEYDOWN): + { + if (ea.getKey()=='a') + { + _autoSteppingActive = !_autoSteppingActive; + _previousTime = ea.time(); + return true; + } + else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Home || + ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home) + { + _autoSteppingActive = false; + selectSlide(0); + return true; + } + else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_End || + ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End) + { + _autoSteppingActive = false; + selectSlide(LAST_POSITION,LAST_POSITION); + return true; + } + else if (ea.getKey()=='n' || + ea.getKey()==osgGA::GUIEventAdapter::KEY_Down || + ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Down) + { + _autoSteppingActive = false; + nextLayerOrSlide(); + return true; + } + else if (ea.getKey()=='p' || + ea.getKey()==osgGA::GUIEventAdapter::KEY_Up || + ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Up) + { + _autoSteppingActive = false; + previousLayerOrSlide(); + return true; + } + else if (ea.getKey()=='N' || + ea.getKey()==osgGA::GUIEventAdapter::KEY_Right || + ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right || + ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Down || + ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Down) + { + _autoSteppingActive = false; + nextSlide(); + return true; + } + else if (ea.getKey()=='P' || + ea.getKey()==osgGA::GUIEventAdapter::KEY_Left || + ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left || + ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Up || + ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Up) + { + _autoSteppingActive = false; + previousSlide(); + return true; + } + else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Pause) + { + _pause = !_pause; + if (_pause) std::cout<<"Pause"<getNumChildren()>0) + { + slideNum = _presentationSwitch->getNumChildren()-1; + } + + if (slideNum>=_presentationSwitch->getNumChildren()) return false; + + + _activeSlide = slideNum; + _presentationSwitch->setSingleChildOn(_activeSlide); + + //std::cout<<"Selected slide '"<<_presentationSwitch->getChild(_activeSlide)->getName()<<"'"<getChild(_activeSlide)->accept(findSlide); + + if (findSlide._switch) + { + //std::cout<<"Found slide '"<getName()<<"'"<getNumChildren()>0) + { + layerNum = _slideSwitch->getNumChildren()-1; + } + + if (layerNum>=_slideSwitch->getNumChildren()) return false; + + _activeLayer = layerNum; + _slideSwitch->setSingleChildOn(_activeLayer); + + //std::cout<<"Selected layer '"<<_slideSwitch->getChild(_activeLayer)->getName()<<"' num="<<_activeLayer<< std::endl; + + return true; +} + +bool SlideEventHandler::nextLayerOrSlide() +{ + if (nextLayer()) return true; + else return nextSlide(); +} + +bool SlideEventHandler::previousLayerOrSlide() +{ + if (previousLayer()) return true; + else return previousSlide(); +} + +bool SlideEventHandler::nextSlide() +{ + if (selectSlide(_activeSlide+1)) return true; + else if (_loopPresentation) return selectSlide(0); + else return false; +} + +bool SlideEventHandler::previousSlide() +{ + if (_activeSlide>0) return selectSlide(_activeSlide-1,LAST_POSITION); + else if (_loopPresentation && _presentationSwitch.valid()) return selectSlide(_presentationSwitch->getNumChildren()-1,LAST_POSITION); + else return false; +} + +bool SlideEventHandler::nextLayer() +{ + return selectLayer(_activeLayer+1); +} + +bool SlideEventHandler::previousLayer() +{ + if (_activeLayer>0) return selectLayer(_activeLayer-1); + else return false; +} diff --git a/examples/osgslideshow/SlideEventHandler.h b/examples/osgslideshow/SlideEventHandler.h new file mode 100644 index 000000000..4d01d3545 --- /dev/null +++ b/examples/osgslideshow/SlideEventHandler.h @@ -0,0 +1,78 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + + +#ifndef SLIDEEVENTHANDLER +#define SLIDEEVENTHANDLER 1 + +#include + +#include + +class SlideEventHandler : public osgGA::GUIEventHandler +{ +public: + + SlideEventHandler(); + + META_Object(osgslideshowApp,SlideEventHandler); + + void set(osg::Node* model); + + virtual void accept(osgGA::GUIEventHandlerVisitor& v) { v.visit(*this); } + + virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&); + + virtual void getUsage(osg::ApplicationUsage& usage) const; + + enum WhichPosition + { + FIRST_POSITION = 0, + LAST_POSITION = 0xffffffff, + }; + + bool selectSlide(unsigned int slideNum,unsigned int layerNum=FIRST_POSITION); + bool selectLayer(unsigned int layerNum); + + bool nextLayerOrSlide(); + bool previousLayerOrSlide(); + + bool nextSlide(); + bool previousSlide(); + + bool nextLayer(); + bool previousLayer(); + +protected: + + ~SlideEventHandler() {} + SlideEventHandler(const SlideEventHandler&,const osg::CopyOp&) {} + + osg::ref_ptr _presentationSwitch; + unsigned int _activeSlide; + + osg::ref_ptr _slideSwitch; + unsigned int _activeLayer; + + bool _firstTraversal; + double _previousTime; + double _timePerSlide; + bool _autoSteppingActive; + bool _loopPresentation; + bool _pause; + +}; + + + +#endif diff --git a/examples/osgslideshow/osgslideshow.cpp b/examples/osgslideshow/osgslideshow.cpp new file mode 100644 index 000000000..7dc5296c8 --- /dev/null +++ b/examples/osgslideshow/osgslideshow.cpp @@ -0,0 +1,119 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This application is open source and may be redistributed and/or modified + * freely and without restriction, both in commericial and non commericial applications, + * as long as this copyright notice is maintained. + * + * This application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +*/ + +#include +#include +#include + +#include "SlideEventHandler.h" + +extern osg::Node* createDefaultPresentation(); + +int main( int argc, char **argv ) +{ + + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + + // set up the usage document, in case we need to print out how to use this program. + arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName()); + arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models."); + arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ..."); + arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information"); + + + // construct the viewer. + osgProducer::Viewer viewer(arguments); + + // set up the value with sensible default event handlers. + viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + + // get details on keyboard and mouse bindings used by the viewer. + viewer.getUsage(*arguments.getApplicationUsage()); + + // register the slide event handler - which moves the presentation from slide to slide, layer to layer. + SlideEventHandler* seh = new SlideEventHandler; + viewer.getEventHandlerList().push_front(seh); + + // if user request help write it out to cout. + if (arguments.read("-h") || arguments.read("--help")) + { + arguments.getApplicationUsage()->write(std::cout); + return 1; + } + + // any option left unread are converted into errors to write out later. + arguments.reportRemainingOptionsAsUnrecognized(); + + // report any errors if they have occured when parsing the program aguments. + if (arguments.errors()) + { + arguments.writeErrorMessages(std::cout); + return 1; + } + + osg::Timer timer; + osg::Timer_t start_tick = timer.tick(); + + // read the scene from the list of file specified commandline args. + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + + // if no model loaded create a default presentation. + if (!loadedModel) + { + loadedModel = createDefaultPresentation(); + } + + + // if no model has been successfully loaded report failure. + if (!loadedModel) + { + std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; + return 1; + } + + osg::Timer_t end_tick = timer.tick(); + + std::cout << "Time to load = "<set(loadedModel.get()); + + // set the scene to render + viewer.setSceneData(loadedModel.get()); + + // create the windows and run the threads. + viewer.realize(); + + while( !viewer.done() ) + { + // wait for all cull and draw threads to complete. + viewer.sync(); + + // update the scene by traversing it with the the update visitor which will + // call all node update callbacks and animations. + viewer.update(); + + // fire off the cull and draw traversals of the scene. + viewer.frame(); + + } + + // wait for all cull and draw threads to complete before exit. + viewer.sync(); + + return 0; +} + diff --git a/include/osg/Geometry b/include/osg/Geometry index 9248c9969..1a0e57796 100644 --- a/include/osg/Geometry +++ b/include/osg/Geometry @@ -394,6 +394,11 @@ class SG_EXPORT Geometry : public Drawable mutable bool _fastPath; }; +/** Convenience function to be used for creating quad geometry with texture coords. + * Tex coords go from bottom left (0,0) to top right (1,1).*/ +extern SG_EXPORT Geometry* createTexturedQuadGeometry(const Vec3& corner,const Vec3& widthVec,const Vec3& heightVec); + + } diff --git a/include/osg/ShapeDrawable b/include/osg/ShapeDrawable index 24d6381e5..79c028eea 100644 --- a/include/osg/ShapeDrawable +++ b/include/osg/ShapeDrawable @@ -29,6 +29,7 @@ class TessellationHints : public Object TessellationHints(): _TessellationMode(USE_SHAPE_DEFAULTS), + _detailRatio(1.0f), _targetNumFaces(100), _createFrontFace(true), _createBackFace(false), @@ -42,6 +43,7 @@ class TessellationHints : public Object TessellationHints(const TessellationHints& tess, const CopyOp& copyop=CopyOp::SHALLOW_COPY): Object(tess,copyop), _TessellationMode(tess._TessellationMode), + _detailRatio(tess._detailRatio), _targetNumFaces(tess._targetNumFaces), _createFrontFace(tess._createFrontFace), _createBackFace(tess._createBackFace), @@ -63,6 +65,9 @@ class TessellationHints : public Object inline void setTessellationMode(TessellationMode mode) { _TessellationMode=mode; } inline TessellationMode getTessellationMode() const { return _TessellationMode; } + inline void setDetailRatio(float ratio) { _detailRatio = ratio; } + inline float getDetailRatio() const { return _detailRatio; } + inline void setTargetNumFaces(unsigned int target) { _targetNumFaces=target; } inline unsigned int getTargetNumFaces() const { return _targetNumFaces; } @@ -93,6 +98,8 @@ class TessellationHints : public Object TessellationMode _TessellationMode; + + float _detailRatio; unsigned int _targetNumFaces; bool _createFrontFace; @@ -112,7 +119,7 @@ class SG_EXPORT ShapeDrawable : public Drawable ShapeDrawable(); - ShapeDrawable(Shape* shape); + ShapeDrawable(Shape* shape,TessellationHints* hints=0); /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ ShapeDrawable(const ShapeDrawable& pg,const CopyOp& copyop=CopyOp::SHALLOW_COPY); diff --git a/include/osg/Texture2D b/include/osg/Texture2D index 41aa6b4f3..7d8213f97 100644 --- a/include/osg/Texture2D +++ b/include/osg/Texture2D @@ -26,6 +26,8 @@ class SG_EXPORT Texture2D : public Texture Texture2D(); + Texture2D(osg::Image* image); + /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ Texture2D(const Texture2D& text,const CopyOp& copyop=CopyOp::SHALLOW_COPY); diff --git a/include/osgUtil/TransformAttributeFunctor b/include/osgUtil/TransformAttributeFunctor new file mode 100644 index 000000000..0a550bfe5 --- /dev/null +++ b/include/osgUtil/TransformAttributeFunctor @@ -0,0 +1,45 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#ifndef OSGUTIL_TRANSFORMATTRIBUTEFUNCTOR +#define OSGUTIL_TRANSFORMATTRIBUTEFUNCTOR 1 + +#include +#include + +#include + +namespace osgUtil { + +/** Functor for transforming a drawable's vertex and normal attributes by specified matrix. + * typically used for flattening transform down onto drawable leaves. */ +class OSGUTIL_EXPORT TransformAttributeFunctor : public osg::Drawable::AttributeFunctor +{ + public: + + /** construct a functor to transform a drawable's vertex and normal attributes by specified matrix.*/ + TransformAttributeFunctor(const osg::Matrix& m); + + virtual ~TransformAttributeFunctor(); + + /** do the work of transforming vertex and normal attributes. */ + virtual void apply(osg::Drawable::AttributeType type,unsigned int count,osg::Vec3* begin); + + osg::Matrix _m; + osg::Matrix _im; + +}; + +} + +#endif diff --git a/src/osg/GNUmakefile b/src/osg/GNUmakefile index 9bed21042..9ffb70ff0 100644 --- a/src/osg/GNUmakefile +++ b/src/osg/GNUmakefile @@ -83,7 +83,6 @@ CXXFILES =\ Texture3D.cpp\ TextureCubeMap.cpp\ TextureRectangle.cpp\ - TransformAttributeFunctor.cpp\ Timer.cpp\ Transform.cpp\ UnitTestFramework.cpp\ diff --git a/src/osg/Geometry.cpp b/src/osg/Geometry.cpp index c9e8df48f..6570fc5cb 100644 --- a/src/osg/Geometry.cpp +++ b/src/osg/Geometry.cpp @@ -2184,3 +2184,38 @@ void Geometry::Extensions::glVertexAttrib4Nubv(unsigned int index, const GLubyte notify(WARN)<<"Error: glVertexAttrib4Nubv not supported by OpenGL driver"<setVertexArray(coords); + + Vec2Array* tcoords = new Vec2Array(4); + (*tcoords)[0].set(0.0f,1.0f); + (*tcoords)[1].set(0.0f,0.0f); + (*tcoords)[2].set(1.0f,0.0f); + (*tcoords)[3].set(1.0f,1.0f); + geom->setTexCoordArray(0,tcoords); + + osg::Vec4Array* colours = new osg::Vec4Array(1); + (*colours)[0].set(1.0f,1.0f,1.0,1.0f); + geom->setColorArray(colours); + geom->setColorBinding(Geometry::BIND_OVERALL); + + osg::Vec3Array* normals = new osg::Vec3Array(1); + (*normals)[0] = widthVec^heightVec; + (*normals)[0].normalize(); + geom->setNormalArray(normals); + geom->setNormalBinding(Geometry::BIND_OVERALL); + + geom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS,0,4)); + + return geom; +} diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 765696bb5..0dac9fa23 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -160,7 +160,7 @@ unsigned int Image::computeNumComponents(GLenum format) case(GL_LUMINANCE_ALPHA): return 2; default: { - std::cout<<"error format = "<r(),t_offset+source->t(),r_offset+source->t(), source->getPixelFormat(),source->getDataType(), source->getPacking()); diff --git a/src/osg/ShapeDrawable.cpp b/src/osg/ShapeDrawable.cpp index 8e850704f..ecfa4c76b 100644 --- a/src/osg/ShapeDrawable.cpp +++ b/src/osg/ShapeDrawable.cpp @@ -16,6 +16,11 @@ using namespace osg; +// arbitrary minima for rows & segments +const unsigned int MIN_NUM_ROWS = 3; +const unsigned int MIN_NUM_SEGMENTS = 5; + + /////////////////////////////////////////////////////////////////////////////// // // draw shape @@ -29,11 +34,12 @@ class DrawShapeVisitor : public ConstShapeVisitor _state(state), _hints(hints) { +#if 0 if (hints) { notify(NOTICE)<<"Warning: TessellationHints ignored in present osg::ShapeDrawable implementation."<getDetailRatio() != 1.0f) { + float ratio = _hints->getDetailRatio(); + numRows = (unsigned int) (numRows * ratio); + if (numRows < MIN_NUM_ROWS) + numRows = MIN_NUM_ROWS; + numSegments = (unsigned int) (numSegments * ratio); + if (numSegments < MIN_NUM_SEGMENTS) + numSegments = MIN_NUM_SEGMENTS; + } float lDelta = osg::PI/(float)numRows; float vDelta = 1.0f/(float)numRows; @@ -76,9 +90,7 @@ void DrawShapeVisitor::apply(const Sphere& sphere) float nzBase=-1.0f; float nRatioBase=0.0f; - for(unsigned int rowi=0; - rowigetCreateBody() : true); + bool createTop = (_hints ? _hints->getCreateTop() : true); + bool createBottom = (_hints ? _hints->getCreateBottom() : true); float dx = box.getHalfLengths().x(); float dy = box.getHalfLengths().y(); @@ -160,6 +173,7 @@ void DrawShapeVisitor::apply(const Box& box) glBegin(GL_QUADS); + if (createBody) { // -ve y plane glNormal3f(0.0f,-1.0f,0.0f); @@ -219,7 +233,9 @@ void DrawShapeVisitor::apply(const Box& box) glTexCoord2f(1.0f,1.0f); glVertex3f(-dx,-dy,dz); + } + if (createTop) { // +ve z plane glNormal3f(0.0f,0.0f,1.0f); @@ -234,7 +250,9 @@ void DrawShapeVisitor::apply(const Box& box) glTexCoord2f(1.0f,1.0f); glVertex3f(dx,dy,dz); + } + if (createBottom) { // -ve z plane glNormal3f(0.0f,0.0f,-1.0f); @@ -249,6 +267,7 @@ void DrawShapeVisitor::apply(const Box& box) glTexCoord2f(1.0f,1.0f); glVertex3f(-dx,dy,-dz); + } glEnd(); @@ -268,9 +287,21 @@ void DrawShapeVisitor::apply(const Cone& cone) glMultMatrixf(rotation.ptr()); } + // evaluate hints + bool createBody = (_hints ? _hints->getCreateBody() : true); + bool createBottom = (_hints ? _hints->getCreateBottom() : true); unsigned int numSegments = 40; unsigned int numRows = 10; + if (_hints && _hints->getDetailRatio() != 1.0f) { + float ratio = _hints->getDetailRatio(); + numRows = (unsigned int) (numRows * ratio); + if (numRows < MIN_NUM_ROWS) + numRows = MIN_NUM_ROWS; + numSegments = (unsigned int) (numSegments * ratio); + if (numSegments < MIN_NUM_SEGMENTS) + numSegments = MIN_NUM_SEGMENTS; + } float r = cone.getRadius(); float h = cone.getHeight(); @@ -294,79 +325,71 @@ void DrawShapeVisitor::apply(const Cone& cone) float angle; float texCoord; - for(unsigned int rowi=0; - rowigetCreateBody() : true); + bool createTop = (_hints ? _hints->getCreateTop() : true); + bool createBottom = (_hints ? _hints->getCreateBottom() : true); unsigned int numSegments = 40; + if (_hints && _hints->getDetailRatio() != 1.0f) { + float ratio = _hints->getDetailRatio(); + numSegments = (unsigned int) (numSegments * ratio); + if (numSegments < MIN_NUM_SEGMENTS) + numSegments = MIN_NUM_SEGMENTS; + } float angleDelta = 2.0f*osg::PI/(float)numSegments; - - float texCoordDelta = 1.0/(float)numSegments; + float texCoordDelta = 1.0f/(float)numSegments; float r = cylinder.getRadius(); float h = cylinder.getHeight(); @@ -395,16 +427,17 @@ void DrawShapeVisitor::apply(const Cylinder& cylinder) float basez = -h*0.5f; float topz = h*0.5f; + float angle = 0.0f; + float texCoord = 0.0f; + // cylinder body - glBegin(GL_QUAD_STRIP); + if (createBody) { + glBegin(GL_QUAD_STRIP); - float angle = 0.0f; - float texCoord = 0.0f; for(unsigned int bodyi=0; bodyiwriteInt(IVECONVEXPLANAROCCLUDER); + // If the osg class is inherited by any other class we should also write this to file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->write(out); + } + else + throw Exception("ConvexPlanarOccluder::write(): Could not cast this osg::ConvexPlanarOccluder to an osg::Object."); + // Write ConvexPlanarOccluder's properties. + + // Write planar polygon occluder. + out->writeInt((int)&getOccluder()); + if(&getOccluder()) + ((ive::ConvexPlanarPolygon*)(&getOccluder()))->write(out); + + // Write hole list. + HoleList holeList = getHoleList(); + int size = holeList.size(); + out->writeInt(size); + for(int i=0; iwrite(out); + } +} + +void ConvexPlanarOccluder::read(DataInputStream* in){ + // Peek on ConvexPlanarOccluder's identification. + int id = in->peekInt(); + if(id == IVECONVEXPLANAROCCLUDER){ + // Read ConvexPlanarOccluder's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->read(in); + } + else + throw Exception("ConvexPlanarOccluder::read(): Could not cast this osg::ConvexPlanarOccluder to an osg::Object."); + // Read ConvexPlanarOccluder's properties + + // Read planar polygon occluder. + if(in->readInt()){ + osg::ConvexPlanarPolygon* cpp = new osg::ConvexPlanarPolygon(); + ((ive::ConvexPlanarPolygon*)(cpp))->read(in); + setOccluder(*cpp); + } + + // Read hole list. + int size = in->readInt(); + for(int i=0; iread(in); + addHole(*cpp); + } + + } + else{ + throw Exception("ConvexPlanarOccluder::read(): Expected ConvexPlanarOccluder identification."); + } +} diff --git a/src/osgPlugins/ive/ConvexPlanarOccluder.h b/src/osgPlugins/ive/ConvexPlanarOccluder.h new file mode 100644 index 000000000..cc6afb79b --- /dev/null +++ b/src/osgPlugins/ive/ConvexPlanarOccluder.h @@ -0,0 +1,15 @@ +#ifndef IVE_CONVEXPLANAROCCLUDER +#define IVE_CONVEXPLANAROCCLUDER 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class ConvexPlanarOccluder : public osg::ConvexPlanarOccluder, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/ConvexPlanarPolygon.cpp b/src/osgPlugins/ive/ConvexPlanarPolygon.cpp new file mode 100644 index 000000000..3ab3a2576 --- /dev/null +++ b/src/osgPlugins/ive/ConvexPlanarPolygon.cpp @@ -0,0 +1,67 @@ +/********************************************************************** + * + * FILE: ConvexPlanarPolygon.cpp + * + * DESCRIPTION: Read/Write osg::ConvexPlanarPolygon in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 23.4.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "ConvexPlanarPolygon.h" + +using namespace ive; + +void ConvexPlanarPolygon::write(DataOutputStream* out){ + // Write ConvexPlanarPolygon's identification. + out->writeInt(IVECONVEXPLANARPOLYGON); + // If the osg class is inherited by any other class we should also write this to file. + //osg::Object* obj = dynamic_cast(this); + //if(obj){ + // ((ive::Object*)(obj))->write(out); + //} + //else + // throw Exception("ConvexPlanarPolygon::write(): Could not cast this osg::ConvexPlanarPolygon to an osg::Object."); + // Write ConvexPlanarPolygon's properties. + + // Write Vertex list + VertexList vertexList = getVertexList(); + int size = vertexList.size(); + out->writeInt(size); + for(int i=0; iwriteVec3(vertexList[i]); + } + +} + +void ConvexPlanarPolygon::read(DataInputStream* in){ + // Peek on ConvexPlanarPolygon's identification. + int id = in->peekInt(); + if(id == IVECONVEXPLANARPOLYGON){ + // Read ConvexPlanarPolygon's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + //osg::Object* obj = dynamic_cast(this); + //if(obj){ + // ((ive::Object*)(obj))->read(in); + //} + //else + // throw Exception("ConvexPlanarPolygon::read(): Could not cast this osg::ConvexPlanarPolygon to an osg::Object."); + // Read ConvexPlanarPolygon's properties + + // Read Vertex list + int size = in->readInt(); + for(int i=0; ireadVec3()); + } + + } + else{ + throw Exception("ConvexPlanarPolygon::read(): Expected ConvexPlanarPolygon identification."); + } +} diff --git a/src/osgPlugins/ive/ConvexPlanarPolygon.h b/src/osgPlugins/ive/ConvexPlanarPolygon.h new file mode 100644 index 000000000..9cd25d1f8 --- /dev/null +++ b/src/osgPlugins/ive/ConvexPlanarPolygon.h @@ -0,0 +1,17 @@ +#ifndef IVE_CONVEXPLANARPOLYGON +#define IVE_CONVEXPLANARPOLYGON 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class ConvexPlanarPolygon : public osg::ConvexPlanarPolygon, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); + + virtual ~ConvexPlanarPolygon() {} +}; +} + +#endif diff --git a/src/osgPlugins/ive/DrawElementsUInt.cpp b/src/osgPlugins/ive/DrawElementsUInt.cpp new file mode 100644 index 000000000..07641e7ec --- /dev/null +++ b/src/osgPlugins/ive/DrawElementsUInt.cpp @@ -0,0 +1,64 @@ +/********************************************************************** + * + * FILE: DrawElementsUInt.cpp + * + * DESCRIPTION: Read/Write osg::DrawElementsUInt in binary format to disk. + * + * CREATED BY: Copied from DrawElementsUShort.cpp by Marco Jez + * + * + * HISTORY: Created 20.3.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "DrawElementsUInt.h" +#include "PrimitiveSet.h" + +using namespace ive; + +void DrawElementsUInt::write(DataOutputStream* out){ + // Write DrawElementsUInt's identification. + out->writeInt(IVEDRAWELEMENTSUINT); + + // If the osg class is inherited by any other class we should also write this to file. + osg::PrimitiveSet* prim = dynamic_cast(this); + if(prim){ + ((ive::PrimitiveSet*)(prim))->write(out); + } + else + throw Exception("DrawElementsUInt::write(): Could not cast this osg::DrawElementsUInt to an osg::PrimitiveSet."); + // Write DrawElementsUInt's properties. + + // Write array length and its elements. + out->writeInt(size()); + for(unsigned int i=0; iwriteUInt(((osg::VectorUInt)(*this))[i]); + } +} + +void DrawElementsUInt::read(DataInputStream* in){ + // Read DrawElementsUInt's identification. + int id = in->peekInt(); + if(id == IVEDRAWELEMENTSUINT){ + // Code to read DrawElementsUInt's properties. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::PrimitiveSet* prim = dynamic_cast(this); + if(prim){ + ((ive::PrimitiveSet*)(prim))->read(in); + } + else + throw Exception("DrawElementsUInt::read(): Could not cast this osg::DrawElementsUInt to an osg::PrimtiveSet."); + + // Read array length and its elements. + int size = in->readInt(); + for(int i=0; ireadUInt()); + } + } + else{ + throw Exception("DrawElementsUInt::read(): Expected DrawElementsUInt identification."); + } +} diff --git a/src/osgPlugins/ive/DrawElementsUInt.h b/src/osgPlugins/ive/DrawElementsUInt.h new file mode 100644 index 000000000..43f98c35e --- /dev/null +++ b/src/osgPlugins/ive/DrawElementsUInt.h @@ -0,0 +1,15 @@ +#ifndef IVE_DRAWELEMENTSUINT +#define IVE_DRAWELEMENTSUINT 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class DrawElementsUInt : public osg::DrawElementsUInt, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/Impostor.cpp b/src/osgPlugins/ive/Impostor.cpp new file mode 100644 index 000000000..3b932c51e --- /dev/null +++ b/src/osgPlugins/ive/Impostor.cpp @@ -0,0 +1,54 @@ +/********************************************************************** + * + * FILE: Impostor.cpp + * + * DESCRIPTION: Read/Write osg::Impostor in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 16.4.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "Impostor.h" +#include "LOD.h" + +using namespace ive; + +void Impostor::write(DataOutputStream* out){ + // Write Impostor's identification. + out->writeInt(IVEIMPOSTOR); + // If the osg class is inherited by any other class we should also write this to file. + osg::LOD* lod = dynamic_cast(this); + if(lod){ + ((ive::LOD*)(lod))->write(out); + } + else + throw Exception("Impostor::write(): Could not cast this osg::Impostor to an osg::LOD."); + // Write Impostor's properties. + out->writeFloat(getImpostorThreshold()); +} + +void Impostor::read(DataInputStream* in){ + // Peek on Impostor's identification. + int id = in->peekInt(); + if(id == IVEIMPOSTOR){ + // Read Impostor's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::LOD* lod = dynamic_cast(this); + if(lod){ + ((ive::LOD*)(lod))->read(in); + } + else + throw Exception("Impostor::read(): Could not cast this osg::Impostor to an osg::LOD."); + // Read Impostor's properties + setImpostorThreshold(in->readFloat()); + } + else{ + throw Exception("Impostor::read(): Expected Impostor identification."); + } +} diff --git a/src/osgPlugins/ive/Impostor.h b/src/osgPlugins/ive/Impostor.h new file mode 100644 index 000000000..2d6444c1a --- /dev/null +++ b/src/osgPlugins/ive/Impostor.h @@ -0,0 +1,15 @@ +#ifndef IVE_IMPOSTOR +#define IVE_IMPOSTOR 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class Impostor : public osg::Impostor, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/OccluderNode.cpp b/src/osgPlugins/ive/OccluderNode.cpp new file mode 100644 index 000000000..d91b2a3d6 --- /dev/null +++ b/src/osgPlugins/ive/OccluderNode.cpp @@ -0,0 +1,61 @@ +/********************************************************************** + * + * FILE: OccluderNode.cpp + * + * DESCRIPTION: Read/Write osg::OccluderNode in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 16.4.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "OccluderNode.h" +#include "Group.h" +#include "ConvexPlanarOccluder.h" + +using namespace ive; + +void OccluderNode::write(DataOutputStream* out){ + // Write OccluderNode's identification. + out->writeInt(IVEOCCLUDERNODE); + // If the osg class is inherited by any other class we should also write this to file. + osg::Group* group = dynamic_cast(this); + if(group){ + ((ive::Group*)(group))->write(out); + } + else + throw Exception("OccluderNode::write(): Could not cast this osg::OccluderNode to an osg::Group."); + // Write OccluderNode's properties. + out->writeInt((int)getOccluder()); + if(getOccluder()) + ((ive::ConvexPlanarOccluder*)(getOccluder()))->write(out); +} + +void OccluderNode::read(DataInputStream* in){ + // Peek on OccluderNode's identification. + int id = in->peekInt(); + if(id == IVEOCCLUDERNODE){ + // Read OccluderNode's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Group* group = dynamic_cast(this); + if(group){ + ((ive::Group*)(group))->read(in); + } + else + throw Exception("OccluderNode::read(): Could not cast this osg::OccluderNode to an osg::Group."); + // Read OccluderNode's properties + if(in->readInt()){ + osg::ConvexPlanarOccluder* cpo = new osg::ConvexPlanarOccluder(); + ((ive::ConvexPlanarOccluder*)(cpo))->read(in); + setOccluder(cpo); + } + } + else{ + throw Exception("OccluderNode::read(): Expected OccluderNode identification."); + } +} diff --git a/src/osgPlugins/ive/OccluderNode.h b/src/osgPlugins/ive/OccluderNode.h new file mode 100644 index 000000000..7e560f654 --- /dev/null +++ b/src/osgPlugins/ive/OccluderNode.h @@ -0,0 +1,16 @@ +#ifndef IVE_OCCLUDERNODE +#define IVE_OCCLUDERNODE 1 + +#include + +#include "ReadWrite.h" + +namespace ive{ +class OccluderNode : public osg::OccluderNode, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/Point.cpp b/src/osgPlugins/ive/Point.cpp new file mode 100644 index 000000000..72e5c2b76 --- /dev/null +++ b/src/osgPlugins/ive/Point.cpp @@ -0,0 +1,62 @@ +/********************************************************************** + * + * FILE: Point.cpp + * + * DESCRIPTION: Read/Write osg::Point in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 27.3.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "Point.h" +#include "Object.h" + +using namespace ive; + +void Point::write(DataOutputStream* out){ + // Write CullFace's identification. + out->writeInt(IVEPOINT); + // If the osg class is inherited by any other class we should also write this to file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->write(out); + } + else + throw Exception("Point::write(): Could not cast this osg::Point to an osg::Object."); + // Write Point's properties. + out->writeFloat(getSize()); + out->writeFloat(getFadeThresholdSize()); + out->writeVec3(getDistanceAttenuation()); + out->writeFloat(getMinSize()); + out->writeFloat(getMaxSize()); +} + +void Point::read(DataInputStream* in){ + // Peek on Point's identification. + int id = in->peekInt(); + if(id == IVEPOINT){ + // Read Point's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->read(in); + } + else + throw Exception("Point::read(): Could not cast this osg::Point to an osg::Object."); + // Read Point's properties + setSize(in->readFloat()); + setFadeThresholdSize(in->readFloat()); + setDistanceAttenuation(in->readVec3()); + setMinSize(in->readFloat()); + setMaxSize(in->readFloat()); + } + else{ + throw Exception("Point::read(): Expected Point identification."); + } +} diff --git a/src/osgPlugins/ive/Point.h b/src/osgPlugins/ive/Point.h new file mode 100644 index 000000000..84d2354f2 --- /dev/null +++ b/src/osgPlugins/ive/Point.h @@ -0,0 +1,15 @@ +#ifndef IVE_POINT +#define IVE_POINT 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class Point : public osg::Point, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/PolygonOffset.cpp b/src/osgPlugins/ive/PolygonOffset.cpp new file mode 100644 index 000000000..ae533bd0c --- /dev/null +++ b/src/osgPlugins/ive/PolygonOffset.cpp @@ -0,0 +1,56 @@ +/********************************************************************** + * + * FILE: PolygonOffset.cpp + * + * DESCRIPTION: Read/Write osg::PolygonOffset in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 27.3.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "PolygonOffset.h" +#include "Object.h" + +using namespace ive; + +void PolygonOffset::write(DataOutputStream* out){ + // Write CullFace's identification. + out->writeInt(IVEPOLYGONOFFSET); + // If the osg class is inherited by any other class we should also write this to file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->write(out); + } + else + throw Exception("PolygonOffset::write(): Could not cast this osg::PolygonOffset to an osg::Object."); + // Write PolygonOffset's properties. + out->writeFloat(getFactor()); + out->writeFloat(getUnits()); +} + +void PolygonOffset::read(DataInputStream* in){ + // Peek on PolygonOffset's identification. + int id = in->peekInt(); + if(id == IVEPOLYGONOFFSET){ + // Read PolygonOffset's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->read(in); + } + else + throw Exception("PolygonOffset::read(): Could not cast this osg::PolygonOffset to an osg::Object."); + // Read PolygonOffset's properties + setFactor(in->readFloat()); + setUnits(in->readFloat()); + } + else{ + throw Exception("PolygonOffset::read(): Expected PolygonOffset identification."); + } +} diff --git a/src/osgPlugins/ive/PolygonOffset.h b/src/osgPlugins/ive/PolygonOffset.h new file mode 100644 index 000000000..9751ffe29 --- /dev/null +++ b/src/osgPlugins/ive/PolygonOffset.h @@ -0,0 +1,15 @@ +#ifndef IVE_POLYGONOFFSET +#define IVE_POLYGONOFFSET 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class PolygonOffset : public osg::PolygonOffset, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/ShadeModel.cpp b/src/osgPlugins/ive/ShadeModel.cpp new file mode 100644 index 000000000..4d0549dfd --- /dev/null +++ b/src/osgPlugins/ive/ShadeModel.cpp @@ -0,0 +1,54 @@ +/********************************************************************** + * + * FILE: ShadeModel.cpp + * + * DESCRIPTION: Read/Write osg::ShadeModel in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 27.3.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "ShadeModel.h" +#include "Object.h" + +using namespace ive; + +void ShadeModel::write(DataOutputStream* out){ + // Write CullFace's identification. + out->writeInt(IVESHADEMODEL); + // If the osg class is inherited by any other class we should also write this to file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->write(out); + } + else + throw Exception("ShadeModel::write(): Could not cast this osg::ShadeModel to an osg::Object."); + // Write ShadeModel's properties. + out->writeInt(getMode()); +} + +void ShadeModel::read(DataInputStream* in){ + // Peek on ShadeModel's identification. + int id = in->peekInt(); + if(id == IVESHADEMODEL){ + // Read ShadeModel's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Object* obj = dynamic_cast(this); + if(obj){ + ((ive::Object*)(obj))->read(in); + } + else + throw Exception("ShadeModel::read(): Could not cast this osg::ShadeModel to an osg::Object."); + // Read ShadeModel's properties + setMode((Mode)in->readInt()); + } + else{ + throw Exception("ShadeModel::read(): Expected ShadeModel identification."); + } +} diff --git a/src/osgPlugins/ive/ShadeModel.h b/src/osgPlugins/ive/ShadeModel.h new file mode 100644 index 000000000..113d46dce --- /dev/null +++ b/src/osgPlugins/ive/ShadeModel.h @@ -0,0 +1,15 @@ +#ifndef IVE_SHADEMODEL +#define IVE_SHADEMODEL 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class ShadeModel : public osg::ShadeModel, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/ive/Switch.cpp b/src/osgPlugins/ive/Switch.cpp new file mode 100644 index 000000000..0de86c39e --- /dev/null +++ b/src/osgPlugins/ive/Switch.cpp @@ -0,0 +1,62 @@ +/********************************************************************** + * + * FILE: Switch.cpp + * + * DESCRIPTION: Read/Write osg::Switch in binary format to disk. + * + * CREATED BY: Auto generated by iveGenerator + * and later modified by Rune Schmidt Jensen. + * + * HISTORY: Created 9.4.2003 + * + * Copyright 2003 VR-C + **********************************************************************/ + +#include "Exception.h" +#include "Switch.h" +#include "Group.h" + +using namespace ive; + +void Switch::write(DataOutputStream* out){ + // Write Switch's identification. + out->writeInt(IVESWITCH); + // If the osg class is inherited by any other class we should also write this to file. + osg::Group* group = dynamic_cast(this); + if(group){ + ((ive::Group*)(group))->write(out); + } + else + throw Exception("Switch::write(): Could not cast this osg::Switch to an osg::Group."); + // Write Switch's properties. + + // Write childrens value. + for(unsigned int i=0; iwriteBool(getValue(i)); + +} + +void Switch::read(DataInputStream* in){ + // Peek on Switch's identification. + int id = in->peekInt(); + if(id == IVESWITCH){ + // Read Switch's identification. + id = in->readInt(); + // If the osg class is inherited by any other class we should also read this from file. + osg::Group* group = dynamic_cast(this); + if(group){ + ((ive::Group*)(group))->read(in); + } + else + throw Exception("Switch::read(): Could not cast this osg::Switch to an osg::Group."); + // Read Switch's properties + + // Read childrens value. + for(unsigned int i=0; ireadBool()); + + } + else{ + throw Exception("Switch::read(): Expected Switch identification."); + } +} diff --git a/src/osgPlugins/ive/Switch.h b/src/osgPlugins/ive/Switch.h new file mode 100644 index 000000000..d34c31e30 --- /dev/null +++ b/src/osgPlugins/ive/Switch.h @@ -0,0 +1,15 @@ +#ifndef IVE_SWITCH +#define IVE_SWITCH 1 + +#include +#include "ReadWrite.h" + +namespace ive{ +class Switch : public osg::Switch, public ReadWrite { +public: + void write(DataOutputStream* out); + void read(DataInputStream* in); +}; +} + +#endif diff --git a/src/osgPlugins/osg/GNUmakefile b/src/osgPlugins/osg/GNUmakefile index 4b2c1b9a0..573d9148d 100644 --- a/src/osgPlugins/osg/GNUmakefile +++ b/src/osgPlugins/osg/GNUmakefile @@ -47,6 +47,7 @@ CXXFILES =\ Sequence.cpp\ Stencil.cpp\ Switch.cpp\ + TessellationHints.cpp\ TexEnv.cpp\ TexEnvCombine.cpp\ TexGen.cpp\ diff --git a/src/osgPlugins/osg/ShapeDrawable.cpp b/src/osgPlugins/osg/ShapeDrawable.cpp index c35089fcd..8cfe7eaee 100644 --- a/src/osgPlugins/osg/ShapeDrawable.cpp +++ b/src/osgPlugins/osg/ShapeDrawable.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -11,17 +12,6 @@ using namespace osgDB; bool ShapeDrawable_readLocalData(Object& obj, Input& fr); bool ShapeDrawable_writeLocalData(const Object& obj, Output& fw); -// //register the read and write functions with the osgDB::Registry. -// RegisterDotOsgWrapperProxy g_ShapeDrawableFuncProxy -// ( -// new osg::ShapeDrawable, -// "ShapeDrawable", -// "Object Drawable ShapeDrawable", -// 0, -// 0, -// DotOsgWrapper::READ_AND_WRITE -// ); - RegisterDotOsgWrapperProxy g_ShapeDrawableFuncProxy ( new osg::ShapeDrawable, @@ -52,6 +42,16 @@ bool ShapeDrawable_readLocalData(Object& obj, Input& fr) iteratorAdvanced = true; } + ref_ptr readObject = fr.readObject(); + if (readObject.valid()) { + TessellationHints* hints = dynamic_cast(readObject.get()); + if (hints) + geom.setTessellationHints(hints); + else + notify(WARN) << "Warning: " << readObject->className() << " loaded but cannot be attached to ShapeDrawable.\n"; + iteratorAdvanced = true; + } + return iteratorAdvanced; } @@ -61,5 +61,9 @@ bool ShapeDrawable_writeLocalData(const Object& obj, Output& fw) fw.indent() << "color " << geom.getColor() << std::endl; + const TessellationHints* hints = geom.getTessellationHints(); + if (hints) + fw.writeObject(*hints); + return true; } diff --git a/src/osgSim/GNUmakefile b/src/osgSim/GNUmakefile index 7942c16c0..7d67e1611 100644 --- a/src/osgSim/GNUmakefile +++ b/src/osgSim/GNUmakefile @@ -9,7 +9,7 @@ CXXFILES = \ LightPointNode.cpp\ Sector.cpp\ Version.cpp\ - + # SphereSegment.cpp\ DEF += -DOSGSIM_LIBRARY diff --git a/src/osgUtil/GNUmakefile b/src/osgUtil/GNUmakefile index e62035879..39adbab6f 100644 --- a/src/osgUtil/GNUmakefile +++ b/src/osgUtil/GNUmakefile @@ -21,6 +21,7 @@ CXXFILES = \ SmoothingVisitor.cpp\ Tesselator.cpp\ TransformCallback.cpp\ + TransformAttributeFunctor.cpp\ TriStripVisitor.cpp\ TriStrip_tri_stripper.cpp\ CubeMapGenerator.cpp\ diff --git a/src/osgUtil/Optimizer.cpp b/src/osgUtil/Optimizer.cpp index 48df6660b..04e8b3456 100644 --- a/src/osgUtil/Optimizer.cpp +++ b/src/osgUtil/Optimizer.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -25,6 +24,8 @@ #include #include +#include + #include #include #include @@ -497,7 +498,7 @@ void CollectLowestTransformsVisitor::doTransform(osg::Object* obj,osg::Matrix& m osg::Drawable* drawable = dynamic_cast(obj); if (drawable) { - osg::TransformAttributeFunctor tf(matrix); + osgUtil::TransformAttributeFunctor tf(matrix); drawable->accept(tf); drawable->dirtyBound(); return; @@ -532,7 +533,7 @@ void CollectLowestTransformsVisitor::doTransform(osg::Object* obj,osg::Matrix& m osg::Matrix matrix_no_trans = matrix; matrix_no_trans.setTrans(0.0f,0.0f,0.0f); - osg::TransformAttributeFunctor tf(matrix_no_trans); + osgUtil::TransformAttributeFunctor tf(matrix_no_trans); osg::Vec3 axis = osg::Matrix::transform3x3(tf._im,billboard->getAxis()); axis.normalize(); diff --git a/src/osgUtil/TransformAttributeFunctor.cpp b/src/osgUtil/TransformAttributeFunctor.cpp new file mode 100644 index 000000000..cbfcc7973 --- /dev/null +++ b/src/osgUtil/TransformAttributeFunctor.cpp @@ -0,0 +1,48 @@ +/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield + * + * This library is open source and may be redistributed and/or modified under + * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or + * (at your option) any later version. The full license is in LICENSE file + * included with this distribution, and on the openscenegraph.org website. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * OpenSceneGraph Public License for more details. +*/ + +#include + +using namespace osgUtil; + +TransformAttributeFunctor::TransformAttributeFunctor(const osg::Matrix& m) +{ + _m = m; + _im.invert(_m); +} + +TransformAttributeFunctor::~TransformAttributeFunctor() +{ +} + +void TransformAttributeFunctor::apply(osg::Drawable::AttributeType type,unsigned int count,osg::Vec3* begin) +{ + if (type == osg::Drawable::VERTICES) + { + osg::Vec3* end = begin+count; + for (osg::Vec3* itr=begin;itr