21 #include "CaelumPrecompiled.h" 22 #include "PrecipitationController.h" 23 #include "InternalUtilities.h" 29 const String PrecipitationController::COMPOSITOR_NAME =
"Caelum/PrecipitationCompositor";
30 const String PrecipitationController::MATERIAL_NAME =
"Caelum/PrecipitationMaterial";
32 const PrecipitationPresetParams PrecipitationPresets[] = {
33 { Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.95,
"precipitation_drizzle.png" },
34 { Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.85,
"precipitation_rain.png" },
35 { Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.12,
"precipitation_snow.png" },
36 { Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.33,
"precipitation_snowgrains.png" },
37 { Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.70,
"precipitation_icecrystals.png" },
38 { Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.78,
"precipitation_icepellets.png" },
39 { Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.74,
"precipitation_hail.png" },
40 { Ogre::ColourValue(0.8, 0.8, 0.8, 1), 0.70,
"precipitation_smallhail.png" }
43 PrecipitationController::PrecipitationController(
44 Ogre::SceneManager *sceneMgr)
46 Ogre::String uniqueId = Ogre::StringConverter::toString((
size_t)
this);
49 setAutoDisableThreshold (0.001);
50 mCameraSpeedScale = Ogre::Vector3::UNIT_SCALE;
53 setWindSpeed (Ogre::Vector3(0, 0, 0));
55 mSecondsSinceLastFrame = 0;
56 mFallingDirection = Ogre::Vector3::NEGATIVE_UNIT_Y;
58 setPresetType (PRECTYPE_RAIN);
60 update (0, Ogre::ColourValue(0, 0, 0, 0));
61 InternalUtilities::checkCompositorSupported(COMPOSITOR_NAME);
64 PrecipitationController::~PrecipitationController () {
65 destroyAllViewportInstances ();
68 void PrecipitationController::setTextureName (
const Ogre::String& textureName) {
69 mPresetType = PRECTYPE_CUSTOM;
70 mTextureName = textureName;
73 const Ogre::String PrecipitationController::getTextureName ()
const {
77 void PrecipitationController::setSpeed (Real speed) {
78 mPresetType = PRECTYPE_CUSTOM;
82 Real PrecipitationController::getSpeed ()
const {
86 void PrecipitationController::setColour (
const Ogre::ColourValue& color) {
87 mPresetType = PRECTYPE_CUSTOM;
91 const Ogre::ColourValue PrecipitationController::getColour ()
const {
96 return PRECTYPE_DRIZZLE <= type && type <= PRECTYPE_SMALLHAIL;
100 assert(isPresetType(type));
101 return PrecipitationPresets[type];
105 setColour (params.Colour);
106 setSpeed (params.Speed);
107 setTextureName (params.Name);
111 setParams (getPresetParams (type));
119 void PrecipitationController::setWindSpeed (
const Ogre::Vector3& value) {
123 const Ogre::Vector3 PrecipitationController::getWindSpeed ()
const {
127 void PrecipitationController::setIntensity (Real intensity) {
128 mIntensity = intensity;
131 Real PrecipitationController::getIntensity ()
const {
135 void PrecipitationController::update (Real secondsSinceLastFrame, Ogre::ColourValue colour) {
136 mSecondsSinceLastFrame = secondsSinceLastFrame;
137 mInternalTime += mSecondsSinceLastFrame;
138 mSceneColour = colour;
140 ViewportInstanceMap::const_iterator it;
141 ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin ();
142 ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end ();
143 for (it = begin; it != end; ++it) {
144 it->second->_update ();
148 void PrecipitationController::setManualCameraSpeed (
const Ogre::Vector3& value) {
149 ViewportInstanceMap::const_iterator it;
150 ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
151 ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
152 for (it = begin; it != end; ++it) {
153 it->second->setManualCameraSpeed(value);
157 void PrecipitationController::setAutoCameraSpeed() {
158 ViewportInstanceMap::const_iterator it;
159 ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
160 ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
161 for (it = begin; it != end; ++it) {
162 it->second->setAutoCameraSpeed();
166 PrecipitationInstance::PrecipitationInstance
169 Ogre::Viewport* viewport
175 mLastCameraPosition(Vector3::ZERO),
176 mCameraSpeed(Vector3::ZERO),
177 mAutoCameraSpeed(
true)
182 PrecipitationInstance::~PrecipitationInstance ()
187 void PrecipitationInstance::createCompositor ()
194 Ogre::CompositorManager* compMgr = Ogre::CompositorManager::getSingletonPtr();
197 mCompInst = compMgr->addCompositor(mViewport, PrecipitationController::COMPOSITOR_NAME);
199 mCompInst->setEnabled (
false);
200 mCompInst->addListener (
this);
203 void PrecipitationInstance::destroyCompositor ()
206 if (mCompInst == 0) {
210 Ogre::CompositorManager* compMgr = Ogre::CompositorManager::getSingletonPtr();
213 mCompInst->removeListener (
this);
214 compMgr->removeCompositor(mViewport, PrecipitationController::COMPOSITOR_NAME);
218 void PrecipitationInstance::notifyMaterialSetup(uint pass_id, Ogre::MaterialPtr &mat)
220 mParams.setup(mat->getTechnique (0)->getPass (0)->getFragmentProgramParameters ());
223 void PrecipitationInstance::Params::setup(Ogre::GpuProgramParametersSharedPtr fpParams)
225 this->fpParams = fpParams;
226 this->precColor.bind(fpParams,
"precColor");
227 this->intensity.bind(fpParams,
"intensity");
228 this->dropSpeed.bind(fpParams,
"dropSpeed");
229 this->corner1.bind(fpParams,
"corner1");
230 this->corner2.bind(fpParams,
"corner2");
231 this->corner3.bind(fpParams,
"corner3");
232 this->corner4.bind(fpParams,
"corner4");
233 this->deltaX.bind(fpParams,
"deltaX");
234 this->deltaY.bind(fpParams,
"deltaY");
237 void PrecipitationInstance::notifyMaterialRender(uint pass_id, Ogre::MaterialPtr &mat)
239 if (mAutoCameraSpeed) {
240 Ogre::Camera* cam = mViewport->getCamera();
241 Ogre::Vector3 camPos = cam->getDerivedPosition();
242 if (cam != mLastCamera) {
243 mCameraSpeed = Ogre::Vector3::ZERO;
245 Real timeDiff = mParent->getSecondsSinceLastFrame ();
246 Ogre::Vector3 posDiff = camPos - mLastCameraPosition;
249 if (timeDiff > 1e-10) {
250 mCameraSpeed = posDiff / timeDiff;
264 mLastCameraPosition = camPos;
267 this->_updateMaterialParams(mat, mViewport->getCamera(), mCameraSpeed);
270 void PrecipitationInstance::_updateMaterialParams(
271 const Ogre::MaterialPtr& mat,
272 const Ogre::Camera* cam,
273 const Ogre::Vector3& camSpeed)
276 Real appTime =
static_cast<Real
>(fmod(mParent->mInternalTime, static_cast<Real>(4523.893416f)));
278 ColourValue sceneColour = mParent->mSceneColour;
279 Real sceneLum = (sceneColour.r + sceneColour.g + sceneColour.b) / 3;
280 mParams.precColor.set(mParams.fpParams, ColourValue::White * sceneLum * mParent->mColour);
281 mParams.intensity.set(mParams.fpParams, mParent->mIntensity);
282 mParams.dropSpeed.set(mParams.fpParams, 0);
284 Ogre::Vector3 corner1, corner2, corner3, corner4;
286 corner1 = cam->getCameraToViewportRay(0, 0).getDirection();
287 corner2 = cam->getCameraToViewportRay(1, 0).getDirection();
288 corner3 = cam->getCameraToViewportRay(0, 1).getDirection();
289 corner4 = cam->getCameraToViewportRay(1, 1).getDirection();
291 Ogre::Vector3 precDir =
292 mParent->mSpeed * mParent->mFallingDirection +
293 mParent->mWindSpeed -
294 camSpeed * mParent->mCameraSpeedScale;
295 Ogre::Quaternion quat = precDir.getRotationTo(Ogre::Vector3(0, -1, 0));
297 corner1 = quat * corner1;
298 corner2 = quat * corner2;
299 corner3 = quat * corner3;
300 corner4 = quat * corner4;
302 mParams.corner1.set(mParams.fpParams, corner1);
303 mParams.corner2.set(mParams.fpParams, corner2);
304 mParams.corner3.set(mParams.fpParams, corner3);
305 mParams.corner4.set(mParams.fpParams, corner4);
307 float fallSpeed = precDir.length();
309 mParams.deltaX.set(mParams.fpParams,
310 Ogre::Vector3(sin(appTime) + 4.33,
311 cos(appTime * 1.5) + 5.26,
312 cos(appTime * 2.5)) * fallSpeed / 10 + 88.001);
313 mParams.deltaY.set(mParams.fpParams,
314 Ogre::Vector3(0.6, 1.0, 1.4) * fallSpeed * appTime);
316 if (mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->getTextureName() != mParent->mTextureName) {
317 mat->getTechnique(0)->getPass(0)->getTextureUnitState(1)->setTextureName(mParent->mTextureName);
321 bool PrecipitationInstance::getAutoCameraSpeed () {
322 return mAutoCameraSpeed;
325 void PrecipitationInstance::setAutoCameraSpeed () {
326 mAutoCameraSpeed =
true;
327 mCameraSpeed = Ogre::Vector3::ZERO;
331 void PrecipitationInstance::setManualCameraSpeed (
const Ogre::Vector3& value) {
332 mAutoCameraSpeed =
false;
333 mCameraSpeed = value;
336 const Ogre::Vector3 PrecipitationInstance::getCameraSpeed () {
340 bool PrecipitationInstance::shouldBeEnabled ()
const {
341 return mParent->getAutoDisableThreshold () < 0 ||
342 mParent->getIntensity () > mParent->getAutoDisableThreshold ();
345 void PrecipitationInstance::_update ()
347 mCompInst->setEnabled (shouldBeEnabled ());
352 ViewportInstanceMap::const_iterator it = mViewportInstanceMap.find (vp);
353 if (it == mViewportInstanceMap.end()) {
355 mViewportInstanceMap.insert (std::make_pair (vp, inst.get()));
357 return inst.release();
364 ViewportInstanceMap::iterator it = mViewportInstanceMap.find (vp);
365 if (it != mViewportInstanceMap.end ()) {
372 void PrecipitationController::destroyViewportInstance (Viewport* vp)
374 ViewportInstanceMap::iterator it = mViewportInstanceMap.find (vp);
375 if (it != mViewportInstanceMap.end ()) {
378 mViewportInstanceMap.erase (it);
382 void PrecipitationController::destroyAllViewportInstances () {
383 ViewportInstanceMap::const_iterator it;
384 ViewportInstanceMap::const_iterator begin = mViewportInstanceMap.begin();
385 ViewportInstanceMap::const_iterator end = mViewportInstanceMap.end();
386 for (it = begin; it != end; ++it) {
387 assert(it->first == it->second->getViewport ());
390 mViewportInstanceMap.clear ();
Compositor-based precipitation controller.
PrecipitationType
An enumeration of the available precipitation presets.
Per-viewport instance of precipitation.
Preset parameters for a certain type of precipitation.