/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. * * ViewDependentShadow codes Copyright (C) 2008 Wojciech Lewandowski * Thanks to to my company http://www.ai.com.pl for allowing me free this work. */ #ifndef OSGSHADOW_MINIMALSHADOWMAP #define OSGSHADOW_MINIMALSHADOWMAP 1 #include namespace osgShadow { class OSGSHADOW_EXPORT MinimalShadowMap : public StandardShadowMap { public : /** Convenient typedef used in definition of ViewData struct and methods */ typedef MinimalShadowMap ThisClass; /** Convenient typedef used in definition of ViewData struct and methods */ typedef StandardShadowMap BaseClass; /** Classic OSG constructor */ MinimalShadowMap(); /** Classic OSG cloning constructor */ MinimalShadowMap( const MinimalShadowMap& msm, const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); /** Declaration of standard OSG object methods */ META_Object( ViewDependentShadow, MinimalShadowMap ); void setModellingSpaceToWorldTransform( const osg::Matrix & modellingSpaceToWorld ) { _modellingSpaceToWorld = modellingSpaceToWorld; } const osg::Matrix & getModellingSpaceToWorldTransform( void ) { return _modellingSpaceToWorld; } float getMaxFarPlane( ) { return _maxFarPlane; } void setMaxFarPlane( float maxFarPlane ) { _maxFarPlane = maxFarPlane; } float getMinLightMargin( ) { return _minLightMargin; } void setMinLightMargin( float minLightMargin ) { _minLightMargin = minLightMargin; } enum ShadowReceivingCoarseBoundAccuracy { EMPTY_BOX, BOUNDING_SPHERE, BOUNDING_BOX, DEFAULT_ACCURACY = BOUNDING_BOX }; void setShadowReceivingCoarseBoundAccuracy ( ShadowReceivingCoarseBoundAccuracy accuracy ) { _shadowReceivingCoarseBoundAccuracy = accuracy; } ShadowReceivingCoarseBoundAccuracy getShadowReceivingCoarseBoundAccuracy() { return _shadowReceivingCoarseBoundAccuracy; } protected: /** Classic protected OSG destructor */ virtual ~MinimalShadowMap(void); protected: // Matrix modellingSpaceToWorld and its inverse // are used to define Modelling Space where shadowed scene drawables // have minimal (smallest possible extent) bounding boxes. // Computing visible shadow range in this space // allows for optimal use of ShadowMap resolution. // By default it is set to identity ie computations are in world space. // But it should be set to ElipsoidModel::localToWorld // when scene objects are put on earth ellipsoid surface. // Other scenarios are also possible for example when models are // built in XZY space which would require identity matrix with swapped colums osg::Matrix _modellingSpaceToWorld; float _maxFarPlane; float _minLightMargin; ShadowReceivingCoarseBoundAccuracy _shadowReceivingCoarseBoundAccuracy; struct OSGSHADOW_EXPORT ViewData: public BaseClass::ViewData { osg::Matrix *_modellingSpaceToWorldPtr; float *_maxFarPlanePtr; float *_minLightMarginPtr; ConvexPolyhedron _sceneReceivingShadowPolytope; std::vector< osg::Vec3d > _sceneReceivingShadowPolytopePoints; osg::Matrixd _clampedProjection; virtual void init( ThisClass * st, osgUtil::CullVisitor * cv ); virtual osg::BoundingBox computeShadowReceivingCoarseBounds( ); virtual void cullShadowReceivingScene( ); virtual void aimShadowCastingCamera( const osg::Light *light, const osg::Vec4 &worldLightPos, const osg::Vec3 &worldLightDir, const osg::Vec3 &worldLightUp = osg::Vec3(0,1,0) ); virtual void frameShadowCastingCamera ( const osg::Camera* cameraMain, osg::Camera* cameraShadow, int pass = 1 ); void cutScenePolytope( const osg::Matrix & matrix, const osg::Matrix & inverse, const osg::BoundingBox &bb = osg::BoundingBox(-1,-1,-1,1,1,1) ); osg::BoundingBox computeScenePolytopeBounds ( const osg::Matrix & m = *(osg::Matrix*)(NULL) ); // Utility methods for adjusting projection matrices // Modify projection matrix so that some output subrange // is remapped to whole clip space (-1..1,-1..1,-1..1). // Bit mask can be used to limit remaping to selected bounds only. static void trimProjection ( osg::Matrixd & projection, osg::BoundingBox subrange, unsigned int trimMask = (1|2|4|8|16|32) /*1=left|2=right|4=bottom|8=top|16=near|32=far*/); static void clampProjection ( osg::Matrixd & projection, float n = 0, float f = FLT_MAX ); static void extendProjection ( osg::Matrixd & projection, osg::Viewport * viewport, const osg::Vec2& margin ); }; META_ViewDependentShadowTechniqueData( ThisClass, ThisClass::ViewData ) }; } // namespace osgShadow #endif