From 982a4db9e2e41c4154a62662586826cf941da413 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 15 Dec 2006 17:27:18 +0000 Subject: [PATCH] Added ViewPoint support into NodeVistor/CullStack/CullVisitor/LOD/PagedLOD etc to facilate management of LOD settings for RTT cameras. --- include/osg/CollectOccludersVisitor | 2 + include/osg/CullStack | 10 +++ include/osg/NodeVisitor | 10 +++ include/osgUtil/CullVisitor | 4 + src/osg/CollectOccludersVisitor.cpp | 6 ++ src/osg/CullStack.cpp | 83 ++++--------------- src/osg/LOD.cpp | 2 +- src/osg/PagedLOD.cpp | 2 +- src/osg/View.cpp | 1 + src/osgUtil/CullVisitor.cpp | 49 +++++++++-- .../osg/CollectOccludersVisitor.cpp | 4 + src/osgWrappers/osg/NodeVisitor.cpp | 11 +++ src/osgWrappers/osgUtil/CullVisitor.cpp | 11 +++ 13 files changed, 116 insertions(+), 79 deletions(-) diff --git a/include/osg/CollectOccludersVisitor b/include/osg/CollectOccludersVisitor index cf9ecbab0..d22fb5551 100644 --- a/include/osg/CollectOccludersVisitor +++ b/include/osg/CollectOccludersVisitor @@ -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&); diff --git a/include/osg/CullStack b/include/osg/CullStack index 2a73affd0..7bf2d66da 100644 --- a/include/osg/CullStack +++ b/include/osg/CullStack @@ -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 EyePointStack; + EyePointStack _referenceViewPoints; EyePointStack _eyePointStack; + EyePointStack _viewPointStack; CullingStack _clipspaceCullingStack; CullingStack _projectionCullingStack; diff --git a/include/osg/NodeVisitor b/include/osg/NodeVisitor index 94d613b6d..fa2d26654 100644 --- a/include/osg/NodeVisitor +++ b/include/osg/NodeVisitor @@ -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); } diff --git a/include/osgUtil/CullVisitor b/include/osgUtil/CullVisitor index d09cdf561..a51951d6f 100644 --- a/include/osgUtil/CullVisitor +++ b/include/osgUtil/CullVisitor @@ -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); diff --git a/src/osg/CollectOccludersVisitor.cpp b/src/osg/CollectOccludersVisitor.cpp index 1f73be0dc..d54f2b08f 100644 --- a/src/osg/CollectOccludersVisitor.cpp +++ b/src/osg/CollectOccludersVisitor.cpp @@ -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(); diff --git a/src/osg/CullStack.cpp b/src/osg/CullStack.cpp index a5149869a..ff0dc352a 100644 --- a/src/osg/CullStack.cpp +++ b/src/osg/CullStack.cpp @@ -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 = "<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(); diff --git a/src/osgWrappers/osg/CollectOccludersVisitor.cpp b/src/osgWrappers/osg/CollectOccludersVisitor.cpp index b769a29d6..eb2a113ac 100644 --- a/src/osgWrappers/osg/CollectOccludersVisitor.cpp +++ b/src/osgWrappers/osg/CollectOccludersVisitor.cpp @@ -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. ", diff --git a/src/osgWrappers/osg/NodeVisitor.cpp b/src/osgWrappers/osg/NodeVisitor.cpp index bbf6993e1..048a194a2 100644 --- a/src/osgWrappers/osg/NodeVisitor.cpp +++ b/src/osgWrappers/osg/NodeVisitor.cpp @@ -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); diff --git a/src/osgWrappers/osgUtil/CullVisitor.cpp b/src/osgWrappers/osgUtil/CullVisitor.cpp index 1ca3782f3..7aeb41b32 100644 --- a/src/osgWrappers/osgUtil/CullVisitor.cpp +++ b/src/osgWrappers/osgUtil/CullVisitor.cpp @@ -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