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"
This commit is contained in:
Robert Osfield 2011-09-19 10:34:31 +00:00
parent 6e01f05853
commit 8a230d42ed
7 changed files with 29 additions and 11 deletions

View File

@ -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
{

View File

@ -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.

View File

@ -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();

View File

@ -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();

View File

@ -289,7 +289,7 @@ void daeWriter::apply( osg::LOD &node )
domTechnique *teq = daeSafeCast<domTechnique>(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());

View File

@ -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

View File

@ -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