Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
2.5 kB · 87 lines
C++
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788#include "lightcontroller.hpp"
#include <cmath>
#include <osg/NodeVisitor>
#include <components/sceneutil/lightmanager.hpp>
#include <components/misc/rng.hpp>
namespace SceneUtil{
LightController::LightController() : mType(LT_Normal) , mPhase(0.25f + Misc::Rng::rollClosedProbability() * 0.75f) , mBrightness(0.675f) , mStartTime(0.0) , mLastTime(0.0) , mTicksToAdvance(0.f) { }
void LightController::setType(LightController::LightType type) { mType = type; }
void LightController::operator()(SceneUtil::LightSource* node, osg::NodeVisitor* nv) { double time = nv->getFrameStamp()->getSimulationTime(); if (mStartTime == 0) mStartTime = time;
// disabled early out, light state needs to be set every frame regardless of change, due to the double buffering // if (time == mLastTime) // return;
SceneUtil::Light* light = node->getLight(nv->getTraversalNumber());
if (mType == LT_Normal) { light->setDiffuse(mDiffuseColor); light->setSpecular(mSpecularColor); traverse(node, nv); return; }
// Updating flickering at 15 FPS like vanilla. constexpr float updateRate = 15.f; mTicksToAdvance = static_cast<float>(time - mStartTime - mLastTime) * updateRate * 0.25f + mTicksToAdvance * 0.75f; mLastTime = time - mStartTime;
float speed = (mType == LT_Flicker || mType == LT_Pulse) ? 0.1f : 0.05f; if (mBrightness >= mPhase) mBrightness -= mTicksToAdvance * speed; else mBrightness += mTicksToAdvance * speed;
if (std::abs(mBrightness - mPhase) < speed) { if (mType == LT_Flicker || mType == LT_FlickerSlow) mPhase = 0.25f + Misc::Rng::rollClosedProbability() * 0.75f; else // if (mType == LT_Pulse || mType == LT_PulseSlow) mPhase = mPhase <= 0.5f ? 1.f : 0.25f; }
const float result = mBrightness * node->getActorFade();
light->setDiffuse(mDiffuseColor * result); light->setSpecular(mSpecularColor * result);
traverse(node, nv); }
void LightController::setDiffuse(const osg::Vec4f& color) { mDiffuseColor = color; }
void LightController::setSpecular(const osg::Vec4f& color) { mSpecularColor = color; }
}