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:
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user