1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
|
#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;
}
}
|