Caelum
GroundFog.cpp
1 /*
2 This file is part of Caelum.
3 See http://www.ogre3d.org/wiki/index.php/Caelum
4 
5 Copyright (c) 2006-2007 Caelum team. See Contributors.txt for details.
6 
7 Caelum is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 Caelum is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16 
17 You should have received a copy of the GNU Lesser General Public License
18 along with Caelum. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "CaelumPrecompiled.h"
22 #include "GroundFog.h"
23 #include "CaelumExceptions.h"
24 #include "InternalUtilities.h"
25 
26 namespace Caelum
27 {
28  const Ogre::String GroundFog::DEFAULT_PASS_NAME = "CaelumGroundFog";
29 
31  Ogre::SceneManager *sceneMgr,
32  Ogre::SceneNode *caelumRootNode,
33  const Ogre::String &domeMaterialName,
34  const Ogre::String &domeEntityName):
35  mScene(sceneMgr)
36  {
37  Ogre::String uniqueSuffix = InternalUtilities::pointerToString (this);
38 
39  mDomeMaterial.reset(InternalUtilities::checkLoadMaterialClone (domeMaterialName, domeMaterialName + uniqueSuffix));
40  mDomeParams.setup(mDomeMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters());
41 
42  // Create dome entity, using a prefab sphere.
43  // The prefab sphere has a radius of 50 units.
44  // If this changes in future version of ogre this might break.
45  mDomeEntity.reset (mScene->createEntity (domeEntityName, Ogre::SceneManager::PT_SPHERE));
46  mDomeEntity->setMaterialName (mDomeMaterial->getName ());
47  mDomeEntity->setCastShadows (false);
48  mDomeEntity->setRenderQueueGroup (CAELUM_RENDER_QUEUE_GROUND_FOG);
49  sceneMgr->getRenderQueue()->getQueueGroup(CAELUM_RENDER_QUEUE_GROUND_FOG)->setShadowsEnabled(false);
50 
51  // Create dome node
52  mDomeNode.reset (caelumRootNode->createChildSceneNode ());
53  mDomeNode->attachObject (mDomeEntity.get());
54 
55  // Initialize default fog parameters
56  mDensity = 0.1;
57  mVerticalDecay = 0.2;
58  mGroundLevel = 5;
59  mFogColour = Ogre::ColourValue::Black;
60 
61  forceUpdate();
62  }
63 
65  // Disable passes.
66  setDensity(0);
67  }
68 
70  return mPasses;
71  }
72 
74  return mPasses;
75  }
76 
77  void GroundFog::findFogPassesByName (const Ogre::String& passName) {
78  Ogre::MaterialManager *matManager = Ogre::MaterialManager::getSingletonPtr();
79  Ogre::MaterialManager::ResourceMapIterator matIt = matManager->getResourceIterator();
80  while (matIt.hasMoreElements()) {
81 
82 #if OGRE_VERSION >= 0x00010900
83  Ogre::MaterialPtr mat = matIt.getNext().staticCast<Ogre::Material>();
84 #else
85  Ogre::MaterialPtr mat = matIt.getNext();
86 #endif
87 
88  Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
89  while (techIt.hasMoreElements()) {
90  Ogre::Technique *tech = techIt.getNext();
91  Ogre::Technique::PassIterator passIt = tech->getPassIterator();
92  while (passIt.hasMoreElements()) {
93  Ogre::Pass *pass = passIt.getNext();
94  if (pass->getName() == passName) {
95  mPasses.insert(pass);
96  }
97  }
98  }
99  }
100  forceUpdate();
101  }
102 
103  void GroundFog::setDensity (Ogre::Real density) {
104  if (Ogre::Math::Abs(mDensity - density) > 0.000001) {
105  for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
106  it->fogDensity.set(it->fpParams, density);
107  }
108  mDensity = density;
109  }
110  updateSkyFogging();
111  }
112 
113  Ogre::Real GroundFog::getDensity () const {
114  return mDensity;
115  }
116 
117  void GroundFog::setColour (const Ogre::ColourValue &colour) {
118  bool different =
119  Ogre::Math::Abs(mFogColour.r - colour.r) > 0.001 ||
120  Ogre::Math::Abs(mFogColour.g - colour.g) > 0.001 ||
121  Ogre::Math::Abs(mFogColour.b - colour.b) > 0.001 ||
122  Ogre::Math::Abs(mFogColour.a - colour.a) > 0.001;
123  if (different) {
124  for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
125  it->fogColour.set(it->fpParams, colour);
126  }
127  mFogColour = colour;
128  }
129  updateSkyFogging();
130  }
131 
132  const Ogre::ColourValue GroundFog::getColour () const {
133  return mFogColour;
134  }
135 
136  void GroundFog::setVerticalDecay (Ogre::Real verticalDecay) {
137  if (Ogre::Math::Abs(mVerticalDecay - verticalDecay) > 0.000001) {
138  for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
139  it->fogVerticalDecay.set(it->fpParams, verticalDecay);
140  }
141  mVerticalDecay = verticalDecay;
142  }
143  updateSkyFogging();
144  }
145 
146  Ogre::Real GroundFog::getVerticalDecay () const {
147  return mVerticalDecay;
148  }
149 
150  void GroundFog::setGroundLevel (Ogre::Real groundLevel) {
151  if (Ogre::Math::Abs(mGroundLevel - groundLevel) > 0.000001) {
152  for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
153  it->fogGroundLevel.set(it->fpParams, groundLevel);
154  }
155  mGroundLevel = groundLevel;
156  }
157  updateSkyFogging();
158  }
159 
160  Ogre::Real GroundFog::getGroundLevel () const {
161  return mGroundLevel;
162  }
163 
164  void GroundFog::updateSkyFogging() {
165  mDomeParams.fogDensity.set(mDomeParams.fpParams, mDensity);
166  mDomeParams.fogVerticalDecay.set(mDomeParams.fpParams, mVerticalDecay);
167  mDomeParams.fogGroundLevel.set(mDomeParams.fpParams, mGroundLevel);
168  mDomeParams.fogColour.set(mDomeParams.fpParams, mFogColour);
169  }
170 
172  {
173  updatePassFogParams();
174  for (PassFogParamsVector::const_iterator it = mPassFogParams.begin(), end = mPassFogParams.end(); it != end; ++it) {
175  const PassFogParams& params = *it;
176  params.fogDensity.set(params.fpParams, mDensity);
177  params.fogVerticalDecay.set(params.fpParams, mVerticalDecay);
178  params.fogGroundLevel.set(params.fpParams, mGroundLevel);
179  params.fogColour.set(params.fpParams, mFogColour);
180  }
181  updateSkyFogging();
182  }
183 
184  void GroundFog::updatePassFogParams ()
185  {
186  mPassFogParams.clear();
187  for (PassSet::const_iterator it = mPasses.begin(), end = mPasses.end(); it != end; ++it) {
188  mPassFogParams.push_back(PassFogParams((*it)->getFragmentProgramParameters()));
189  }
190  std::sort(mPassFogParams.begin(), mPassFogParams.end(), PassFogParams::lessThanByParams);
191  std::unique(mPassFogParams.begin(), mPassFogParams.end(), PassFogParams::equalByParams);
192  }
193 
194  void GroundFog::FogParamsBase::setup(Ogre::GpuProgramParametersSharedPtr fpParams) {
195  this->fpParams = fpParams;
196  fogDensity.bind(fpParams, "fogDensity");
197  fogVerticalDecay.bind(fpParams, "fogVerticalDecay");
198  fogGroundLevel.bind(fpParams, "fogGroundLevel");
199  fogColour.bind(fpParams, "fogColour");
200  }
201 
202  void GroundFog::DomeFogParams::setup(Ogre::GpuProgramParametersSharedPtr fpParams) {
203  FogParamsBase::setup(fpParams);
204  cameraHeight.bind(fpParams, "cameraHeight");
205  }
206 
207  void GroundFog::notifyCameraChanged (Ogre::Camera *cam)
208  {
210 
211  // Send camera height to shader.
212  float cameraHeight = cam->getDerivedPosition().dotProduct(mDomeNode->_getDerivedOrientation() * Ogre::Vector3::UNIT_Y);
213  mDomeParams.cameraHeight.set(mDomeParams.fpParams, cameraHeight);
214  }
215 
216  void GroundFog::setFarRadius (Ogre::Real radius)
217  {
219  // Adjust for radius 50.
220  mDomeNode->setScale(Ogre::Vector3::UNIT_SCALE * radius / 50.0);
221  }
222 }
void setGroundLevel(Ogre::Real GroundLevela)
Sets the ground level.
Definition: GroundFog.cpp:150
virtual void notifyCameraChanged(Ogre::Camera *cam)=0
Notify new camera conditions.
virtual void setFarRadius(Ogre::Real radius)
Handle far radius.
Definition: GroundFog.cpp:216
const Ogre::ColourValue getColour() const
Gets fog colour.
Definition: GroundFog.cpp:132
void setDensity(Ogre::Real density)
Sets the fog density multiplier.
Definition: GroundFog.cpp:103
virtual ~GroundFog()
Virtual destructor.
Definition: GroundFog.cpp:64
static const Ogre::String pointerToString(void *pointer)
Quickly format a pointer as a string; in hex.
void findFogPassesByName(const Ogre::String &passName=DEFAULT_PASS_NAME)
Find caelum fog passes to control by name.
Definition: GroundFog.cpp:77
static Ogre::MaterialPtr checkLoadMaterialClone(const Ogre::String &originalName, const Ogre::String &cloneName)
Creates a private clone of a material from a script.
virtual void setFarRadius(Ogre::Real radius)
Abstract method to set the radius for this elements Derived classes should override this and resize t...
void setColour(const Ogre::ColourValue &colour)
Sets fog colour.
Definition: GroundFog.cpp:117
std::set< Ogre::Pass * > PassSet
Typedef for easier manipulation of a set of Passes.
Definition: GroundFog.h:65
void forceUpdate()
Forces an update of all the passes.
Definition: GroundFog.cpp:171
void reset(const InnerPointerType &newInner=TraitsT::getNullValue())
Change the inner value.
Definition: PrivatePtr.h:94
PassSet & getPasses()
Get the set of currently controlled passes.
Definition: GroundFog.cpp:69
virtual void notifyCameraChanged(Ogre::Camera *cam)
Handle camera change.
Definition: GroundFog.cpp:207
void setVerticalDecay(Ogre::Real verticalDecay)
Sets the vertical fog decay constant.
Definition: GroundFog.cpp:136
Ogre::Real getDensity() const
Get the fog density multiplier.
Definition: GroundFog.cpp:113
Ogre::Real getVerticalDecay() const
Get the vertical fog decay constant.
Definition: GroundFog.cpp:146
Ogre::Real getGroundLevel() const
Get the ground level.
Definition: GroundFog.cpp:160
Caelum namespace.
Definition: Astronomy.cpp:24
GroundFog(Ogre::SceneManager *scene, Ogre::SceneNode *caelumRootNode, const Ogre::String &domeMaterialName="CaelumGroundFogDome", const Ogre::String &domeEntityName="CaelumGroundFogDome")
Constructor.
Definition: GroundFog.cpp:30