]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/clouds3d/SkyCloud.hpp
Clouds3D crashes because there is no Light
[simgear.git] / simgear / scene / sky / clouds3d / SkyCloud.hpp
1 //------------------------------------------------------------------------------
2 // File : SkyCloud.hpp
3 //------------------------------------------------------------------------------
4 // SkyWorks : Copyright 2002 Mark J. Harris and
5 //                                              The University of North Carolina at Chapel Hill
6 //------------------------------------------------------------------------------
7 // Permission to use, copy, modify, distribute and sell this software and its 
8 // documentation for any purpose is hereby granted without fee, provided that 
9 // the above copyright notice appear in all copies and that both that copyright 
10 // notice and this permission notice appear in supporting documentation. 
11 // Binaries may be compiled with this software without any royalties or 
12 // restrictions. 
13 //
14 // The author(s) and The University of North Carolina at Chapel Hill make no 
15 // representations about the suitability of this software for any purpose. 
16 // It is provided "as is" without express or 
17 // implied warranty.
18 /**
19  * @file SkyCloud.hpp
20  * 
21  * Interface definition for class SkyCloud.
22  */
23 #ifndef __SKYCLOUD_HPP__
24 #define __SKYCLOUD_HPP__
25
26 // warning for truncation of template name for browse info
27 #pragma warning( disable : 4786)
28
29 #include "SkyCloudParticle.hpp"
30 #include "SkyRenderable.hpp"
31 #include "SkyMinMaxBox.hpp"
32 #include "camera.hpp"
33 #include "SkyArchive.hpp"
34 #include "mat33.hpp"
35
36 #include <plib/sg.h>
37
38 class SkyMaterial;
39 class SkyLight;
40 class SkyRenderableInstance;
41
42
43 //------------------------------------------------------------------------------
44 /**
45  * @class SkyCloud
46  * @brief A renderable that represents a volumetric cloud.
47  * 
48  * A SkyCloud is made up of particles, and is rendered using particle splatting.  
49  * SkyCloud is intended to represent realisticly illuminated volumetric clouds
50  * through which the viewer and / or other objects can realistically pass.
51  *
52  * Realistic illumination is performed by the Illuminate() method, which uses a
53  * graphics hardware algorithm to precompute and store multiple forward scattering 
54  * of light by each particle in the cloud.  Clouds may be illuminated by multiple
55  * light sources.  The light from each source is precomputed and stored at each
56  * particle.  Each light's contribution is stored separately so that we can 
57  * compute view-dependent (anisotropic) scattering at run-time.  This gives realistic
58  * effects such as the "silver lining" that you see on a thick cloud when it crosses
59  * in front of the sun.
60  *
61  * At run-time, the cloud is rendered by drawing each particle as a view-oriented 
62  * textured billboard (splat), with lighting computed from the precomputed illumination
63  * as follows: for each light source <i>l</i>, compute the scattering function (See _PhaseFunction())
64  * based on the view direction and the direction from the particle to the viewer.  This 
65  * scattering function modulates the lighting contribution of <i>l</i>.  The modulated 
66  * contributions are then added and used to modulate the color of the particle.  The result
67  * is view-dependent scattering.  
68  * 
69  * If the phase (scattering) function is not enabled (see IsPhaseFunctionEnabled()), then the 
70  * contributions of the light sources are simply added.
71  *
72  * @see SkyRenderableInstanceCloud, SkyCloudParticle, SkySceneManager
73  */
74 class SkyCloud : public SkyRenderable
75 {
76 public:
77   SkyCloud();
78   virtual ~SkyCloud();
79   
80   virtual SKYRESULT           Update(const Camera &cam, SkyRenderableInstance* pInstance = NULL);
81   
82   virtual SKYRESULT           Display(const Camera &camera, SkyRenderableInstance *pInstance = NULL);
83  
84   SKYRESULT                   DisplaySplit(const Camera           &camera, 
85                                            const Vec3f            &vecSplitPoint,
86                                            bool                   bBackHalf,
87                                            SkyRenderableInstance  *pInstance = NULL);
88
89   SKYRESULT                   Illuminate( SkyLight *pLight, 
90                                           SkyRenderableInstance* pInstance,
91                                           bool bReset = false);
92   
93   virtual SkyMinMaxBox*       CopyBoundingVolume() const;
94   
95   //! Enables the use of a scattering function for anisotropic light scattering.
96   void                        EnablePhaseFunction(bool bEnable)   { _bUsePhaseFunction = bEnable; }
97   //! Returns true if the use of a scattering function is enabled.
98   bool                        IsPhaseFunctionEnabled() const      { return _bUsePhaseFunction;    }
99   
100   SKYRESULT                   Save(SkyArchive &archive) const;
101   SKYRESULT                   Load(const SkyArchive &archive, float rScale = 1.0f,double latitude=0.0, double longitude=0.0);
102   SKYRESULT                   Load(const unsigned char *data, unsigned int size, float rScale = 1.0f,double latitude=0.0,double longitude=0.0);
103   
104   void                        Rotate(const Mat33f& rot);
105   void                        Translate(const Vec3f& trans);
106   void                        Scale(const float scale);
107
108 protected: // methods
109   enum SortDirection
110   {
111     SKY_CLOUD_SORT_TOWARD,
112     SKY_CLOUD_SORT_AWAY
113   };
114
115   void                                                _SortParticles(   const Vec3f& vecViewDir,
116                                               const Vec3f& vecSortPoint, 
117                                               SortDirection dir);
118   
119   void                        _CreateSplatTexture( unsigned int iResolution);
120   
121   float                       _PhaseFunction(const Vec3f& vecLightDir, const Vec3f& vecViewDir);
122   
123 protected: // datatypes 
124   typedef std::vector<SkyCloudParticle*>  ParticleArray;
125   typedef ParticleArray::iterator         ParticleIterator;
126   typedef ParticleArray::const_iterator   ParticleConstIterator;
127   
128   typedef std::vector<Vec3f>              DirectionArray;
129   typedef DirectionArray::iterator        DirectionIterator;
130   
131   class ParticleAwayComparator
132   {
133   public:
134     bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
135     {
136       return ((*pA) < (*pB));
137     }
138   };
139   
140   class ParticleTowardComparator
141   {
142   public:
143     bool operator()(SkyCloudParticle* pA, SkyCloudParticle *pB)
144     {
145       return ((*pA) > (*pB));
146     }
147   };
148
149 protected: // data
150   ParticleArray               _particles;       // cloud particles
151   // particle sorting functors for STL sort.
152   ParticleTowardComparator    _towardComparator; 
153   ParticleAwayComparator      _awayComparator; 
154
155   DirectionArray              _lightDirections; // light directions in cloud space (cached)
156
157   SkyMinMaxBox                _boundingBox;     // bounds
158
159   bool                        _bUsePhaseFunction;
160
161   Vec3f                       _vecLastSortViewDir;
162   Vec3f                       _vecLastSortCamPos;
163   Vec3f                       _vecSortPos;
164
165   float                       _rSplitDistance;
166   
167   static SkyMaterial          *s_pMaterial;     // shared material for clouds. 
168   static SkyMaterial          *s_pShadeMaterial;// shared material for illumination pass.
169   static unsigned int         s_iShadeResolution; // the resolution of the viewport used for shading
170   static float                s_rAlbedo;        // the cloud albedo
171   static float                s_rExtinction;    // the extinction of the clouds
172   static float                s_rTransparency;  // the transparency of the clouds
173   static float                s_rScatterFactor; // How much the clouds scatter
174   static float                s_rSortAngleErrorTolerance; // how far the view must turn to cause a resort.
175   static float                s_rSortSquareDistanceTolerance; // how far the view must move to cause a resort.
176 };
177
178 #endif //__SKYCLOUD_HPP__