Added ViewPoint support into NodeVistor/CullStack/CullVisitor/LOD/PagedLOD etc to facilate
management of LOD settings for RTT cameras.
This commit is contained in:
parent
d88b996df1
commit
982a4db9e2
@ -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&);
|
||||
|
@ -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;
|
||||
|
@ -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); }
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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())
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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. ",
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user