Added ViewPoint support into NodeVistor/CullStack/CullVisitor/LOD/PagedLOD etc to facilate

management of LOD settings for RTT cameras.
This commit is contained in:
Robert Osfield 2006-12-15 17:27:18 +00:00
parent d88b996df1
commit 982a4db9e2
13 changed files with 116 additions and 79 deletions

View File

@ -36,6 +36,8 @@ class OSG_EXPORT CollectOccludersVisitor : public osg::NodeVisitor, public osg::
virtual void reset();
virtual float getDistanceToEyePoint(const Vec3& pos, bool withLODScale) const;
virtual float getDistanceToViewPoint(const Vec3& pos, bool withLODScale) const;
virtual float getDistanceFromEyePoint(const Vec3& pos, bool withLODScale) const;
virtual void apply(osg::Node&);

View File

@ -134,9 +134,15 @@ class OSG_EXPORT CullStack : public osg::CullSettings
inline osg::RefMatrix& getProjectionMatrix();
inline osg::Matrix getWindowMatrix();
inline const osg::RefMatrix& getMVPW();
inline const osg::Vec3& getReferenceViewPoint() const { return _referenceViewPoints.back(); }
inline void pushReferenceViewPoint(const osg::Vec3& viewPoint) { _referenceViewPoints.push_back(viewPoint); }
inline void popReferenceViewPoint() { _referenceViewPoints.pop_back(); }
inline const osg::Vec3& getEyeLocal() const { return _eyePointStack.back(); }
inline const osg::Vec3& getViewPointLocal() const { return _viewPointStack.back(); }
inline const osg::Vec3 getUpLocal() const
{
const osg::Matrix& matrix = *_modelviewStack.back();
@ -149,6 +155,8 @@ class OSG_EXPORT CullStack : public osg::CullSettings
return osg::Vec3(-matrix(0,2),-matrix(1,2),-matrix(2,2));
}
protected:
void pushCullingSet();
@ -168,7 +176,9 @@ class OSG_EXPORT CullStack : public osg::CullSettings
ViewportStack _viewportStack;
typedef fast_back_stack<Vec3> EyePointStack;
EyePointStack _referenceViewPoints;
EyePointStack _eyePointStack;
EyePointStack _viewPointStack;
CullingStack _clipspaceCullingStack;
CullingStack _projectionCullingStack;

View File

@ -207,6 +207,10 @@ class OSG_EXPORT NodeVisitor : public virtual Referenced
* Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.*/
virtual osg::Vec3 getEyePoint() const { return Vec3(0.0f,0.0f,0.0f); }
/** Get the view point in local coordinates.
* Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.*/
virtual osg::Vec3 getViewPoint() const { return getEyePoint(); }
/** Get the distance from a point to the eye point, distance value in local coordinate system.
* Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.
* If the getDistanceFromEyePoint(pos) is not implemented then a default value of 0.0 is returned.*/
@ -217,6 +221,12 @@ class OSG_EXPORT NodeVisitor : public virtual Referenced
* If the getDistanceFromEyePoint(pos) is not implemented than a default value of 0.0 is returned.*/
virtual float getDistanceFromEyePoint(const Vec3& /*pos*/, bool /*useLODScale*/) const { return 0.0f; }
/** Get the distance from a point to the view point, distance value in local coordinate system.
* Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement.
* If the getDistanceToViewPoint(pos) is not implemented then a default value of 0.0 is returned.*/
virtual float getDistanceToViewPoint(const Vec3& /*pos*/, bool /*useLODScale*/) const { return 0.0f; }
virtual void apply(Node& node) { traverse(node);}
virtual void apply(Geode& node) { apply((Node&)node); }

View File

@ -60,9 +60,13 @@ class OSGUTIL_EXPORT CullVisitor : public osg::NodeVisitor, public osg::CullStac
virtual void reset();
virtual osg::Vec3 getEyePoint() const { return getEyeLocal(); }
virtual osg::Vec3 getViewPoint() const { return getViewPointLocal(); }
virtual float getDistanceToEyePoint(const osg::Vec3& pos, bool withLODScale) const;
virtual float getDistanceFromEyePoint(const osg::Vec3& pos, bool withLODScale) const;
virtual float getDistanceToViewPoint(const osg::Vec3& pos, bool withLODScale) const;
virtual void apply(osg::Node&);
virtual void apply(osg::Geode& node);
virtual void apply(osg::Billboard& node);

View File

@ -52,6 +52,12 @@ float CollectOccludersVisitor::getDistanceToEyePoint(const Vec3& pos, bool withL
else return (pos-getEyeLocal()).length();
}
float CollectOccludersVisitor::getDistanceToViewPoint(const Vec3& pos, bool withLODScale) const
{
if (withLODScale) return (pos-getViewPointLocal()).length()*getLODScale();
else return (pos-getViewPointLocal()).length();
}
float CollectOccludersVisitor::getDistanceFromEyePoint(const Vec3& pos, bool withLODScale) const
{
const Matrix& matrix = *_modelviewStack.back();

View File

@ -25,6 +25,8 @@ CullStack::CullStack()
_index_modelviewCullingStack = 0;
_back_modelviewCullingStack = 0;
_referenceViewPoints.push_back(osg::Vec3(0.0f,0.0f,0.0f));
}
@ -42,7 +44,12 @@ void CullStack::reset()
_projectionStack.clear();
_modelviewStack.clear();
_viewportStack.clear();
_referenceViewPoints.clear();
_referenceViewPoints.push_back(osg::Vec3(0.0f,0.0f,0.0f));
_eyePointStack.clear();
_viewPointStack.clear();
_clipspaceCullingStack.clear();
@ -60,7 +67,7 @@ void CullStack::reset()
_bbCornerNear = (~_bbCornerFar)&7;
_currentReuseMatrixIndex=0;
_currentReuseMatrixIndex=0;
}
@ -186,76 +193,13 @@ void CullStack::pushModelViewMatrix(RefMatrix* matrix)
pushCullingSet();
#if 1
osg::Vec3f slow_eyepoint = osg::Matrix::inverse(*matrix).getTrans();
_eyePointStack.push_back(slow_eyepoint);
#else
// fast method for computing the eye point in local coords which doesn't require the inverse matrix.
const float x_0 = (*matrix)(0,0);
const float x_1 = (*matrix)(1,0);
const float x_2 = (*matrix)(2,0);
const float x_len2 = (x_0*x_0+x_1*x_1+x_2*x_2);
osg::Matrix inv;
inv.invert(*matrix);
const float y_0 = (*matrix)(0,1);
const float y_1 = (*matrix)(1,1);
const float y_2 = (*matrix)(2,1);
const float y_len2 = (y_0*y_0+y_1*y_1+y_2*y_2);
const float z_0 = (*matrix)(0,2);
const float z_1 = (*matrix)(1,2);
const float z_2 = (*matrix)(2,2);
const float z_len2 = (z_0*z_0+z_1*z_1+z_2*z_2);
_eyePointStack.push_back(inv.getTrans());
_viewPointStack.push_back(getReferenceViewPoint() * inv);
bool useFastPath = (osg::equivalent(x_len2,y_len2) &&
osg::equivalent(x_len2,z_len2) &&
osg::equivalent(y_len2,z_len2));
// std::cout<<"x_len2 = "<<x_len2 << "\ty_len2 = "<<y_len2 << "\tz_len2 = "<<z_len2 << std::endl;
if (useFastPath)
{
const float xyz_len0 = x_0*x_0 + y_0*y_0 + z_0*z_0;
const float xyz_len1 = x_1*x_1 + y_1*y_1 + z_1*z_1;
const float xyz_len2 = x_2*x_2 + y_2*y_2 + z_2*z_2;
// std::cout<<"xyz_len0 = "<<xyz_len0 << "\txyz_len2 = "<<xyz_len1 << "\txyz_len2 = "<<xyz_len2 << std::endl;
if (!osg::equivalent(xyz_len0,xyz_len1) ||
!osg::equivalent(xyz_len0,xyz_len2) ||
!osg::equivalent(xyz_len1,xyz_len2)) useFastPath = false;
}
if (useFastPath)
{
// compute the eye point in local coords using a fast technique
// which assumes that only proportional scaling, no shearing, this
// is satisfied for most scene graph usage.
const float x_scale = (*matrix)(3,0) / -x_len2;
const float y_scale = (*matrix)(3,1) / -y_len2;
const float z_scale = (*matrix)(3,2) / -z_len2;
osg::Vec3 fast_eyepoint(x_0*x_scale + y_0*y_scale + z_0*z_scale,
x_1*x_scale + y_1*y_scale + z_1*z_scale,
x_2*x_scale + y_2*y_scale + z_2*z_scale);
}
else
{
// shearing or no proportional scaling has been detected so we
// callback to compute the inverse of the model view matrix and
// transforming the eye point into local coords. This is ten
// to thirty times slower than the above fast path.
osg::Vec3 slow_eyepoint(osg::Matrix::inverse(*matrix).getTrans());
_eyePointStack.push_back(slow_eyepoint);
}
#endif
osg::Vec3 lookVector = getLookVectorLocal();
_bbCornerFar = (lookVector.x()>=0?1:0) |
@ -269,7 +213,10 @@ void CullStack::pushModelViewMatrix(RefMatrix* matrix)
void CullStack::popModelViewMatrix()
{
_modelviewStack.pop_back();
_eyePointStack.pop_back();
_viewPointStack.pop_back();
popCullingSet();

View File

@ -47,7 +47,7 @@ void LOD::traverse(NodeVisitor& nv)
float required_range = 0;
if (_rangeMode==DISTANCE_FROM_EYE_POINT)
{
required_range = nv.getDistanceToEyePoint(getCenter(),true);
required_range = nv.getDistanceToViewPoint(getCenter(),true);
}
else
{

View File

@ -119,7 +119,7 @@ void PagedLOD::traverse(NodeVisitor& nv)
float required_range = 0;
if (_rangeMode==DISTANCE_FROM_EYE_POINT)
{
required_range = nv.getDistanceToEyePoint(getCenter(),true);
required_range = nv.getDistanceToViewPoint(getCenter(),true);
}
else
{

View File

@ -54,6 +54,7 @@ bool View::addSlave(osg::Camera* camera, const osg::Matrix& projectionOffset, co
{
if (!camera) return false;
camera->setView(this);
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
if (_camera.valid())

View File

@ -153,11 +153,14 @@ float CullVisitor::getDistanceToEyePoint(const Vec3& pos, bool withLODScale) con
else return (pos-getEyeLocal()).length();
}
float CullVisitor::getDistanceToViewPoint(const Vec3& pos, bool withLODScale) const
{
if (withLODScale) return (pos-getViewPointLocal()).length()*getLODScale();
else return (pos-getViewPointLocal()).length();
}
inline CullVisitor::value_type distance(const osg::Vec3& coord,const osg::Matrix& matrix)
{
//std::cout << "distance("<<coord<<", "<<matrix<<")"<<std::endl;
return -((CullVisitor::value_type)coord[0]*(CullVisitor::value_type)matrix(0,2)+(CullVisitor::value_type)coord[1]*(CullVisitor::value_type)matrix(1,2)+(CullVisitor::value_type)coord[2]*(CullVisitor::value_type)matrix(2,2)+matrix(3,2));
}
@ -1079,23 +1082,45 @@ void CullVisitor::apply(osg::Camera& camera)
RefMatrix& originalModelView = getModelViewMatrix();
osg::RefMatrix* projection = 0;
osg::RefMatrix* modelview = 0;
if (camera.getReferenceFrame()==osg::Transform::ABSOLUTE_RF)
{
pushProjectionMatrix(createOrReuseMatrix(camera.getProjectionMatrix()));
pushModelViewMatrix(createOrReuseMatrix(camera.getViewMatrix()));
projection = createOrReuseMatrix(camera.getProjectionMatrix());
modelview = createOrReuseMatrix(camera.getViewMatrix());
}
else if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY)
{
pushProjectionMatrix(createOrReuseMatrix(getProjectionMatrix()*camera.getProjectionMatrix()));
pushModelViewMatrix(createOrReuseMatrix(getModelViewMatrix()*camera.getViewMatrix()));
projection = createOrReuseMatrix(getProjectionMatrix()*camera.getProjectionMatrix());
modelview = createOrReuseMatrix(getModelViewMatrix()*camera.getViewMatrix());
}
else // pre multiply
{
pushProjectionMatrix(createOrReuseMatrix(camera.getProjectionMatrix()*getProjectionMatrix()));
pushModelViewMatrix(createOrReuseMatrix(camera.getViewMatrix()*getModelViewMatrix()));
projection = createOrReuseMatrix(camera.getProjectionMatrix()*getProjectionMatrix());
modelview = createOrReuseMatrix(camera.getViewMatrix()*getModelViewMatrix());
}
bool localReferenceViewPoint = true;
if (localReferenceViewPoint)
{
// put the reference view point into the new camera eye coordinates
osg::Vec3 referenceViewPoint = getReferenceViewPoint();
if (originalModelView.valid())
{
osg::Matrix matrix;
matrix.invert(originalModelView); // note should this be view.getCamera()->getViewMatrix() ??
matrix.postMult(*modelview);
referenceViewPoint = referenceViewPoint * matrix;
}
pushReferenceViewPoint(referenceViewPoint);
}
pushProjectionMatrix(projection);
pushModelViewMatrix(modelview);
if (camera.getRenderOrder()==osg::Camera::NESTED_RENDER)
{
handle_cull_callbacks_and_traverse(camera);
@ -1213,6 +1238,12 @@ void CullVisitor::apply(osg::Camera& camera)
}
if (localReferenceViewPoint)
{
// restore the previous reference view point
popReferenceViewPoint();
}
// restore the previous model view matrix.
popModelViewMatrix();

View File

@ -47,6 +47,10 @@ BEGIN_OBJECT_REFLECTOR(osg::CollectOccludersVisitor)
__float__getDistanceToEyePoint__C5_Vec3_R1__bool,
"Get the distance from a point to the eye point, distance value in local coordinate system. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. If the getDistanceFromEyePoint(pos) is not implemented then a default value of 0.0 is returned. ");
I_Method2(float, getDistanceToViewPoint, IN, const osg::Vec3 &, pos, IN, bool, withLODScale,
__float__getDistanceToViewPoint__C5_Vec3_R1__bool,
"Get the distance from a point to the view point, distance value in local coordinate system. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. If the getDistanceToViewPoint(pos) is not implemented then a default value of 0.0 is returned. ");
I_Method2(float, getDistanceFromEyePoint, IN, const osg::Vec3 &, pos, IN, bool, withLODScale,
__float__getDistanceFromEyePoint__C5_Vec3_R1__bool,
"Get the distance of a point from the eye point, distance value in the eye coordinate system. ",

View File

@ -168,6 +168,10 @@ BEGIN_OBJECT_REFLECTOR(osg::NodeVisitor)
__osg_Vec3__getEyePoint,
"Get the eye point in local coordinates. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. ");
I_Method0(osg::Vec3, getViewPoint,
__osg_Vec3__getViewPoint,
"Get the view point in local coordinates. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. ");
I_Method2(float, getDistanceToEyePoint, IN, const osg::Vec3 &, x, IN, bool, x,
__float__getDistanceToEyePoint__C5_Vec3_R1__bool,
"Get the distance from a point to the eye point, distance value in local coordinate system. ",
@ -176,6 +180,10 @@ BEGIN_OBJECT_REFLECTOR(osg::NodeVisitor)
__float__getDistanceFromEyePoint__C5_Vec3_R1__bool,
"Get the distance of a point from the eye point, distance value in the eye coordinate system. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. If the getDistanceFromEyePoint(pos) is not implemented than a default value of 0.0 is returned. ");
I_Method2(float, getDistanceToViewPoint, IN, const osg::Vec3 &, x, IN, bool, x,
__float__getDistanceToViewPoint__C5_Vec3_R1__bool,
"Get the distance from a point to the view point, distance value in local coordinate system. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. If the getDistanceToViewPoint(pos) is not implemented then a default value of 0.0 is returned. ");
I_Method1(void, apply, IN, osg::Node &, node,
__void__apply__Node_R1,
"",
@ -299,6 +307,9 @@ BEGIN_OBJECT_REFLECTOR(osg::NodeVisitor)
I_SimpleProperty(osg::Referenced *, UserData,
__Referenced_P1__getUserData,
__void__setUserData__Referenced_P1);
I_SimpleProperty(osg::Vec3, ViewPoint,
__osg_Vec3__getViewPoint,
0);
I_SimpleProperty(osg::NodeVisitor::VisitorType, VisitorType,
__VisitorType__getVisitorType,
__void__setVisitorType__VisitorType);

View File

@ -68,6 +68,10 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::CullVisitor)
__osg_Vec3__getEyePoint,
"Get the eye point in local coordinates. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. ");
I_Method0(osg::Vec3, getViewPoint,
__osg_Vec3__getViewPoint,
"Get the view point in local coordinates. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. ");
I_Method2(float, getDistanceToEyePoint, IN, const osg::Vec3 &, pos, IN, bool, withLODScale,
__float__getDistanceToEyePoint__C5_osg_Vec3_R1__bool,
"Get the distance from a point to the eye point, distance value in local coordinate system. ",
@ -76,6 +80,10 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::CullVisitor)
__float__getDistanceFromEyePoint__C5_osg_Vec3_R1__bool,
"Get the distance of a point from the eye point, distance value in the eye coordinate system. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. If the getDistanceFromEyePoint(pos) is not implemented than a default value of 0.0 is returned. ");
I_Method2(float, getDistanceToViewPoint, IN, const osg::Vec3 &, pos, IN, bool, withLODScale,
__float__getDistanceToViewPoint__C5_osg_Vec3_R1__bool,
"Get the distance from a point to the view point, distance value in local coordinate system. ",
"Note, not all NodeVisitor implement this method, it is mainly cull visitors which will implement. If the getDistanceToViewPoint(pos) is not implemented then a default value of 0.0 is returned. ");
I_Method1(void, apply, IN, osg::Node &, x,
__void__apply__osg_Node_R1,
"",
@ -293,5 +301,8 @@ BEGIN_OBJECT_REFLECTOR(osgUtil::CullVisitor)
I_SimpleProperty(osgUtil::StateGraph *, StateGraph,
0,
__void__setStateGraph__StateGraph_P1);
I_SimpleProperty(osg::Vec3, ViewPoint,
__osg_Vec3__getViewPoint,
0);
END_REFLECTOR