You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/components/sceneutil/lightcontroller.cpp

88 lines
2.4 KiB
C++

#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;
osg::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;
}
}