mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-20 03:53:52 +00:00
Merge remote-tracking branch 'blunted2night/better_flicker'
This commit is contained in:
commit
41767f8dfa
2 changed files with 87 additions and 60 deletions
|
@ -235,8 +235,9 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f
|
||||||
else
|
else
|
||||||
info.type = LT_Normal;
|
info.type = LT_Normal;
|
||||||
|
|
||||||
// random starting phase for the animation
|
// randomize lights animations
|
||||||
info.time = Ogre::Math::RangeRandom(0, 2 * Ogre::Math::PI);
|
info.time = Ogre::Math::RangeRandom(-500, +500);
|
||||||
|
info.phase = Ogre::Math::RangeRandom(-500, +500);
|
||||||
|
|
||||||
// adjust the lights depending if we're in an interior or exterior cell
|
// adjust the lights depending if we're in an interior or exterior cell
|
||||||
// quadratic means the light intensity falls off quite fast, resulting in a
|
// quadratic means the light intensity falls off quite fast, resulting in a
|
||||||
|
@ -373,6 +374,48 @@ void Objects::disableLights()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace pulse
|
||||||
|
{
|
||||||
|
static float frequency (float x)
|
||||||
|
{
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float amplitude (float phase)
|
||||||
|
{
|
||||||
|
return sin (phase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace flicker
|
||||||
|
{
|
||||||
|
static const float fa = 0.785398f;
|
||||||
|
static const float fb = 1.17024f;
|
||||||
|
|
||||||
|
static const float tdo = 0.94f;
|
||||||
|
static const float tdm = 2.48f;
|
||||||
|
|
||||||
|
static const float f [3] = { 1.5708f, 4.18774f, 5.19934f };
|
||||||
|
static const float o [3] = { 0.804248f, 2.11115f, 3.46832f };
|
||||||
|
static const float m [3] = { 1.0f, 0.785f, 0.876f };
|
||||||
|
static const float s = 0.394f;
|
||||||
|
|
||||||
|
static const float phase_wavelength = 120.0f * 3.14159265359f / fa;
|
||||||
|
|
||||||
|
static float frequency (float x)
|
||||||
|
{
|
||||||
|
return tdo + tdm * sin (fa * x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float amplitude (float x)
|
||||||
|
{
|
||||||
|
float v = 0.0f;
|
||||||
|
for (int i = 0; i < 3; ++i)
|
||||||
|
v += sin (fb*x*f[i] + o[1])*m[i];
|
||||||
|
return v * s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Objects::update(const float dt)
|
void Objects::update(const float dt)
|
||||||
{
|
{
|
||||||
std::vector<LightInfo>::iterator it = mLights.begin();
|
std::vector<LightInfo>::iterator it = mLights.begin();
|
||||||
|
@ -382,77 +425,64 @@ void Objects::update(const float dt)
|
||||||
{
|
{
|
||||||
Ogre::Light* light = mMwRoot->getCreator()->getLight(it->name);
|
Ogre::Light* light = mMwRoot->getCreator()->getLight(it->name);
|
||||||
|
|
||||||
// Light animation (pulse & flicker)
|
|
||||||
it->time += dt;
|
float brightness;
|
||||||
const float phase = std::fmod(static_cast<double> (it->time), static_cast<double>(32 * 2 * Ogre::Math::PI)) * 20;
|
float cycle_time;
|
||||||
float pulseConstant;
|
float time_distortion;
|
||||||
|
|
||||||
|
if ((it->type == LT_Pulse) && (it->type == LT_PulseSlow))
|
||||||
|
{
|
||||||
|
cycle_time = 2 * Ogre::Math::PI;
|
||||||
|
time_distortion = 20.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cycle_time = 500.0f;
|
||||||
|
it->phase = fmod (it->phase + dt, flicker::phase_wavelength);
|
||||||
|
time_distortion = flicker::frequency (it->phase);
|
||||||
|
}
|
||||||
|
|
||||||
|
it->time += it->dir*dt*time_distortion;
|
||||||
|
if (it->dir > 0 && it->time > +cycle_time)
|
||||||
|
{
|
||||||
|
it->dir = -1.0f;
|
||||||
|
it->time = +2*cycle_time - it->time;
|
||||||
|
}
|
||||||
|
if (it->dir < 0 && it->time < -cycle_time)
|
||||||
|
{
|
||||||
|
it->dir = +1.0f;
|
||||||
|
it->time = -2*cycle_time - it->time;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const float fast = 4.0f/1.0f;
|
||||||
|
static const float slow = 1.0f/1.0f;
|
||||||
|
|
||||||
// These formulas are just guesswork, but they work pretty well
|
// These formulas are just guesswork, but they work pretty well
|
||||||
if (it->type == LT_Normal)
|
if (it->type == LT_Normal)
|
||||||
{
|
{
|
||||||
// Less than 1/255 light modifier for a constant light:
|
// Less than 1/255 light modifier for a constant light:
|
||||||
pulseConstant = (const float)(1.0 + sin(phase) / 255.0 );
|
brightness = (const float)(1.0 + flicker::amplitude(it->time*slow) / 255.0 );
|
||||||
}
|
}
|
||||||
else if (it->type == LT_Flicker)
|
else if (it->type == LT_Flicker)
|
||||||
{
|
{
|
||||||
// Let's do a 50% -> 100% sine wave pulse over 1 second:
|
brightness = (const float)(0.75 + flicker::amplitude(it->time*fast) * 0.25);
|
||||||
// This is 75% +/- 25%
|
|
||||||
pulseConstant = (const float)(0.75 + sin(phase) * 0.25);
|
|
||||||
|
|
||||||
// Then add a 25% flicker variation:
|
|
||||||
it->resetTime -= dt;
|
|
||||||
if (it->resetTime < 0)
|
|
||||||
{
|
|
||||||
it->flickerVariation = (rand() % 1000) / 1000 * 0.25;
|
|
||||||
it->resetTime = 0.5;
|
|
||||||
}
|
|
||||||
if (it->resetTime > 0.25)
|
|
||||||
{
|
|
||||||
pulseConstant = (pulseConstant+it->flickerVariation) * (1-it->resetTime * 2.0f) + pulseConstant * it->resetTime * 2.0f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pulseConstant = (pulseConstant+it->flickerVariation) * (it->resetTime * 2.0f) + pulseConstant * (1-it->resetTime * 2.0f);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (it->type == LT_FlickerSlow)
|
else if (it->type == LT_FlickerSlow)
|
||||||
{
|
{
|
||||||
// Let's do a 50% -> 100% sine wave pulse over 1 second:
|
brightness = (const float)(0.75 + flicker::amplitude(it->time*slow) * 0.25);
|
||||||
// This is 75% +/- 25%
|
|
||||||
pulseConstant = (const float)(0.75 + sin(phase / 4.0) * 0.25);
|
|
||||||
|
|
||||||
// Then add a 25% flicker variation:
|
|
||||||
it->resetTime -= dt;
|
|
||||||
if (it->resetTime < 0)
|
|
||||||
{
|
|
||||||
it->flickerVariation = (rand() % 1000) / 1000 * 0.25;
|
|
||||||
it->resetTime = 0.5;
|
|
||||||
}
|
|
||||||
if (it->resetTime > 0.5)
|
|
||||||
{
|
|
||||||
pulseConstant = (pulseConstant+it->flickerVariation) * (1-it->resetTime) + pulseConstant * it->resetTime;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pulseConstant = (pulseConstant+it->flickerVariation) * (it->resetTime) + pulseConstant * (1-it->resetTime);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (it->type == LT_Pulse)
|
else if (it->type == LT_Pulse)
|
||||||
{
|
{
|
||||||
// Let's do a 75% -> 125% sine wave pulse over 1 second:
|
brightness = (const float)(1.0 + pulse::amplitude (it->time*fast) * 0.25);
|
||||||
// This is 100% +/- 25%
|
|
||||||
pulseConstant = (const float)(1.0 + sin(phase) * 0.25);
|
|
||||||
}
|
}
|
||||||
else if (it->type == LT_PulseSlow)
|
else if (it->type == LT_PulseSlow)
|
||||||
{
|
{
|
||||||
// Let's do a 75% -> 125% sine wave pulse over 1 second:
|
brightness = (const float)(1.0 + pulse::amplitude (it->time*slow) * 0.25);
|
||||||
// This is 100% +/- 25%
|
|
||||||
pulseConstant = (const float)(1.0 + sin(phase / 4.0) * 0.25);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(0 && "Invalid light type");
|
assert(0 && "Invalid light type");
|
||||||
|
|
||||||
light->setDiffuseColour( it->colour * pulseConstant );
|
light->setDiffuseColour(it->colour * brightness);
|
||||||
|
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,16 +34,13 @@ struct LightInfo
|
||||||
LightType type;
|
LightType type;
|
||||||
|
|
||||||
// Runtime variables
|
// Runtime variables
|
||||||
float flickerVariation; // 25% flicker variation, reset once every 0.5 seconds
|
float dir; // direction time is running...
|
||||||
float flickerSlowVariation; // 25% flicker variation, reset once every 1.0 seconds
|
float time; // current time
|
||||||
float resetTime;
|
float phase; // current phase
|
||||||
long double time;
|
|
||||||
|
|
||||||
|
|
||||||
LightInfo() :
|
LightInfo() :
|
||||||
flickerVariation(0), resetTime(0.5),
|
dir(1.0f), time(0.0f), phase (0.0f),
|
||||||
flickerSlowVariation(0), time(0), interior(true),
|
interior(true), type(LT_Normal), radius(1.0)
|
||||||
type(LT_Normal), radius(1.0)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue