lightdimming.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. enum ELightDimmingState
  2. {
  3. PAUSED,
  4. DIMMING,
  5. PAUSED_DIMMED,
  6. BRIGHTENING
  7. }
  8. /* Enable and configure light dimming
  9. Example setup in ScriptedLightBase constructor:
  10. DimmingConfig dimCfg = new DimmingConfig();
  11. // randomized
  12. dimCfg.SetRandomBrigthnessLimits(10, 50);
  13. dimCfg.SetRandomDimSpeedLimits(0.1, 1);
  14. dimCfg.SetRandomDurationLimits(0.2, 1);
  15. dimCfg.SetRandomBrightenSpeedLimits(0.1, 1);
  16. dimCfg.SetRandomPauseDurationLimits(1, 2);
  17. // custom patterns
  18. float f = LightDimming.FLICKER_TIME;
  19. dimCfg.AddDimmingPattern( {0, 0, 50}, {f, f, 0.1}, {f, f, 2}, {f, f, 0.1}, {0.1, 0.1, 4});
  20. dimCfg.AddDimmingPattern( {0, 50, 0}, {f, 0.1, f}, {f, 1, f}, {f, 0.1, f}, {0.1, 0.1, 3});
  21. dimCfg.SetPatternQueueRepeat(2);
  22. EnableDimming(6.5, dimCfg);
  23. */
  24. class LightDimming
  25. {
  26. const float FLICKER_TIME = 0.05; // duration of a flicker -> when this speed is set in phase, DIM / BRIGHTEN phases are skipped, producing a quick flicker
  27. protected float m_DimBrigthnessBase;
  28. protected float m_DimBrigthnessSpeedCoef; // interp speed multiplier
  29. protected float m_DimBrigthnessTarget; // brightness value we want to dim to
  30. protected float m_DimDelta; // delta used for timing states
  31. protected int m_CurrentPatternID;
  32. protected int m_CurrentEntryID;
  33. protected bool m_ToBeDestroyed;
  34. protected ELightDimmingState m_DimState;
  35. protected ScriptedLightBase m_Light;
  36. protected DimmingConfig m_ActiveCfg;
  37. protected ref array<ref DimmingConfig> m_Configs = new array<ref DimmingConfig>();
  38. void LightDimming(ScriptedLightBase light, float baseBrightness, DimmingConfig dimCfg)
  39. {
  40. m_Light = light;
  41. m_DimBrigthnessBase = baseBrightness;
  42. m_Configs.Insert(dimCfg);
  43. m_ActiveCfg = dimCfg;
  44. }
  45. ELightDimmingState GetState()
  46. {
  47. return m_DimState;
  48. }
  49. // load additional config for dimming to allow switches between multiple configurations
  50. void AddConfig(DimmingConfig cfg)
  51. {
  52. m_Configs.Insert(cfg);
  53. }
  54. protected void SetDimmingVal(float val)
  55. {
  56. m_Light.SetBrightnessTo(val);
  57. }
  58. protected void AdvanceState(ELightDimmingState lastState)
  59. {
  60. if (lastState == ELightDimmingState.PAUSED)
  61. {
  62. m_DimState = ELightDimmingState.DIMMING;
  63. if (m_ActiveCfg.m_UsePatterns)
  64. {
  65. SelectPattern();
  66. if (m_ToBeDestroyed)
  67. return;
  68. m_DimBrigthnessTarget = m_ActiveCfg.m_BrightnessPatterns[m_CurrentPatternID][m_CurrentEntryID] * 0.01 * m_DimBrigthnessBase;
  69. m_DimDelta = m_ActiveCfg.m_DimSpeedPatterns[m_CurrentPatternID][m_CurrentEntryID];
  70. if (m_DimDelta == FLICKER_TIME) // flicker, skip dim interp
  71. {
  72. AdvanceState(ELightDimmingState.DIMMING);
  73. return;
  74. }
  75. }
  76. else
  77. {
  78. m_DimBrigthnessTarget = Math.RandomFloat(m_ActiveCfg.m_DimBrigthnessMin * m_DimBrigthnessBase, m_ActiveCfg.m_DimBrigthnessMax * m_DimBrigthnessBase);
  79. m_DimDelta = Math.RandomFloat(m_ActiveCfg.m_DimSpeedMin, m_ActiveCfg.m_DimSpeedMax);
  80. }
  81. m_DimBrigthnessSpeedCoef = 1/m_DimDelta;
  82. }
  83. else if (lastState == ELightDimmingState.DIMMING)
  84. {
  85. m_DimState = ELightDimmingState.PAUSED_DIMMED;
  86. if (m_ActiveCfg.m_UsePatterns)
  87. m_DimDelta = m_ActiveCfg.m_DurationPatterns[m_CurrentPatternID][m_CurrentEntryID];
  88. else
  89. m_DimDelta = Math.RandomFloat(m_ActiveCfg.m_DimBrigthnessDurationMin,m_ActiveCfg. m_DimBrigthnessDurationMax);
  90. SetDimmingVal(m_DimBrigthnessTarget);
  91. }
  92. else if (lastState == ELightDimmingState.PAUSED_DIMMED)
  93. {
  94. m_DimState = ELightDimmingState.BRIGHTENING;
  95. if (m_ActiveCfg.m_UsePatterns)
  96. {
  97. m_DimDelta = m_ActiveCfg.m_BrightenSpeedPatterns[m_CurrentPatternID][m_CurrentEntryID];
  98. if (m_DimDelta == FLICKER_TIME) // flicker, skip brighten interp
  99. {
  100. AdvanceState(ELightDimmingState.BRIGHTENING);
  101. return;
  102. }
  103. }
  104. else
  105. m_DimDelta = Math.RandomFloat(m_ActiveCfg.m_BrightenSpeedMin, m_ActiveCfg.m_BrightenSpeedMax);
  106. m_DimBrigthnessSpeedCoef = 1/m_DimDelta;
  107. }
  108. else if (lastState == ELightDimmingState.BRIGHTENING)
  109. {
  110. m_DimState = ELightDimmingState.PAUSED;
  111. if (m_ActiveCfg.m_UsePatterns)
  112. {
  113. m_DimDelta = m_ActiveCfg.m_PausePatterns[m_CurrentPatternID][m_CurrentEntryID];
  114. m_CurrentEntryID++;
  115. }
  116. else
  117. m_DimDelta = Math.RandomFloat(m_ActiveCfg.m_DimBrigthnessPauseMin, m_ActiveCfg.m_DimBrigthnessPauseMax);
  118. SetDimmingVal(m_DimBrigthnessBase);
  119. }
  120. }
  121. protected void SelectPattern()
  122. {
  123. if (m_CurrentEntryID != m_ActiveCfg.m_BrightnessPatterns[m_CurrentPatternID].Count())
  124. return; // pattern in progress
  125. m_CurrentPatternID++;
  126. m_CurrentEntryID = 0;
  127. if (m_CurrentPatternID == m_ActiveCfg.m_PatternCount)
  128. {
  129. if (m_ActiveCfg.m_PatternRepeatCount == -1)
  130. m_CurrentPatternID = 0;
  131. else if (m_ActiveCfg.m_PatternRepeatCount == 0)
  132. {
  133. m_ToBeDestroyed = true;
  134. m_Light.StopDimming();
  135. }
  136. else
  137. {
  138. m_ActiveCfg.m_PatternRepeatCount--;
  139. m_CurrentPatternID = 0;
  140. }
  141. }
  142. }
  143. void SwapConfig(int index)
  144. {
  145. if (!m_Configs.IsValidIndex(index))
  146. return;
  147. m_ActiveCfg = m_Configs[index];
  148. m_CurrentPatternID = 0;
  149. m_CurrentEntryID = 0;
  150. m_DimState = ELightDimmingState.PAUSED;
  151. }
  152. void HandleDimming(float timeSlice)
  153. {
  154. if (m_ToBeDestroyed)
  155. return;
  156. m_DimDelta -= timeSlice;
  157. if (m_DimDelta < 0)
  158. {
  159. AdvanceState(m_DimState);
  160. return;
  161. }
  162. if (m_DimState == ELightDimmingState.DIMMING || m_DimState == ELightDimmingState.BRIGHTENING)
  163. {
  164. if (m_DimState == ELightDimmingState.DIMMING)
  165. SetDimmingVal(Math.Lerp(m_DimBrigthnessTarget, m_DimBrigthnessBase, m_DimDelta * m_DimBrigthnessSpeedCoef));
  166. else
  167. SetDimmingVal(Math.Lerp(m_DimBrigthnessBase, m_DimBrigthnessTarget, m_DimDelta * m_DimBrigthnessSpeedCoef));
  168. }
  169. }
  170. }