From 8a230d42edb2cf6e1d96d90c774bf02f0d8de451 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 19 Sep 2011 10:34:31 +0000 Subject: [PATCH] From Luc Frauciel, "You'll find attached a new option that allow, when using LOD in USER_DEFINED_CENTER mode to expand the radius of the node by the radius of loaded objets. Motivation ; When using PagedLODs, you don't always know the real size of loaded children, If it occurs that they are out of predefined bounds, picking on the parts that are out of bound will fail They also can be culled out too soon. The problem often occurs with long object (roads). I've modified LOD and ProxyNode to include this option." and later email: "Attached the UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED version There are impacts on some serializers (dae, osgWrapper). I haven't modified deprecated osg, since it's deprecated" --- include/osg/LOD | 9 ++++----- include/osg/ProxyNode | 7 ++++--- src/osg/LOD.cpp | 8 ++++++++ src/osg/ProxyNode.cpp | 8 ++++++++ src/osgPlugins/dae/daeWSceneObjects.cpp | 2 +- src/osgWrappers/serializers/osg/LOD.cpp | 3 ++- src/osgWrappers/serializers/osg/ProxyNode.cpp | 3 ++- 7 files changed, 29 insertions(+), 11 deletions(-) diff --git a/include/osg/LOD b/include/osg/LOD index 732de9819..35a3aa917 100644 --- a/include/osg/LOD +++ b/include/osg/LOD @@ -61,7 +61,8 @@ class OSG_EXPORT LOD : public Group enum CenterMode { USE_BOUNDING_SPHERE_CENTER, - USER_DEFINED_CENTER + USER_DEFINED_CENTER, + UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED }; /** Set how the center of object should be determined when computing which child is active.*/ @@ -72,10 +73,10 @@ class OSG_EXPORT LOD : public Group /** Sets the object-space point which defines the center of the osg::LOD. center is affected by any transforms in the hierarchy above the osg::LOD.*/ - inline void setCenter(const vec_type& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; } + inline void setCenter(const vec_type& center) { if (_centerMode!=UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED) { _centerMode=USER_DEFINED_CENTER; } _userDefinedCenter = center; } /** return the LOD center point. */ - inline const vec_type& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); } + inline const vec_type& getCenter() const { if ((_centerMode==USER_DEFINED_CENTER)||(_centerMode==UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED)) return _userDefinedCenter; else return getBound().center(); } /** Set the object-space reference radius of the volume enclosed by the LOD. @@ -85,8 +86,6 @@ class OSG_EXPORT LOD : public Group /** Get the object-space radius of the volume enclosed by the LOD.*/ inline value_type getRadius() const { return _radius; } - - /** Modes that control how the range values should be interpreted when computing which child is active.*/ enum RangeMode { diff --git a/include/osg/ProxyNode b/include/osg/ProxyNode index a9d5c233e..8a54aabc9 100644 --- a/include/osg/ProxyNode +++ b/include/osg/ProxyNode @@ -75,7 +75,8 @@ class OSG_EXPORT ProxyNode : public Group enum CenterMode { USE_BOUNDING_SPHERE_CENTER, - USER_DEFINED_CENTER + USER_DEFINED_CENTER, + UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED }; /** Set how the center of object should be determined when computed which child is active.*/ @@ -100,10 +101,10 @@ class OSG_EXPORT ProxyNode : public Group /** Sets the object-space point which defines the center of the osg::ProxyNode. center is affected by any transforms in the hierarchy above the osg::ProxyNode.*/ - inline void setCenter(const Vec3& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; } + inline void setCenter(const vec_type& center) { if (_centerMode!=UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED) { _centerMode=USER_DEFINED_CENTER; } _userDefinedCenter = center; } /** return the ProxyNode center point. */ - inline const vec_type& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); } + inline const vec_type& getCenter() const { if ((_centerMode==USER_DEFINED_CENTER)||(_centerMode==UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED)) return _userDefinedCenter; else return getBound().center(); } /** Set the object-space reference radius of the volume enclosed by the ProxyNode. diff --git a/src/osg/LOD.cpp b/src/osg/LOD.cpp index 61fdb676a..a3362ebcd 100644 --- a/src/osg/LOD.cpp +++ b/src/osg/LOD.cpp @@ -90,6 +90,14 @@ BoundingSphere LOD::computeBound() const { return BoundingSphere(_userDefinedCenter,_radius); } + else if (_centerMode==UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED && _radius>=0.0f) + { + BoundingSphere bs = BoundingSphere(_userDefinedCenter,_radius); + bs.expandBy(Group::computeBound()); + //alternative (used in TxpPagedLOD) + // bs.expandRadiusBy(Group::computeBound()); + return bs; + } else { return Group::computeBound(); diff --git a/src/osg/ProxyNode.cpp b/src/osg/ProxyNode.cpp index d6432022b..57904256e 100644 --- a/src/osg/ProxyNode.cpp +++ b/src/osg/ProxyNode.cpp @@ -110,6 +110,14 @@ BoundingSphere ProxyNode::computeBound() const { return BoundingSphere(_userDefinedCenter,_radius); } + else if (_centerMode==UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED && _radius>=0.0f) + { + BoundingSphere bs = BoundingSphere(_userDefinedCenter,_radius); + bs.expandBy(Group::computeBound()); + //alternative (used in TxpPagedLOD) + // bs.expandRadiusBy(Group::computeBound()); + return bs; + } else { return Group::computeBound(); diff --git a/src/osgPlugins/dae/daeWSceneObjects.cpp b/src/osgPlugins/dae/daeWSceneObjects.cpp index fa05bcc17..adaa515e6 100644 --- a/src/osgPlugins/dae/daeWSceneObjects.cpp +++ b/src/osgPlugins/dae/daeWSceneObjects.cpp @@ -289,7 +289,7 @@ void daeWriter::apply( osg::LOD &node ) domTechnique *teq = daeSafeCast(extra->add( COLLADA_ELEMENT_TECHNIQUE ) ); teq->setProfile( "OpenSceneGraph" ); - if (node.getCenterMode()==osg::LOD::USER_DEFINED_CENTER) + if ((node.getCenterMode()==osg::LOD::USER_DEFINED_CENTER)||(node.getCenterMode()==osg::LOD::UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED)) { domAny *center = (domAny*)teq->add("Center"); center->setValue(toString(node.getCenter()).c_str()); diff --git a/src/osgWrappers/serializers/osg/LOD.cpp b/src/osgWrappers/serializers/osg/LOD.cpp index 47b0d10d8..e042962e4 100644 --- a/src/osgWrappers/serializers/osg/LOD.cpp +++ b/src/osgWrappers/serializers/osg/LOD.cpp @@ -6,7 +6,7 @@ // _userDefinedCenter, _radius static bool checkUserCenter( const osg::LOD& node ) { - return node.getCenterMode()==osg::LOD::USER_DEFINED_CENTER; + return (node.getCenterMode()==osg::LOD::USER_DEFINED_CENTER)||(node.getCenterMode()==osg::LOD::UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED); } static bool readUserCenter( osgDB::InputStream& is, osg::LOD& node ) @@ -63,6 +63,7 @@ REGISTER_OBJECT_WRAPPER( LOD, BEGIN_ENUM_SERIALIZER( CenterMode, USE_BOUNDING_SPHERE_CENTER ); ADD_ENUM_VALUE( USE_BOUNDING_SPHERE_CENTER ); ADD_ENUM_VALUE( USER_DEFINED_CENTER ); + ADD_ENUM_VALUE( UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED ); END_ENUM_SERIALIZER(); // _centerMode ADD_USER_SERIALIZER( UserCenter ); // _userDefinedCenter, _radius diff --git a/src/osgWrappers/serializers/osg/ProxyNode.cpp b/src/osgWrappers/serializers/osg/ProxyNode.cpp index a82991920..bfee2cd98 100644 --- a/src/osgWrappers/serializers/osg/ProxyNode.cpp +++ b/src/osgWrappers/serializers/osg/ProxyNode.cpp @@ -80,7 +80,7 @@ static bool writeChildren( osgDB::OutputStream& os, const osg::ProxyNode& node ) // _userDefinedCenter, _radius static bool checkUserCenter( const osg::ProxyNode& node ) { - return node.getCenterMode()==osg::ProxyNode::USER_DEFINED_CENTER; + return (node.getCenterMode()==osg::ProxyNode::USER_DEFINED_CENTER)||(node.getCenterMode()==osg::ProxyNode::UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED); } static bool readUserCenter( osgDB::InputStream& is, osg::ProxyNode& node ) @@ -117,6 +117,7 @@ REGISTER_OBJECT_WRAPPER( ProxyNode, BEGIN_ENUM_SERIALIZER( CenterMode, USE_BOUNDING_SPHERE_CENTER ); ADD_ENUM_VALUE( USE_BOUNDING_SPHERE_CENTER ); ADD_ENUM_VALUE( USER_DEFINED_CENTER ); + ADD_ENUM_VALUE( UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED ); END_ENUM_SERIALIZER(); // _centerMode ADD_USER_SERIALIZER( UserCenter ); // _userDefinedCenter, _radius