mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-30 06:15:32 +00:00
thunderstorm
This commit is contained in:
parent
0ebdce543a
commit
4650672bb1
5 changed files with 192 additions and 65 deletions
|
@ -284,9 +284,25 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) :
|
|||
mRootNode->setInheritOrientation(false);
|
||||
|
||||
/// \todo preload all the textures and meshes that are used for sky rendering
|
||||
|
||||
mViewport->setBackgroundColour(ColourValue(0.87, 0.87, 0.87));
|
||||
|
||||
// Create overlay used for thunderstorm
|
||||
MaterialPtr material = MaterialManager::getSingleton().create( "ThunderMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME );
|
||||
Pass* pass = material->getTechnique(0)->getPass(0);
|
||||
pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
|
||||
mThunderTextureUnit = pass->createTextureUnitState();
|
||||
mThunderTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(1.f, 1.f, 1.f)); // always black colour
|
||||
mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, 0.5f);
|
||||
OverlayManager& ovm = OverlayManager::getSingleton();
|
||||
mThunderOverlay = ovm.create( "ThunderOverlay" );
|
||||
OverlayContainer* overlay_panel;
|
||||
overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", "ThunderPanel");
|
||||
overlay_panel->_setPosition(0, 0);
|
||||
overlay_panel->_setDimensions(1, 1);
|
||||
overlay_panel->setMaterialName( "ThunderMaterial" );
|
||||
overlay_panel->show();
|
||||
mThunderOverlay->add2D(overlay_panel);
|
||||
mThunderOverlay->hide();
|
||||
|
||||
mSun = new BillboardObject("textures\\tx_sun_05.dds", 1, Vector3(0.4, 0.4, 0.4), mRootNode);
|
||||
mSunGlare = new BillboardObject("textures\\tx_sun_flash_grey_05.dds", 3, Vector3(0.4, 0.4, 0.4), mRootNode);
|
||||
mSunGlare->setRenderQueue(RENDER_QUEUE_SKIES_LATE);
|
||||
|
@ -294,22 +310,15 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) :
|
|||
mSecunda = new Moon("textures\\tx_secunda_full.dds", 0.5, Vector3(0.4, -0.4, 0.5), mRootNode);
|
||||
mMasser->setType(Moon::Type_Masser);
|
||||
mSecunda->setType(Moon::Type_Secunda);
|
||||
//mMasser->setVisibility(0.2);
|
||||
//mSecunda->setVisibility(0.2);
|
||||
mMasser->setVisible(false);
|
||||
mSecunda->setVisible(false);
|
||||
|
||||
|
||||
HighLevelGpuProgramManager& mgr = HighLevelGpuProgramManager::getSingleton();
|
||||
|
||||
// Stars
|
||||
/// \todo sky_night_02.nif (available in Bloodmoon)
|
||||
/// \todo how to make a transition between day and night sky?
|
||||
MeshPtr mesh = NifOgre::NIFLoader::load("meshes\\sky_night_01.nif");
|
||||
Entity* night1_ent = mSceneMgr->createEntity("meshes\\sky_night_01.nif");
|
||||
night1_ent->setRenderQueueGroup(RENDER_QUEUE_SKIES_EARLY+1);
|
||||
|
||||
ModVertexAlpha(night1_ent, 2);
|
||||
|
||||
|
||||
mAtmosphereNight = mRootNode->createChildSceneNode();
|
||||
mAtmosphereNight->attachObject(night1_ent);
|
||||
|
||||
|
@ -326,7 +335,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) :
|
|||
mStarsMaterials[i] = mp;
|
||||
}
|
||||
|
||||
// Stars vertex shader
|
||||
// Stars vertex shader
|
||||
HighLevelGpuProgramPtr vshader3 = mgr.createProgram("Stars_VP", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
|
||||
"cg", GPT_VERTEX_PROGRAM);
|
||||
vshader3->setParameter("profiles", "vs_2_x arbvp1");
|
||||
|
@ -636,3 +645,14 @@ void SkyManager::setSunDirection(const Vector3& direction)
|
|||
mSun->setPosition(direction);
|
||||
mSunGlare->setPosition(direction);
|
||||
}
|
||||
|
||||
void SkyManager::setThunder(const float factor)
|
||||
{
|
||||
if (factor > 0.f)
|
||||
{
|
||||
mThunderOverlay->show();
|
||||
mThunderTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, factor*0.6);
|
||||
}
|
||||
else
|
||||
mThunderOverlay->hide();
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ namespace Ogre
|
|||
class SceneManager;
|
||||
class Entity;
|
||||
class BillboardSet;
|
||||
class TextureUnitState;
|
||||
class Overlay;
|
||||
}
|
||||
|
||||
namespace MWRender
|
||||
{
|
||||
class BillboardObject
|
||||
class BillboardObject
|
||||
{
|
||||
public:
|
||||
BillboardObject( const Ogre::String& textureName,
|
||||
|
@ -136,6 +138,8 @@ namespace MWRender
|
|||
|
||||
void setSunDirection(const Ogre::Vector3& direction);
|
||||
|
||||
void setThunder(const float factor);
|
||||
|
||||
void setGlare(bool glare);
|
||||
Ogre::Vector3 getRealSunPos();
|
||||
|
||||
|
@ -168,6 +172,9 @@ namespace MWRender
|
|||
float mStarsOpacity;
|
||||
Ogre::ColourValue mCloudColour;
|
||||
Ogre::ColourValue mSkyColour;
|
||||
|
||||
Ogre::Overlay* mThunderOverlay;
|
||||
Ogre::TextureUnitState* mThunderTextureUnit;
|
||||
|
||||
float mRemainingTransitionTime;
|
||||
|
||||
|
|
|
@ -2,19 +2,30 @@
|
|||
#include "world.hpp"
|
||||
|
||||
#include "../mwrender/renderingmanager.hpp"
|
||||
#include "../mwsound/soundmanager.hpp"
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace Ogre;
|
||||
using namespace MWWorld;
|
||||
using namespace MWSound;
|
||||
|
||||
#define TRANSITION_TIME 10
|
||||
|
||||
#define lerp(x, y) (x * (1-factor) + y * factor)
|
||||
|
||||
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, World* world) :
|
||||
mHour(14), mCurrentWeather("clear")
|
||||
const std::string WeatherGlobals::mThunderSoundID0 = "Thunder0";
|
||||
const std::string WeatherGlobals::mThunderSoundID1 = "Thunder1";
|
||||
const std::string WeatherGlobals::mThunderSoundID2 = "Thunder2";
|
||||
const std::string WeatherGlobals::mThunderSoundID3 = "Thunder3";
|
||||
|
||||
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, Environment* env) :
|
||||
mHour(14), mCurrentWeather("clear"), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50),
|
||||
mThunderSoundDelay(0)
|
||||
{
|
||||
mRendering = rendering;
|
||||
mWorld = world;
|
||||
mEnvironment = env;
|
||||
|
||||
#define clr(r,g,b) ColourValue(r/255.f, g/255.f, b/255.f)
|
||||
|
||||
|
@ -22,7 +33,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, World* wor
|
|||
Weather clear;
|
||||
clear.mCloudTexture = "tx_sky_clear.dds";
|
||||
clear.mCloudsMaximumPercent = 1.0;
|
||||
clear.mTransitionDelta = 0.15;
|
||||
clear.mTransitionDelta = 0.015;
|
||||
clear.mSkySunriseColor = clr(118, 141, 164);
|
||||
clear.mSkyDayColor = clr(95, 135, 203);
|
||||
clear.mSkySunsetColor = clr(56, 89, 129);
|
||||
|
@ -39,19 +50,18 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, World* wor
|
|||
clear.mSunDayColor = clr(255, 252, 238);
|
||||
clear.mSunSunsetColor = clr(255, 115, 79);
|
||||
clear.mSunNightColor = clr(59, 97, 176);
|
||||
clear.mSunDiscSunsetColour = clr(255, 189, 157);
|
||||
clear.mSunDiscSunsetColor = clr(255, 189, 157);
|
||||
clear.mLandFogDayDepth = 0.69;
|
||||
clear.mLandFogNightDepth = 0.69;
|
||||
clear.mWindSpeed = 0.1;
|
||||
clear.mCloudSpeed = 1.25;
|
||||
clear.mGlareView = 1.0;
|
||||
|
||||
mWeatherSettings["clear"] = clear;
|
||||
|
||||
Weather cloudy;
|
||||
cloudy.mCloudTexture = "tx_sky_cloudy.dds";
|
||||
cloudy.mCloudsMaximumPercent = 1.0;
|
||||
cloudy.mTransitionDelta = 0.15;
|
||||
cloudy.mTransitionDelta = 0.015;
|
||||
cloudy.mSkySunriseColor = clr(126, 158, 173);
|
||||
cloudy.mSkyDayColor = clr(117, 160, 215);
|
||||
cloudy.mSkySunsetColor = clr(111, 114, 159);
|
||||
|
@ -68,15 +78,42 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, World* wor
|
|||
cloudy.mSunDayColor = clr(255, 236, 221);
|
||||
cloudy.mSunSunsetColor = clr(255, 89, 00);
|
||||
cloudy.mSunNightColor = clr(77, 91, 124);
|
||||
cloudy.mSunDiscSunsetColour = clr(255, 202, 179);
|
||||
cloudy.mSunDiscSunsetColor = clr(255, 202, 179);
|
||||
cloudy.mLandFogDayDepth = 0.72;
|
||||
cloudy.mLandFogNightDepth = 0.72;
|
||||
cloudy.mWindSpeed = 0.2;
|
||||
cloudy.mCloudSpeed = 2;
|
||||
cloudy.mGlareView = 1.0;
|
||||
|
||||
mWeatherSettings["cloudy"] = cloudy;
|
||||
|
||||
Weather thunderstorm;
|
||||
thunderstorm.mCloudTexture = "tx_sky_thunder.dds";
|
||||
thunderstorm.mCloudsMaximumPercent = 0.66;
|
||||
thunderstorm.mTransitionDelta = 0.03;
|
||||
thunderstorm.mSkySunriseColor = clr(35, 36, 39);
|
||||
thunderstorm.mSkyDayColor = clr(97, 104, 115);
|
||||
thunderstorm.mSkySunsetColor = clr(35, 36, 39);
|
||||
thunderstorm.mSkyNightColor = clr(19, 20, 22);
|
||||
thunderstorm.mFogSunriseColor = clr(70, 74, 85);
|
||||
thunderstorm.mFogDayColor = clr(97, 104, 115);
|
||||
thunderstorm.mFogSunsetColor = clr(70, 74, 85);
|
||||
thunderstorm.mFogNightColor = clr(19, 20, 22);
|
||||
thunderstorm.mAmbientSunriseColor = clr(54, 54, 54);
|
||||
thunderstorm.mAmbientDayColor = clr(90, 90, 90);
|
||||
thunderstorm.mAmbientSunsetColor = clr(54, 54, 54);
|
||||
thunderstorm.mAmbientNightColor = clr(49, 51, 54);
|
||||
thunderstorm.mSunSunriseColor = clr(91, 99, 122);
|
||||
thunderstorm.mSunDayColor = clr(138, 144, 155);
|
||||
thunderstorm.mSunSunsetColor = clr(96, 101, 117);
|
||||
thunderstorm.mSunNightColor = clr(55, 76, 110);
|
||||
thunderstorm.mSunDiscSunsetColor = clr(128, 128, 128);
|
||||
thunderstorm.mLandFogDayDepth = 1;
|
||||
thunderstorm.mLandFogNightDepth = 1.15;
|
||||
thunderstorm.mWindSpeed = 0.5;
|
||||
thunderstorm.mCloudSpeed = 3;
|
||||
thunderstorm.mGlareView = 0;
|
||||
mWeatherSettings["thunderstorm"] = thunderstorm;
|
||||
|
||||
/*
|
||||
Weather overcast;
|
||||
overcast.mCloudTexture = "tx_sky_overcast.dds";
|
||||
|
@ -84,7 +121,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering, World* wor
|
|||
mWeatherSettings["overcast"] = overcast;
|
||||
*/
|
||||
|
||||
setWeather("clear", true);
|
||||
setWeather("thunderstorm", true);
|
||||
}
|
||||
|
||||
void WeatherManager::setWeather(const String& weather, bool instant)
|
||||
|
@ -245,26 +282,90 @@ WeatherResult WeatherManager::transition(float factor)
|
|||
|
||||
void WeatherManager::update(float duration)
|
||||
{
|
||||
WeatherResult result;
|
||||
|
||||
if (mNextWeather != "")
|
||||
if (mEnvironment->mWorld->isCellExterior() || mEnvironment->mWorld->isCellQuasiExterior())
|
||||
{
|
||||
mRemainingTransitionTime -= duration;
|
||||
if (mRemainingTransitionTime < 0)
|
||||
WeatherResult result;
|
||||
|
||||
if (mNextWeather != "")
|
||||
{
|
||||
mCurrentWeather = mNextWeather;
|
||||
mNextWeather = "";
|
||||
mRemainingTransitionTime -= duration;
|
||||
if (mRemainingTransitionTime < 0)
|
||||
{
|
||||
mCurrentWeather = mNextWeather;
|
||||
mNextWeather = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mNextWeather != "")
|
||||
result = transition(1-(mRemainingTransitionTime/TRANSITION_TIME));
|
||||
else
|
||||
result = getResult(mCurrentWeather);
|
||||
|
||||
|
||||
if (mWorld->isCellExterior() || mWorld->isCellQuasiExterior())
|
||||
{
|
||||
|
||||
if (mNextWeather != "")
|
||||
result = transition(1-(mRemainingTransitionTime/TRANSITION_TIME));
|
||||
else
|
||||
result = getResult(mCurrentWeather);
|
||||
|
||||
// disable sun during night
|
||||
if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration
|
||||
|| mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
|
||||
mRendering->getSkyManager()->sunDisable();
|
||||
else
|
||||
{
|
||||
// during day, calculate sun angle
|
||||
float height = 1-std::abs(((mHour-13)/7.f));
|
||||
int facing = mHour > 13.f ? 1 : -1;
|
||||
Vector3 final(
|
||||
(1-height)*facing,
|
||||
(1-height)*facing,
|
||||
height);
|
||||
mRendering->setSunDirection(final);
|
||||
|
||||
mRendering->getSkyManager()->sunEnable();
|
||||
}
|
||||
|
||||
if (mCurrentWeather == "thunderstorm" && mNextWeather == "")
|
||||
{
|
||||
if (mThunderFlash > 0)
|
||||
{
|
||||
// play the sound after a delay
|
||||
mThunderSoundDelay -= duration;
|
||||
if (mThunderSoundDelay <= 0)
|
||||
{
|
||||
// pick a random sound
|
||||
int sound = rand() % 4;
|
||||
std::string soundname;
|
||||
if (sound == 0) soundname = WeatherGlobals::mThunderSoundID0;
|
||||
else if (sound == 1) soundname = WeatherGlobals::mThunderSoundID1;
|
||||
else if (sound == 2) soundname = WeatherGlobals::mThunderSoundID2;
|
||||
else if (sound == 3) soundname = WeatherGlobals::mThunderSoundID3;
|
||||
#include <iostream>
|
||||
std::cout << "play sound" << std::endl;
|
||||
mEnvironment->mSoundManager->playSound(soundname, 1.0, 1.0);
|
||||
mThunderSoundDelay = 1000;
|
||||
}
|
||||
|
||||
mThunderFlash -= duration;
|
||||
if (mThunderFlash > 0)
|
||||
mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
|
||||
else
|
||||
{
|
||||
srand(time(NULL));
|
||||
mThunderChanceNeeded = rand() % 100;
|
||||
mThunderChance = 0;
|
||||
mRendering->getSkyManager()->setThunder( 0.f );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no thunder active
|
||||
mThunderChance += duration*4; // chance increases by 4 percent every second
|
||||
if (mThunderChance >= mThunderChanceNeeded)
|
||||
{
|
||||
mThunderFlash = WeatherGlobals::mThunderThreshold;
|
||||
|
||||
mRendering->getSkyManager()->setThunder( mThunderFlash / WeatherGlobals::mThunderThreshold );
|
||||
|
||||
mThunderSoundDelay = WeatherGlobals::mThunderSoundDelay;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mRendering->setAmbientColour(result.mAmbientColor);
|
||||
mRendering->sunEnable();
|
||||
mRendering->setSunColour(result.mSunColor);
|
||||
|
@ -276,24 +377,7 @@ void WeatherManager::update(float duration)
|
|||
{
|
||||
mRendering->sunDisable();
|
||||
mRendering->skyDisable();
|
||||
}
|
||||
|
||||
// disable sun during night
|
||||
if (mHour >= WeatherGlobals::mSunsetTime+WeatherGlobals::mSunsetDuration
|
||||
|| mHour <= WeatherGlobals::mSunriseTime-WeatherGlobals::mSunriseDuration)
|
||||
mRendering->getSkyManager()->sunDisable();
|
||||
else
|
||||
{
|
||||
// during day, calculate sun angle
|
||||
float height = 1-std::abs(((mHour-13)/7.f));
|
||||
int facing = mHour > 13.f ? 1 : -1;
|
||||
Vector3 final(
|
||||
(1-height)*facing,
|
||||
(1-height)*facing,
|
||||
height);
|
||||
mRendering->setSunDirection(final);
|
||||
|
||||
mRendering->getSkyManager()->sunEnable();
|
||||
mRendering->getSkyManager()->setThunder(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace MWRender
|
|||
|
||||
namespace MWWorld
|
||||
{
|
||||
class World;
|
||||
class Environment;
|
||||
|
||||
/// Global weather manager properties (according to INI)
|
||||
struct WeatherGlobals
|
||||
|
@ -72,8 +72,18 @@ namespace MWWorld
|
|||
static const float mSunsetTime = 18;
|
||||
static const float mSunriseDuration = 2;
|
||||
static const float mSunsetDuration = 2;
|
||||
|
||||
// morrowind sets these per-weather, but since they are only used by 'thunderstorm'
|
||||
// weather setting anyway, we can just as well set them globally
|
||||
static const float mThunderFrequency = .4;
|
||||
static const float mThunderThreshold = 0.6;
|
||||
static const float mThunderSoundDelay = 0.25;
|
||||
static const std::string mThunderSoundID0;
|
||||
static const std::string mThunderSoundID1;
|
||||
static const std::string mThunderSoundID2;
|
||||
static const std::string mThunderSoundID3;
|
||||
};
|
||||
|
||||
|
||||
/// Defines the actual weather that results from weather setting (see below), time of day and weather transition
|
||||
struct WeatherResult
|
||||
{
|
||||
|
@ -142,7 +152,7 @@ namespace MWWorld
|
|||
mLandFogNightDepth;
|
||||
|
||||
// Color modulation for the sun itself during sunset (not completely sure)
|
||||
Ogre::ColourValue mSunDiscSunsetColour;
|
||||
Ogre::ColourValue mSunDiscSunsetColor;
|
||||
|
||||
// Duration of weather transition
|
||||
// the INI value is 0.015, so I suppose this is measured in Morrowind-days? (0.015 days = 36 minutes in Morrowind)
|
||||
|
@ -164,7 +174,8 @@ namespace MWWorld
|
|||
// This is used for Blight, Ashstorm and Blizzard (Bloodmoon)
|
||||
Ogre::String mAmbientLoopSoundID;
|
||||
|
||||
/// \todo rain, thunder, ashstorm...
|
||||
// Rain sound effect
|
||||
Ogre::String mRainLoopSoundID;
|
||||
|
||||
/// \todo disease chance
|
||||
};
|
||||
|
@ -175,7 +186,7 @@ namespace MWWorld
|
|||
class WeatherManager
|
||||
{
|
||||
public:
|
||||
WeatherManager(MWRender::RenderingManager*, MWWorld::World*);
|
||||
WeatherManager(MWRender::RenderingManager*, MWWorld::Environment*);
|
||||
|
||||
/**
|
||||
* Change the weather setting
|
||||
|
@ -201,7 +212,7 @@ namespace MWWorld
|
|||
int mDay, mMonth;
|
||||
|
||||
MWRender::RenderingManager* mRendering;
|
||||
MWWorld::World* mWorld;
|
||||
MWWorld::Environment* mEnvironment;
|
||||
|
||||
std::map<Ogre::String, Weather> mWeatherSettings;
|
||||
|
||||
|
@ -210,6 +221,11 @@ namespace MWWorld
|
|||
|
||||
float mRemainingTransitionTime;
|
||||
|
||||
float mThunderFlash;
|
||||
float mThunderChance;
|
||||
float mThunderChanceNeeded;
|
||||
float mThunderSoundDelay;
|
||||
|
||||
WeatherResult transition(const float factor);
|
||||
WeatherResult getResult(const Ogre::String& weather);
|
||||
};
|
||||
|
|
|
@ -160,7 +160,7 @@ namespace MWWorld
|
|||
|
||||
mRendering = new MWRender::RenderingManager(renderer, resDir, mPhysEngine, environment);
|
||||
|
||||
mWeatherManager = new MWWorld::WeatherManager(mRendering, this);
|
||||
mWeatherManager = new MWWorld::WeatherManager(mRendering, &environment);
|
||||
|
||||
boost::filesystem::path masterPath (fileCollections.getCollection (".esm").getPath (master));
|
||||
|
||||
|
|
Loading…
Reference in a new issue