| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| 2 | * |
|---|
| 3 | * This library is open source and may be redistributed and/or modified under |
|---|
| 4 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|---|
| 5 | * (at your option) any later version. The full license is in LICENSE file |
|---|
| 6 | * included with this distribution, and on the openscenegraph.org website. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | * OpenSceneGraph Public License for more details. |
|---|
| 12 | * |
|---|
| 13 | * ViewDependentShadow codes Copyright (C) 2008 Wojciech Lewandowski |
|---|
| 14 | * Thanks to to my company http://www.ai.com.pl for allowing me free this work. |
|---|
| 15 | */ |
|---|
| 16 | |
|---|
| 17 | #ifndef OSGSHADOW_MINIMALSHADOWMAP |
|---|
| 18 | #define OSGSHADOW_MINIMALSHADOWMAP 1 |
|---|
| 19 | |
|---|
| 20 | #include <osgShadow/StandardShadowMap> |
|---|
| 21 | |
|---|
| 22 | namespace osgShadow { |
|---|
| 23 | |
|---|
| 24 | class OSGSHADOW_EXPORT MinimalShadowMap : public StandardShadowMap |
|---|
| 25 | { |
|---|
| 26 | public : |
|---|
| 27 | /** Convenient typedef used in definition of ViewData struct and methods */ |
|---|
| 28 | typedef MinimalShadowMap ThisClass; |
|---|
| 29 | /** Convenient typedef used in definition of ViewData struct and methods */ |
|---|
| 30 | typedef StandardShadowMap BaseClass; |
|---|
| 31 | |
|---|
| 32 | /** Classic OSG constructor */ |
|---|
| 33 | MinimalShadowMap(); |
|---|
| 34 | |
|---|
| 35 | /** Classic OSG cloning constructor */ |
|---|
| 36 | MinimalShadowMap( |
|---|
| 37 | const MinimalShadowMap& msm, |
|---|
| 38 | const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY); |
|---|
| 39 | |
|---|
| 40 | /** Declaration of standard OSG object methods */ |
|---|
| 41 | META_Object( osgShadow, MinimalShadowMap ); |
|---|
| 42 | |
|---|
| 43 | void setModellingSpaceToWorldTransform( const osg::Matrix & modellingSpaceToWorld ) |
|---|
| 44 | { _modellingSpaceToWorld = modellingSpaceToWorld; } |
|---|
| 45 | |
|---|
| 46 | const osg::Matrix & getModellingSpaceToWorldTransform( void ) const |
|---|
| 47 | { return _modellingSpaceToWorld; } |
|---|
| 48 | |
|---|
| 49 | float getMaxFarPlane( ) const |
|---|
| 50 | { return _maxFarPlane; } |
|---|
| 51 | |
|---|
| 52 | void setMaxFarPlane( float maxFarPlane ) |
|---|
| 53 | { _maxFarPlane = maxFarPlane; } |
|---|
| 54 | |
|---|
| 55 | float getMinLightMargin( ) const |
|---|
| 56 | { return _minLightMargin; } |
|---|
| 57 | |
|---|
| 58 | void setMinLightMargin( float minLightMargin ) |
|---|
| 59 | { _minLightMargin = minLightMargin; } |
|---|
| 60 | |
|---|
| 61 | enum ShadowReceivingCoarseBoundAccuracy { |
|---|
| 62 | EMPTY_BOX, |
|---|
| 63 | BOUNDING_SPHERE, |
|---|
| 64 | BOUNDING_BOX, |
|---|
| 65 | DEFAULT_ACCURACY = BOUNDING_BOX |
|---|
| 66 | }; |
|---|
| 67 | |
|---|
| 68 | void setShadowReceivingCoarseBoundAccuracy |
|---|
| 69 | ( ShadowReceivingCoarseBoundAccuracy accuracy ) |
|---|
| 70 | { _shadowReceivingCoarseBoundAccuracy = accuracy; } |
|---|
| 71 | |
|---|
| 72 | ShadowReceivingCoarseBoundAccuracy |
|---|
| 73 | getShadowReceivingCoarseBoundAccuracy() const |
|---|
| 74 | { return _shadowReceivingCoarseBoundAccuracy; } |
|---|
| 75 | |
|---|
| 76 | protected: |
|---|
| 77 | /** Classic protected OSG destructor */ |
|---|
| 78 | virtual ~MinimalShadowMap(void); |
|---|
| 79 | |
|---|
| 80 | protected: |
|---|
| 81 | // Matrix modellingSpaceToWorld and its inverse |
|---|
| 82 | // are used to define Modelling Space where shadowed scene drawables |
|---|
| 83 | // have minimal (smallest possible extent) bounding boxes. |
|---|
| 84 | |
|---|
| 85 | // Computing visible shadow range in this space |
|---|
| 86 | // allows for optimal use of ShadowMap resolution. |
|---|
| 87 | |
|---|
| 88 | // By default it is set to identity ie computations are in world space. |
|---|
| 89 | // But it should be set to ElipsoidModel::localToWorld |
|---|
| 90 | // when scene objects are put on earth ellipsoid surface. |
|---|
| 91 | |
|---|
| 92 | // Other scenarios are also possible for example when models are |
|---|
| 93 | // built in XZY space which would require identity matrix with swapped colums |
|---|
| 94 | |
|---|
| 95 | osg::Matrix _modellingSpaceToWorld; |
|---|
| 96 | float _maxFarPlane; |
|---|
| 97 | float _minLightMargin; |
|---|
| 98 | ShadowReceivingCoarseBoundAccuracy _shadowReceivingCoarseBoundAccuracy; |
|---|
| 99 | |
|---|
| 100 | struct OSGSHADOW_EXPORT ViewData: public BaseClass::ViewData |
|---|
| 101 | { |
|---|
| 102 | osg::Matrix *_modellingSpaceToWorldPtr; |
|---|
| 103 | float *_maxFarPlanePtr; |
|---|
| 104 | float *_minLightMarginPtr; |
|---|
| 105 | int _frameShadowCastingCameraPasses; |
|---|
| 106 | |
|---|
| 107 | ConvexPolyhedron _sceneReceivingShadowPolytope; |
|---|
| 108 | std::vector< osg::Vec3d > _sceneReceivingShadowPolytopePoints; |
|---|
| 109 | |
|---|
| 110 | osg::Matrixd _clampedProjection; |
|---|
| 111 | |
|---|
| 112 | virtual void init( ThisClass * st, osgUtil::CullVisitor * cv ); |
|---|
| 113 | |
|---|
| 114 | virtual osg::BoundingBox computeShadowReceivingCoarseBounds( ); |
|---|
| 115 | |
|---|
| 116 | virtual void cullShadowReceivingScene( ); |
|---|
| 117 | |
|---|
| 118 | virtual void aimShadowCastingCamera( |
|---|
| 119 | const osg::BoundingSphere &bounds, |
|---|
| 120 | const osg::Light *light, |
|---|
| 121 | const osg::Vec4 &worldLightPos, |
|---|
| 122 | const osg::Vec3 &worldLightDir, |
|---|
| 123 | const osg::Vec3 &worldLightUp = osg::Vec3(0,1,0) ); |
|---|
| 124 | |
|---|
| 125 | virtual void aimShadowCastingCamera( const osg::Light *light, |
|---|
| 126 | const osg::Vec4 &worldLightPos, |
|---|
| 127 | const osg::Vec3 &worldLightDir, |
|---|
| 128 | const osg::Vec3 &worldLightUp |
|---|
| 129 | = osg::Vec3(0,1,0) ); |
|---|
| 130 | |
|---|
| 131 | virtual void frameShadowCastingCamera |
|---|
| 132 | ( const osg::Camera* cameraMain, osg::Camera* cameraShadow, int pass = 1 ); |
|---|
| 133 | |
|---|
| 134 | void cutScenePolytope( const osg::Matrix & matrix, |
|---|
| 135 | const osg::Matrix & inverse, |
|---|
| 136 | const osg::BoundingBox &bb = |
|---|
| 137 | osg::BoundingBox(-1,-1,-1,1,1,1) ); |
|---|
| 138 | |
|---|
| 139 | osg::BoundingBox computeScenePolytopeBounds |
|---|
| 140 | ( const osg::Matrix & m = *(osg::Matrix*)(NULL) ); |
|---|
| 141 | |
|---|
| 142 | // Utility methods for adjusting projection matrices |
|---|
| 143 | |
|---|
| 144 | // Modify projection matrix so that some output subrange |
|---|
| 145 | // is remapped to whole clip space (-1..1,-1..1,-1..1). |
|---|
| 146 | // Bit mask can be used to limit remaping to selected bounds only. |
|---|
| 147 | static void trimProjection |
|---|
| 148 | ( osg::Matrixd & projection, osg::BoundingBox subrange, |
|---|
| 149 | unsigned int trimMask = (1|2|4|8|16|32) |
|---|
| 150 | /*1=left|2=right|4=bottom|8=top|16=near|32=far*/); |
|---|
| 151 | |
|---|
| 152 | static void clampProjection |
|---|
| 153 | ( osg::Matrixd & projection, float n = 0, float f = FLT_MAX ); |
|---|
| 154 | |
|---|
| 155 | static void extendProjection |
|---|
| 156 | ( osg::Matrixd & projection, osg::Viewport * viewport, const osg::Vec2& margin ); |
|---|
| 157 | }; |
|---|
| 158 | |
|---|
| 159 | META_ViewDependentShadowTechniqueData( ThisClass, ThisClass::ViewData ) |
|---|
| 160 | }; |
|---|
| 161 | |
|---|
| 162 | } // namespace osgShadow |
|---|
| 163 | |
|---|
| 164 | #endif |
|---|