Added new Transform::ReferenceType enum ABSOLUTE_RF_INHERIT_VIEWPOINT to support

internal RTT cameras that wish to use the main cameras view/eye point for LOD and other
distance based tests.
This commit is contained in:
Robert Osfield
2007-02-07 16:32:14 +00:00
parent c2e79a2d89
commit c52207b637
11 changed files with 104 additions and 64 deletions

View File

@@ -18,6 +18,7 @@
#include <osg/CullSettings>
#include <osg/Viewport>
#include <osg/fast_back_stack>
#include <osg/Transform>
namespace osg {
@@ -47,7 +48,7 @@ class OSG_EXPORT CullStack : public osg::CullSettings
void pushProjectionMatrix(osg::RefMatrix* matrix);
void popProjectionMatrix();
void pushModelViewMatrix(osg::RefMatrix* matrix);
void pushModelViewMatrix(osg::RefMatrix* matrix, Transform::ReferenceFrame referenceFrame);
void popModelViewMatrix();
inline float getFrustumVolume() { if (_frustumVolume<0.0f) computeFrustumVolume(); return _frustumVolume; }

View File

@@ -90,7 +90,8 @@ class OSG_EXPORT Transform : public Group
enum ReferenceFrame
{
RELATIVE_RF,
ABSOLUTE_RF
ABSOLUTE_RF,
ABSOLUTE_RF_INHERIT_VIEWPOINT
};
/** Set the transform's ReferenceFrame, either to be relative to its
@@ -104,6 +105,12 @@ class OSG_EXPORT Transform : public Group
* deep in the scene graph. It is therefore recommended to only use
* absolute Transforms at the top of the scene, for such things as
* heads up displays.
* ABSOLUTE_RF_INHERIT_VIEWPOINT is the same as ABSOLUTE_RF except it
* adds the ability to use the parents view points position in world coordinates
* as its local viewpoint in the new coordinates frame. This is useful for
* Render to texture Cameras that wish to use the main views LOD range computation
* (which uses the viewpoint rather than the eye point) rather than use the local
* eye point defined by the this Transforms' abosolute view matrix.
*/
void setReferenceFrame(ReferenceFrame rf);

View File

@@ -89,7 +89,7 @@ void CollectOccludersVisitor::apply(osg::Transform& node)
ref_ptr<osg::RefMatrix> matrix = createOrReuseMatrix(getModelViewMatrix());
node.computeLocalToWorldMatrix(*matrix,this);
pushModelViewMatrix(matrix.get());
pushModelViewMatrix(matrix.get(), node.getReferenceFrame());
handle_cull_callbacks_and_traverse(node);

View File

@@ -13,6 +13,9 @@
#include <osg/CullStack>
#include <osg/Timer>
#include <osg/Notify>
#include <osg/io_utils>
using namespace osg;
CullStack::CullStack()
@@ -187,8 +190,10 @@ void CullStack::popProjectionMatrix()
popCullingSet();
}
void CullStack::pushModelViewMatrix(RefMatrix* matrix)
void CullStack::pushModelViewMatrix(RefMatrix* matrix, Transform::ReferenceFrame referenceFrame)
{
osg::RefMatrix* originalModelView = _modelviewStack.empty() ? 0 : _modelviewStack.back().get();
_modelviewStack.push_back(matrix);
pushCullingSet();
@@ -196,8 +201,37 @@ void CullStack::pushModelViewMatrix(RefMatrix* matrix)
osg::Matrix inv;
inv.invert(*matrix);
_eyePointStack.push_back(inv.getTrans());
_viewPointStack.push_back(getReferenceViewPoint() * inv);
switch(referenceFrame)
{
case(Transform::RELATIVE_RF):
_eyePointStack.push_back(inv.getTrans());
_referenceViewPoints.push_back(getReferenceViewPoint());
_viewPointStack.push_back(getReferenceViewPoint() * inv);
break;
case(Transform::ABSOLUTE_RF):
_eyePointStack.push_back(inv.getTrans());
_referenceViewPoints.push_back(osg::Vec3(0.0,0.0,0.0));
_viewPointStack.push_back(_eyePointStack.back());
break;
case(Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT):
{
_eyePointStack.push_back(inv.getTrans());
osg::Vec3 referenceViewPoint = getReferenceViewPoint();
if (originalModelView)
{
osg::Matrix viewPointTransformMatrix;
viewPointTransformMatrix.invert(*originalModelView);
viewPointTransformMatrix.postMult(*matrix);
referenceViewPoint = referenceViewPoint * viewPointTransformMatrix;
}
_referenceViewPoints.push_back(referenceViewPoint);
_viewPointStack.push_back(getReferenceViewPoint() * inv);
break;
}
}
osg::Vec3 lookVector = getLookVectorLocal();
@@ -215,6 +249,7 @@ void CullStack::popModelViewMatrix()
_modelviewStack.pop_back();
_eyePointStack.pop_back();
_referenceViewPoints.pop_back();
_viewPointStack.pop_back();
popCullingSet();

View File

@@ -68,7 +68,7 @@ class TransformVisitor : public NodeVisitor
{
const osg::Camera* camera = dynamic_cast<const osg::Camera*>(*ritr);
if (camera &&
(camera->getReferenceFrame()==osg::Transform::ABSOLUTE_RF || camera->getParents().empty()))
(camera->getReferenceFrame()!=osg::Transform::RELATIVE_RF || camera->getParents().empty()))
{
break;
}

View File

@@ -50,13 +50,19 @@ bool Transform_readLocalData(Object& obj, Input& fr)
if (fr[0].matchWord("referenceFrame"))
{
if (fr[1].matchWord("RELATIVE_TO_ABSOLUTE") || fr[1].matchWord("ABSOLUTE") )
if (fr[1].matchWord("RELATIVE_TO_ABSOLUTE") || fr[1].matchWord("ABSOLUTE") || fr[1].matchWord("ABSOLUTE_RF"))
{
transform.setReferenceFrame(Transform::ABSOLUTE_RF);
fr += 2;
iteratorAdvanced = true;
}
if (fr[1].matchWord("RELATIVE_TO_PARENTS") || fr[1].matchWord("RELATIVE"))
if (fr[1].matchWord("RELATIVE_TO_ABSOLUTE") || fr[1].matchWord("ABSOLUTE_RF_INHERIT_VIEWPOINT") )
{
transform.setReferenceFrame(Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT);
fr += 2;
iteratorAdvanced = true;
}
if (fr[1].matchWord("RELATIVE_TO_PARENTS") || fr[1].matchWord("RELATIVE") || fr[1].matchWord("RELATIVE_RF"))
{
transform.setReferenceFrame(Transform::RELATIVE_RF);
fr += 2;
@@ -78,6 +84,9 @@ bool Transform_writeLocalData(const Object& obj, Output& fw)
case Transform::ABSOLUTE_RF:
fw << "ABSOLUTE\n";
break;
case Transform::ABSOLUTE_RF_INHERIT_VIEWPOINT:
fw << "ABSOLUTE_RF_INHERIT_VIEWPOINT\n";
break;
case Transform::RELATIVE_RF:
default:
fw << "RELATIVE\n";

View File

@@ -103,9 +103,10 @@ void TXPNode::traverse(osg::NodeVisitor& nv)
osg::ref_ptr<TileMapper> tileMapper = new TileMapper;
tileMapper->setLODScale(cv->getLODScale());
tileMapper->pushReferenceViewPoint(cv->getReferenceViewPoint());
tileMapper->pushViewport(cv->getViewport());
tileMapper->pushProjectionMatrix(&(cv->getProjectionMatrix()));
tileMapper->pushModelViewMatrix(&(cv->getModelViewMatrix()));
tileMapper->pushModelViewMatrix(&(cv->getModelViewMatrix()), osg::Transform::RELATIVE_RF);
// traverse the scene graph to search for valid tiles
accept(*tileMapper);
@@ -113,6 +114,7 @@ void TXPNode::traverse(osg::NodeVisitor& nv)
tileMapper->popModelViewMatrix();
tileMapper->popProjectionMatrix();
tileMapper->popViewport();
tileMapper->popReferenceViewPoint();
//std::cout<<" found " << tileMapper._tileMap.size() << std::endl;

View File

@@ -961,7 +961,7 @@ void CullVisitor::apply(Transform& node)
ref_ptr<RefMatrix> matrix = createOrReuseMatrix(getModelViewMatrix());
node.computeLocalToWorldMatrix(*matrix,this);
pushModelViewMatrix(matrix.get());
pushModelViewMatrix(matrix.get(), node.getReferenceFrame());
handle_cull_callbacks_and_traverse(node);
@@ -1117,40 +1117,29 @@ void CullVisitor::apply(osg::Camera& camera)
osg::RefMatrix* projection = 0;
osg::RefMatrix* modelview = 0;
if (camera.getReferenceFrame()==osg::Transform::ABSOLUTE_RF)
if (camera.getReferenceFrame()==osg::Transform::RELATIVE_RF)
{
if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY)
{
projection = createOrReuseMatrix(getProjectionMatrix()*camera.getProjectionMatrix());
modelview = createOrReuseMatrix(getModelViewMatrix()*camera.getViewMatrix());
}
else // pre multiply
{
projection = createOrReuseMatrix(camera.getProjectionMatrix()*getProjectionMatrix());
modelview = createOrReuseMatrix(camera.getViewMatrix()*getModelViewMatrix());
}
}
else
{
// an absolute reference frame
projection = createOrReuseMatrix(camera.getProjectionMatrix());
modelview = createOrReuseMatrix(camera.getViewMatrix());
}
else if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY)
{
projection = createOrReuseMatrix(getProjectionMatrix()*camera.getProjectionMatrix());
modelview = createOrReuseMatrix(getModelViewMatrix()*camera.getViewMatrix());
}
else // pre multiply
{
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);
pushModelViewMatrix(modelview, camera.getReferenceFrame());
if (camera.getRenderOrder()==osg::Camera::NESTED_RENDER)
@@ -1277,12 +1266,6 @@ void CullVisitor::apply(osg::Camera& camera)
}
}
if (localReferenceViewPoint)
{
// restore the previous reference view point
popReferenceViewPoint();
}
// restore the previous model view matrix.
popModelViewMatrix();

View File

@@ -804,7 +804,26 @@ void PickVisitor::apply(osg::Camera& camera)
{
if (!camera.isRenderToTextureCamera())
{
if (camera.getReferenceFrame()==osg::Camera::ABSOLUTE_RF)
if (camera.getReferenceFrame()==osg::Camera::RELATIVE_RF)
{
if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY)
{
runNestedPickVisitor( camera,
camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
_lastProjectionMatrix * camera.getProjectionMatrix(),
_lastViewMatrix * camera.getViewMatrix(),
_mx, _my );
}
else // PRE_MULTIPLY
{
runNestedPickVisitor( camera,
camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
camera.getProjectionMatrix() * _lastProjectionMatrix,
camera.getViewMatrix() * _lastViewMatrix,
_mx, _my );
}
}
else
{
runNestedPickVisitor( camera,
camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
@@ -812,21 +831,5 @@ void PickVisitor::apply(osg::Camera& camera)
camera.getViewMatrix(),
_mx, _my );
}
else if (camera.getTransformOrder()==osg::Camera::POST_MULTIPLY)
{
runNestedPickVisitor( camera,
camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
_lastProjectionMatrix * camera.getProjectionMatrix(),
_lastViewMatrix * camera.getViewMatrix(),
_mx, _my );
}
else // PRE_MULTIPLY
{
runNestedPickVisitor( camera,
camera.getViewport() ? camera.getViewport() : _lastViewport.get(),
camera.getProjectionMatrix() * _lastProjectionMatrix,
camera.getViewMatrix() * _lastViewMatrix,
_mx, _my );
}
}
}

View File

@@ -789,7 +789,7 @@ class CollectLowestTransformsVisitor : public BaseOptimizerVisitor
if (transform)
{
if (transform->getDataVariance()==osg::Transform::DYNAMIC) _moreThanOneMatrixRequired=true;
else if (transform->getReferenceFrame()==osg::Transform::ABSOLUTE_RF) _moreThanOneMatrixRequired=true;
else if (transform->getReferenceFrame()!=osg::Transform::RELATIVE_RF) _moreThanOneMatrixRequired=true;
else
{
if (_transformSet.empty()) transform->computeLocalToWorldMatrix(_firstMatrix,0);

View File

@@ -659,7 +659,7 @@ void SceneView::cullStage(const osg::Matrixd& projection,const osg::Matrixd& mod
_collectOccludersVisistor->pushViewport(getViewport());
_collectOccludersVisistor->pushProjectionMatrix(proj.get());
_collectOccludersVisistor->pushModelViewMatrix(mv.get());
_collectOccludersVisistor->pushModelViewMatrix(mv.get(),osg::Transform::ABSOLUTE_RF);
// traverse the scene graph to search for occluder in there new positions.
for(unsigned int i=0; i< _camera->getNumChildren(); ++i)
@@ -736,7 +736,7 @@ void SceneView::cullStage(const osg::Matrixd& projection,const osg::Matrixd& mod
cullVisitor->pushViewport(getViewport());
cullVisitor->pushProjectionMatrix(proj.get());
cullVisitor->pushModelViewMatrix(mv.get());
cullVisitor->pushModelViewMatrix(mv.get(),osg::Transform::ABSOLUTE_RF);
// traverse the scene graph to generate the rendergraph.