diff --git a/TODO b/TODO index eaae87624..b13eae008 100644 --- a/TODO +++ b/TODO @@ -35,7 +35,6 @@ o Core OSG Library . add support for Multi-texturing into osg::GeoSet/osg::GeoState. . add support for pixel/vertex shaders into osg::GeoSet/osg::GeoState. . utilise stl vectors for osg::GeoSets? - . add handling of memory of osg::GeoSet's attributes. . add osg::Terrain node. . add proxy node for lazy loading of nodes, when needed. . implement visual proximity to assist loading of proxied data @@ -44,13 +43,11 @@ o Core OSG Library . implement support for modified status/lazy evaluation of node data and observer style pattern. . manipulator decoration nodes? - . spacial subdivision decoration nodes? - - . improved osgUtil:TriStringVisitor to replace NvTriStrip code. + . spacial subdivision decoration nodes? + . improved osgUtil:TriStripVisitor to replace NvTriStrip code. . update of osgText to latest FTGL. . create osg::Drawable::PrimtiveFunrctor . support for volume rendering. - . improved stereo support. . occlusion culling. . integrated osgEnv. . implement a osg::CameraRelativeNode for earth sky/HUD's etc. @@ -62,13 +59,10 @@ o Core OSG Library . osgParticles - support for particle effects. . osgAnimation - support for skinning etc. . osgShader - suppor for shader languages. - . improved makefiles. . improved impostor implementation - use depth textures? . clean up multi-bin control. - . improve the node callback mechanism. . osgUtil::MultiSceneView/Multi-channel configuration. . support for node kits via the plugins mechanism. - . Added tracking of matrix stacks in osg::State. . Added ImageGroup's which can be attached to textures for animation. - Visitors @@ -109,9 +103,7 @@ o Under development Sign up here if would like to take on a task :-) - add osg::Billboard for trees etc. - - full maths support in osg::Matrix class. - Netscape plug-in. - - CVS support for when source is made fully public. - Mac port. - tri stripping visitor. - .obj Alias wavefront's format.(functioning already.) @@ -168,3 +160,10 @@ o Work completed - return error messages of on failed loading/saving. - .bmp Windows Bitmap files. - .tar Automatic unpacking of directories and loading of contents. + - add handling of memory of osg::GeoSet's attributes. + - Added tracking of matrix stacks in osg::State. + - improved stereo support. + - improved makefiles. + - improve the node callback mechanism. + - CVS support for when source is made fully public. + - full maths support in osg::Matrix class. diff --git a/include/osg/AnimationPath b/include/osg/AnimationPath index 36f62686e..6caa6fba4 100644 --- a/include/osg/AnimationPath +++ b/include/osg/AnimationPath @@ -7,22 +7,34 @@ #include #include +#include #include namespace osg { -/** Animation Path for specify the time varying transformation pathway to use when update camera and model objects. +/** AnimationPath for specify the time varying transformation pathway to use when update camera and model objects. + * Subclassed from Transform::ComputeTransformCallback allows AnimationPath to + * be attached directly to Transform nodes to move subgraphs around the scene. */ -class SG_EXPORT AnimationPath : public osg::Referenced +class SG_EXPORT AnimationPath : public Transform::ComputeTransformCallback { public: AnimationPath() {} + + /** get the local transformation matrix for a point in time.*/ + virtual bool getMatrix(double time,Matrix& matrix) const; + + /** get the local inverse transformation matrix for a point in time.*/ + virtual bool getInverse(double time,Matrix& matrix) const; - virtual bool getMatrix(double time,Matrix& matrix); - virtual bool getInverse(double time,Matrix& matrix); - + /** Get the transformation matrix which moves from local coords to world coords.*/ + virtual const bool computeLocalToWorldMatrix(Matrix& matrix,const Transform* transform, NodeVisitor* nv) const; + + /** Get the transformation matrix which moves from world coords to local coords.*/ + virtual const bool computeWorldToLocalMatrix(Matrix& matrix,const Transform* transform, NodeVisitor* nv) const; + struct Key { Key() {} @@ -44,14 +56,14 @@ class SG_EXPORT AnimationPath : public osg::Referenced _scale = first._scale*one_minus_ratio + second._scale*ratio; } - inline void getMatrix(Matrix& matrix) + inline void getMatrix(Matrix& matrix) const { matrix.makeScale(_scale); matrix.postMult(_rotation.getMatrix()); matrix.postMult(osg::Matrix::translate(_position)); } - inline void getInverse(Matrix& matrix) + inline void getInverse(Matrix& matrix) const { matrix.makeScale(1.0f/_scale.x(),1.0f/_scale.y(),1.0f/_scale.y()); matrix.postMult(_rotation.inverse().getMatrix()); diff --git a/src/osg/AnimationPath.cpp b/src/osg/AnimationPath.cpp index 1c333fe3a..31338811e 100644 --- a/src/osg/AnimationPath.cpp +++ b/src/osg/AnimationPath.cpp @@ -1,4 +1,5 @@ #include +#include using namespace osg; @@ -7,18 +8,18 @@ void AnimationPath::insert(double time,const Key& key) _timeKeyMap[time] = key; } -bool AnimationPath::getMatrix(double time,Matrix& matrix) +bool AnimationPath::getMatrix(double time,Matrix& matrix) const { if (_timeKeyMap.empty()) return false; - TimeKeyMap::iterator second = _timeKeyMap.lower_bound(time); + TimeKeyMap::const_iterator second = _timeKeyMap.lower_bound(time); if (second==_timeKeyMap.begin()) { second->second.getMatrix(matrix); } else if (second!=_timeKeyMap.end()) { - TimeKeyMap::iterator first = second; + TimeKeyMap::const_iterator first = second; --first; // we have both a lower bound and the next item. @@ -44,18 +45,18 @@ bool AnimationPath::getMatrix(double time,Matrix& matrix) return true; } -bool AnimationPath::getInverse(double time,Matrix& matrix) +bool AnimationPath::getInverse(double time,Matrix& matrix) const { if (_timeKeyMap.empty()) return false; - TimeKeyMap::iterator second = _timeKeyMap.lower_bound(time); + TimeKeyMap::const_iterator second = _timeKeyMap.lower_bound(time); if (second==_timeKeyMap.begin()) { second->second.getInverse(matrix); } else if (second!=_timeKeyMap.end()) { - TimeKeyMap::iterator first = second; + TimeKeyMap::const_iterator first = second; --first; // we have both a lower bound and the next item. @@ -80,3 +81,36 @@ bool AnimationPath::getInverse(double time,Matrix& matrix) } return true; } + +const bool AnimationPath::computeLocalToWorldMatrix(Matrix& matrix,const Transform*, NodeVisitor* nv) const +{ + if (nv) + { + const osg::FrameStamp* fs = nv->getFrameStamp(); + if (fs) + { + osg::Matrix localMatrix; + getMatrix(fs->getReferenceTime(),localMatrix); + matrix.preMult(localMatrix); + return true; + } + } + return false; +} + +/** Get the transformation matrix which moves from world coords to local coords.*/ +const bool AnimationPath::computeWorldToLocalMatrix(Matrix& matrix,const Transform* , NodeVisitor* nv) const +{ + if (nv) + { + const osg::FrameStamp* fs = nv->getFrameStamp(); + if (fs) + { + osg::Matrix localInverse; + getInverse(fs->getReferenceTime(),localInverse); + matrix.postMult(localInverse); + return true; + } + } + return false; +} diff --git a/src/osg/State.cpp b/src/osg/State.cpp index 188bc817d..08abb2c57 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -33,7 +33,8 @@ void State::reset() _modeMap.clear(); _modeMap[GL_DEPTH_TEST].global_default_value = true; - + _modeMap[GL_DEPTH_TEST].changed = true; + // go through all active StateAttribute's, applying where appropriate. for(AttributeMap::iterator aitr=_attributeMap.begin(); aitr!=_attributeMap.end(); diff --git a/src/osg/StateSet.cpp b/src/osg/StateSet.cpp index 49e4421e0..8c8bee289 100644 --- a/src/osg/StateSet.cpp +++ b/src/osg/StateSet.cpp @@ -130,6 +130,7 @@ void StateSet::setGlobalDefaults() setRendingBinToInherit(); + setMode(GL_DEPTH_TEST,StateAttribute::ON); setAttributeAndModes(osgNew AlphaFunc,StateAttribute::OFF); setAttributeAndModes(osgNew Transparency,StateAttribute::OFF); diff --git a/src/osgGLUT/Viewer.cpp b/src/osgGLUT/Viewer.cpp index 581ec0aa6..0a61188f6 100644 --- a/src/osgGLUT/Viewer.cpp +++ b/src/osgGLUT/Viewer.cpp @@ -243,7 +243,7 @@ bool Viewer::open() ++itr) { osgUtil::RenderStage *stage = itr->sceneView->getRenderStage(); - stage->setClearMask(clear_mask); + if (stage) stage->setClearMask(clear_mask); } @@ -767,6 +767,7 @@ void Viewer::mouse(int button, int state, int x, int y) } + void Viewer::keyboard(unsigned char key, int x, int y) { osg::ref_ptr ea = osgNew GLUTEventAdapter; @@ -775,6 +776,8 @@ void Viewer::keyboard(unsigned char key, int x, int y) if (_viewportList[_focusedViewport]._cameraManipulator->handle(*ea,*this)) return; + + if (key>='1' && key<='3') { int pos = key-'1'; @@ -782,6 +785,12 @@ void Viewer::keyboard(unsigned char key, int x, int y) } osgUtil::SceneView* sceneView = getViewportSceneView(_focusedViewport); + osg::StateSet* globalStateSet = sceneView->getGlobalStateSet(); + if (!globalStateSet) + { + globalStateSet = osgNew osg::StateSet; + sceneView->setGlobalStateSet(globalStateSet); + } switch( key ) { @@ -881,7 +890,7 @@ void Viewer::keyboard(unsigned char key, int x, int y) case 's' : { flat_shade = 1 - flat_shade ; - osg::StateSet* stateset = sceneView->getGlobalStateSet(); + osg::StateSet* stateset = globalStateSet; osg::ShadeModel* shademodel = dynamic_cast(stateset->getAttribute(osg::StateAttribute::SHADEMODEL)); if (!shademodel) { @@ -920,18 +929,18 @@ void Viewer::keyboard(unsigned char key, int x, int y) backface = 1 - backface; if( backface ) - sceneView->getGlobalStateSet()->setMode(GL_CULL_FACE,osg::StateAttribute::ON); + globalStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::ON); else - sceneView->getGlobalStateSet()->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE_OFF); + globalStateSet->setMode(GL_CULL_FACE,osg::StateAttribute::OVERRIDE_OFF); break; case 'l' : lighting = 1 - lighting ; if( lighting ) - sceneView->getGlobalStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_ON); + globalStateSet->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_ON); else - sceneView->getGlobalStateSet()->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_OFF); + globalStateSet->setMode(GL_LIGHTING,osg::StateAttribute::OVERRIDE_OFF); break; case 'L' : @@ -950,8 +959,8 @@ void Viewer::keyboard(unsigned char key, int x, int y) texture = 1 - texture; if (texture) { - sceneView->getGlobalStateSet()->setModeToInherit(GL_TEXTURE_2D); -// sceneView->getGlobalStateSet()->setAttributeToInherit(osg::StateAttribute::TEXTURE); + globalStateSet->setModeToInherit(GL_TEXTURE_2D); +// globalStateSet->setAttributeToInherit(osg::StateAttribute::TEXTURE); } else { @@ -959,18 +968,18 @@ void Viewer::keyboard(unsigned char key, int x, int y) // thus causing them to all use the same texture attribute, hence // preventing a state attribute change due to unused textures. static osg::ref_ptr blank_texture = osgNew osg::Texture; - sceneView->getGlobalStateSet()->setMode(GL_TEXTURE_2D,osg::StateAttribute::OVERRIDE_OFF); -// sceneView->getGlobalStateSet()->setAttribute(blank_texture.get(),true); + globalStateSet->setMode(GL_TEXTURE_2D,osg::StateAttribute::OVERRIDE_OFF); +// globalStateSet->setAttribute(blank_texture.get(),true); } break; case 'T' : { - osg::LightModel* lightmodel = dynamic_cast(sceneView->getGlobalStateSet()->getAttribute(osg::StateAttribute::LIGHTMODEL)); + osg::LightModel* lightmodel = dynamic_cast(globalStateSet->getAttribute(osg::StateAttribute::LIGHTMODEL)); if (lightmodel) { lightmodel = osgNew osg::LightModel; - sceneView->getGlobalStateSet()->setAttribute(lightmodel); + globalStateSet->setAttribute(lightmodel); } lightmodel->setTwoSided(!lightmodel->getTwoSided()); } @@ -981,7 +990,7 @@ void Viewer::keyboard(unsigned char key, int x, int y) polymode = (polymode+1)%3; osg::PolygonMode* polyModeObj = osgNew osg::PolygonMode; polyModeObj->setMode(osg::PolygonMode::FRONT_AND_BACK,polymodes[polymode]); - sceneView->getGlobalStateSet()->setAttribute(polyModeObj); + globalStateSet->setAttribute(polyModeObj); } break; diff --git a/src/osgUtil/SceneView.cpp b/src/osgUtil/SceneView.cpp index a13ae402e..09d33bf45 100644 --- a/src/osgUtil/SceneView.cpp +++ b/src/osgUtil/SceneView.cpp @@ -158,8 +158,30 @@ void SceneView::app() void SceneView::cull() { + if (!_state) + { + osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView::_state attached, creating a default state automatically."<< std::endl; + + // note the constructor for osg::State will set ContextID to 0 which will be fine to single context graphics + // applications which is ok for most apps, but not multiple context/pipe applications. + _state = osgNew osg::State; + } + + if (!_globalState) + { + osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView::_globalState attached, creating a default global stateset automatically."<< std::endl; + + _globalState = osgNew osg::StateSet; + _globalState->setGlobalDefaults(); + } + + // we in theory should be able to be able to bypass reset, but we'll call it just incase. _state->reset(); + _state->setFrameStamp(_frameStamp.get()); + _state->setDisplaySettings(_displaySettings.get()); + + osg::ref_ptr projection = _projectionMatrix.get(); osg::ref_ptr modelview = _modelviewMatrix.get(); @@ -238,6 +260,22 @@ void SceneView::cull() } else { + if (!_cullVisitor) + { + osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a default CullVisitor automatically."<< std::endl; + _cullVisitor = osgNew CullVisitor; + } + if (!_rendergraph) + { + osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView:: attached, creating a global default RenderGraph automatically."<< std::endl; + _rendergraph = osgNew RenderGraph; + } + if (!_renderStage) + { + osg::notify(osg::INFO) << "Warning: no valid osgUtil::SceneView::_renderStage attached, creating a default RenderStage automatically."<< std::endl; + _renderStage = osgNew RenderStage; + } + _cullVisitor->setTraversalMask(_cullMask); cullStage(projection.get(),modelview.get(),_cullVisitor.get(),_rendergraph.get(),_renderStage.get()); } @@ -256,20 +294,6 @@ void SceneView::cullStage(osg::Matrix* projection,osg::Matrix* modelview,osgUtil if (!_initCalled) init(); - if (!_state) - { - osg::notify(osg::WARN) << "Warning: no valid osgUtil::SceneView::_state"<< std::endl; - osg::notify(osg::WARN) << " creating a state automatically."<< std::endl; - - // note the constructor for osg::State will set ContextID to 0. - _state = osgNew osg::State; - } - - // we in theory should be able to be able to bypass reset, but we'll call it just incase. - _state->reset(); - - _state->setFrameStamp(_frameStamp.get()); - _state->setDisplaySettings(_displaySettings.get());