File: lightcontroller.cpp

package info (click to toggle)
openmw 0.49.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,992 kB
  • sloc: cpp: 372,479; xml: 2,149; sh: 1,403; python: 797; makefile: 26
file content (87 lines) | stat: -rw-r--r-- 2,484 bytes parent folder | download
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;
    }

}