00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "CaelumPrecompiled.h"
00022 #include "GroundFog.h"
00023 #include "CaelumExceptions.h"
00024
00025 namespace caelum {
00026 const Ogre::String GroundFog::DEFAULT_PASS_NAME = "CaelumGroundFog";
00027
00028 GroundFog::GroundFog(
00029 Ogre::SceneManager *sceneMgr,
00030 Ogre::SceneNode *caelumRootNode,
00031 const Ogre::String &domeMaterialName,
00032 const Ogre::String &domeEntityName):
00033 mScene(sceneMgr)
00034 {
00035 mDomeMaterial = Ogre::MaterialManager::getSingleton().getByName(domeMaterialName);
00036 mDomeMaterial = mDomeMaterial->clone(domeMaterialName + Ogre::StringConverter::toString((size_t)this));
00037 mDomeMaterial->load();
00038 if (mDomeMaterial->getBestTechnique() == 0) {
00039 throw new UnsupportedException (0, "GroundFog dome material not supported.",
00040 "GroundFog", "GroundFog.cpp", -1);
00041 }
00042 mDomeMaterial->getBestTechnique()->getPass(0)->getFragmentProgramParameters()->setIgnoreMissingParams(true);
00043 mDomeMaterial->getBestTechnique()->getPass(0)->getVertexProgramParameters()->setIgnoreMissingParams(true);
00044
00045 sceneMgr->getRenderQueue()->getQueueGroup(CAELUM_RENDER_QUEUE_GROUND_FOG)->setShadowsEnabled(false);
00046
00047
00048
00049
00050 mDomeEntity = mScene->createEntity(domeEntityName, Ogre::SceneManager::PT_SPHERE);
00051 mDomeEntity->setMaterialName(mDomeMaterial->getName());
00052 mDomeEntity->setCastShadows(false);
00053 mDomeEntity->setRenderQueueGroup (CAELUM_RENDER_QUEUE_GROUND_FOG);
00054
00055 mDomeNode = caelumRootNode->createChildSceneNode ();
00056 mDomeNode->attachObject (mDomeEntity);
00057
00058
00059 mDensity = 0.1;
00060 mVerticalDecay = 0.2;
00061 mGroundLevel = 5;
00062 mFogColour = Ogre::ColourValue::Black;
00063
00064 forceUpdate();
00065 }
00066
00067 GroundFog::~GroundFog() {
00068
00069 setDensity(0);
00070 mDomeNode->detachObject(mDomeEntity);
00071 mScene->destroyEntity(mDomeEntity);
00072 mDomeEntity = 0;
00073 static_cast<Ogre::SceneNode*>(mDomeNode->getParent())->removeAndDestroyChild(mDomeNode->getName());
00074 mDomeNode = 0;
00075 mScene = 0;
00076 Ogre::MaterialManager::getSingletonPtr()->remove(mDomeMaterial->getHandle());
00077 }
00078
00079 GroundFog::PassSet& GroundFog::getPasses() {
00080 return mPasses;
00081 }
00082
00083 const GroundFog::PassSet& GroundFog::getPasses() const {
00084 return mPasses;
00085 }
00086
00087 void GroundFog::findFogPassesByName (const Ogre::String& passName) {
00088 Ogre::MaterialManager *matManager = Ogre::MaterialManager::getSingletonPtr();
00089 Ogre::MaterialManager::ResourceMapIterator matIt = matManager->getResourceIterator();
00090 while (matIt.hasMoreElements()) {
00091 Ogre::MaterialPtr mat = matIt.getNext();
00092 Ogre::Material::TechniqueIterator techIt = mat->getTechniqueIterator();
00093 while (techIt.hasMoreElements()) {
00094 Ogre::Technique *tech = techIt.getNext();
00095 Ogre::Technique::PassIterator passIt = tech->getPassIterator();
00096 while (passIt.hasMoreElements()) {
00097 Ogre::Pass *pass = passIt.getNext();
00098 if (pass->getName() == passName) {
00099 mPasses.insert(pass);
00100 }
00101 }
00102 }
00103 }
00104 forceUpdate();
00105 }
00106
00107 void GroundFog::setDensity (Ogre::Real density) {
00108 if (Ogre::Math::Abs(mDensity - density) > 0.000001) {
00109 for (PassSet::iterator it = mPasses.begin(); it != mPasses.end(); ++it) {
00110 Ogre::GpuProgramParametersSharedPtr params = (*it)->getFragmentProgramParameters();
00111 params->setNamedConstant("fogDensity", density);
00112 }
00113 mDensity = density;
00114 }
00115 updateSkyFogging();
00116 }
00117
00118 Ogre::Real GroundFog::getDensity () {
00119 return mDensity;
00120 }
00121
00122 void GroundFog::setColour (const Ogre::ColourValue &colour) {
00123 for (PassSet::iterator it = mPasses.begin(); it != mPasses.end(); ++it) {
00124 Ogre::GpuProgramParametersSharedPtr params = (*it)->getFragmentProgramParameters();
00125 params->setNamedConstant("fogColour", colour);
00126 }
00127 mFogColour = colour;
00128 updateSkyFogging();
00129 }
00130
00131 Ogre::ColourValue GroundFog::getColour () {
00132 return mFogColour;
00133 }
00134
00135 void GroundFog::setVerticalDecay (Ogre::Real verticalDecay) {
00136 if (Ogre::Math::Abs(mVerticalDecay - verticalDecay) > 0.000001) {
00137 for (PassSet::iterator it = mPasses.begin(); it != mPasses.end(); ++it) {
00138 Ogre::GpuProgramParametersSharedPtr params = (*it)->getFragmentProgramParameters();
00139 params->setNamedConstant("fogVerticalDecay", verticalDecay);
00140 }
00141 mVerticalDecay = verticalDecay;
00142 }
00143 updateSkyFogging();
00144 }
00145
00146 Ogre::Real GroundFog::getVerticalDecay () {
00147 return mVerticalDecay;
00148 }
00149
00150 void GroundFog::setGroundLevel (Ogre::Real groundLevel) {
00151 if (Ogre::Math::Abs(mGroundLevel - groundLevel) > 0.000001) {
00152 for (PassSet::iterator it = mPasses.begin(); it != mPasses.end(); ++it) {
00153 Ogre::GpuProgramParametersSharedPtr params = (*it)->getFragmentProgramParameters();
00154 params->setNamedConstant("fogGroundLevel", groundLevel);
00155 }
00156 mGroundLevel = groundLevel;
00157 }
00158 updateSkyFogging();
00159 }
00160
00161 Ogre::Real GroundFog::getGroundLevel () {
00162 return mGroundLevel;
00163 }
00164
00165 void GroundFog::forceUpdate () {
00166 for (PassSet::iterator it = mPasses.begin(); it != mPasses.end(); ++it) {
00167 Ogre::GpuProgramParametersSharedPtr params = (*it)->getFragmentProgramParameters();
00168 params->setNamedConstant("fogDensity", mDensity);
00169 params->setNamedConstant("fogVerticalDecay", mVerticalDecay);
00170 params->setNamedConstant("fogGroundLevel", mGroundLevel);
00171 params->setNamedConstant("fogColour", mFogColour);
00172 }
00173 updateSkyFogging();
00174 }
00175
00176 void GroundFog::notifyCameraChanged (Ogre::Camera *cam)
00177 {
00178 CameraBoundElement::notifyCameraChanged (cam);
00179
00180
00181 Ogre::GpuProgramParametersSharedPtr params =
00182 mDomeMaterial->getBestTechnique()->getPass(0)->getFragmentProgramParameters();
00183 params->setNamedConstant("cameraHeight", cam->getDerivedPosition().dotProduct(mDomeNode->_getDerivedOrientation() * Ogre::Vector3::UNIT_Y));
00184 }
00185
00186 void GroundFog::setFarRadius (Ogre::Real radius)
00187 {
00188 CameraBoundElement::setFarRadius(radius);
00189
00190 mDomeNode->setScale(Ogre::Vector3::UNIT_SCALE * radius / 50.0);
00191 }
00192
00193 void GroundFog::updateSkyFogging() {
00194 Ogre::GpuProgramParametersSharedPtr params =
00195 mDomeMaterial->getBestTechnique()->getPass(0)->getFragmentProgramParameters();
00196 params->setNamedConstant("fogDensity", getDensity());
00197 params->setNamedConstant("fogColour", getColour());
00198 params->setNamedConstant("fogVerticalDecay", getVerticalDecay());
00199 params->setNamedConstant("fogGroundLevel", getGroundLevel());
00200 }
00201 }