mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-29 10:56:37 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			87 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			87 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;
 | |
|     }
 | |
| 
 | |
| }
 |