From ba3971bb45b133d3f38b3f15db575af3fdf473a1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 1 Mar 2010 13:00:04 +0000 Subject: [PATCH] Added a ShadowTechnique::computeOrthogonalVector(const osg::Vec3& direction) const method for helping compute an appropriate up vector to setViewMatrixAsLookAt(..) codes in osgShadow. This will addresses previous issues that occured when look vectors co-incided with the hard coded up vectors. --- include/osgShadow/ShadowTechnique | 1 + src/osgShadow/ShadowMap.cpp | 6 +++--- src/osgShadow/ShadowTechnique.cpp | 13 +++++++++++++ src/osgShadow/ShadowTexture.cpp | 4 ++-- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/osgShadow/ShadowTechnique b/include/osgShadow/ShadowTechnique index 4c37c6e29..b67bc6e94 100644 --- a/include/osgShadow/ShadowTechnique +++ b/include/osgShadow/ShadowTechnique @@ -71,6 +71,7 @@ class OSGSHADOW_EXPORT ShadowTechnique : public osg::Object ShadowTechnique* _shadowTechnique; }; + osg::Vec3 computeOrthogonalVector(const osg::Vec3& direction) const; virtual ~ShadowTechnique(); diff --git a/src/osgShadow/ShadowMap.cpp b/src/osgShadow/ShadowMap.cpp index 1ac885665..2dd7c280f 100644 --- a/src/osgShadow/ShadowMap.cpp +++ b/src/osgShadow/ShadowMap.cpp @@ -408,7 +408,7 @@ void ShadowMap::cull(osgUtil::CullVisitor& cv) { osg::Vec3 position(lightpos.x(), lightpos.y(), lightpos.z()); _camera->setProjectionMatrixAsPerspective(fov, 1.0, 0.1, 1000.0); - _camera->setViewMatrixAsLookAt(position,position+lightDir,osg::Vec3(0.0f,1.0f,0.0f)); + _camera->setViewMatrixAsLookAt(position,position+lightDir,computeOrthogonalVector(lightDir)); } else { @@ -435,7 +435,7 @@ void ShadowMap::cull(osgUtil::CullVisitor& cv) float right = top; _camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar); - _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f)); + _camera->setViewMatrixAsLookAt(position,bb.center(),computeOrthogonalVector(bb.center()-position)); } else // directional light { @@ -457,7 +457,7 @@ void ShadowMap::cull(osgUtil::CullVisitor& cv) float right = top; _camera->setProjectionMatrixAsOrtho(-right, right, -top, top, znear, zfar); - _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f)); + _camera->setViewMatrixAsLookAt(position,bb.center(),computeOrthogonalVector(lightDir)); } diff --git a/src/osgShadow/ShadowTechnique.cpp b/src/osgShadow/ShadowTechnique.cpp index 245edc5f9..a6f444402 100644 --- a/src/osgShadow/ShadowTechnique.cpp +++ b/src/osgShadow/ShadowTechnique.cpp @@ -14,6 +14,7 @@ #include #include #include +#include using namespace osgShadow; @@ -92,3 +93,15 @@ void ShadowTechnique::traverse(osg::NodeVisitor& nv) _shadowedScene->osg::Group::traverse(nv); } } + +osg::Vec3 ShadowTechnique::computeOrthogonalVector(const osg::Vec3& direction) const +{ + float length = direction.length(); + osg::Vec3 orthogonalVector = direction ^ osg::Vec3(0.0f, 1.0f, 0.0f); + if (orthogonalVector.normalize()setReferenceFrame(osg::Camera::ABSOLUTE_RF); _camera->setProjectionMatrixAsFrustum(-right,right,-top,top,znear,zfar); - _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f)); + _camera->setViewMatrixAsLookAt(position,bb.center(),computeOrthogonalVector(bb.center()-position)); // compute the matrix which takes a vertex from local coords into tex coords @@ -221,7 +221,7 @@ void ShadowTexture::cull(osgUtil::CullVisitor& cv) _camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); _camera->setProjectionMatrixAsOrtho(-right, right, -top, top, znear, zfar); - _camera->setViewMatrixAsLookAt(position,bb.center(),osg::Vec3(0.0f,1.0f,0.0f)); + _camera->setViewMatrixAsLookAt(position,bb.center(),computeOrthogonalVector(lightDir)); // compute the matrix which takes a vertex from local coords into tex coords