Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_LightManualCameraComponent.c
Go to the documentation of this file.
1 
4 [BaseContainerProps(), SCR_BaseManualCameraComponentTitle()]
6 {
7  [Attribute(params: "et")]
8  protected ResourceName m_LightPrefab;
9 
10  [Attribute("-24")]
11  protected float m_fLongitudinalOffset;
12 
13  [Attribute(defvalue: "")]
14  protected string m_sSoundEvent;
15 
16  [Attribute(defvalue: "255,255,255,0", desc: "Color of Camera attached light")]
17  protected ref Color m_cCameraLightColor;
18 
19  [Attribute(defvalue: "255,255,255,0", desc: "Color of pointing light")]
20  protected ref Color m_cPointingLightColor;
21 
22  [Attribute("0 0 1 1", UIWidgets.GraphDialog, "", params: "1 1 0 0")]
23  protected ref Curve m_cCameraLightIntensityCurve;
24 
25  [Attribute("0 0 1 1", UIWidgets.GraphDialog, "", params: "1 1 0 0")]
26  protected ref Curve m_cPointingLightIntensityCurve;
27 
28  [Attribute("150", desc: "How high in the air is the light compaired to the ground at the given position if it does not follow the camera")]
29  protected float m_fPointingLightHeight;
30 
31  [Attribute("0", desc: "(Keyboard) How high does the camera need to be from the ground before the system considers showing the pointing light (still only showing when ShowPointingLightDistance is reached)")]
32  protected float m_fCameraHeightBeforeShowPointing_keyboard;
33 
34  [Attribute("0", desc: "(Gamepad) How high does the camera need to be from the ground before the system considers showing the pointing light (still only showing when ShowPointingLightDistance is reached)")]
35  protected float m_fCameraHeightBeforeShowPointing_gamepad;
36 
37  [Attribute("100", desc: "(Keyboard) How far does the hit location need to be before the pointing light is shown")]
38  protected float m_fShowPointingLightDistance_keyboard;
39 
40  [Attribute("100", desc: "(Gamepad) How far does the hit location need to be before the pointing light is shown")]
41  protected float m_fShowPointingLightDistance_gamepad;
42 
43  [Attribute("1", desc: "If false the rotation is the same as camera. If true it will set the m_fLightDeattachedRotationOverrideY as pointing light rotation Y")]
44  protected bool m_bPointingLightRotationOverride;
45 
46  [Attribute("-75", desc: "Will set pointing light rotation Y to this value if m_bPointingLightRotationOverride is true")]
47  protected float m_fPointingLightRotationOverrideY;
48 
49  [Attribute("100", desc: "Distance from ground when Camera light is at max intensity", params: "0 99999")]
50  protected float m_fCameraLightIntensityMaxHeight;
51 
52  [Attribute("200", desc: "Pointing light will be max light intensity fi this distance from light or higher")]
53  protected float m_fPointingLightIntensityMaxDistance;
54 
55 
56  [Attribute("17", desc: "Min intensity of camera light. This uses the ground level (alpha 0) to calculate the alpha to use in m_cCameraLightIntensityCurve", params: "-8 21")]
57  protected float m_fCameraLightIntesityMin;
58 
59  [Attribute("17", desc: "Max intensity of camera light. This uses m_fCameraLightIntensityMaxHeight from ground (alpha 1) to calculate the alpha to use in m_cCameraLightIntensityCurve", params: "-8 21")]
60  protected float m_fCameraLightIntesityMax;
61 
62 
63  [Attribute("17", desc: "Min intensity of pointer light. This uses the m_fPointingLightIntensityMaxDistance (alpha 0) to calculate the alpha to use in m_cPointingLightIntensityCurve", params: "-8 21")]
64  protected float m_fPointingLightIntesityMin;
65 
66  [Attribute("17", desc: "Max intensity of pointer light. This uses the m_fPointingLightIntensityMaxDistance (alpha 1) to calculate alpha to use in m_cPointingLightIntensityCurve", params: "-8 21")]
67  protected float m_fPointingLightIntesityMax;
68 
69  protected bool m_bIsUsingKeyboardAndMouse = true;
70 
71  //~ Max and min values of LV light to cap any overflow and prevent errors
72  protected float m_fLightMaxLV = 21;
73  protected float m_fLightMinLV = -8;
74 
75  protected LightEntity m_CameraLight;
76  protected LightEntity m_PointingLight;
77  protected BaseWorld m_World;
78  protected WorkspaceWidget m_WorkSpace;
79 
80  protected bool m_bIsLightOn;
81  protected ref ScriptInvoker Event_OnLightChanged = new ScriptInvoker();
82 
83  protected bool m_bLightAtCameraPosition = true;
84  private const float LIGHT_TRACE_DISTANCE = 1500;
85  private const float LIGHT_MOUSE_Y_OFFSET = 20;
86 
87  //------------------------------------------------------------------------------------------------
89  void ToggleLight()
90  {
91  if (!IsEnabled())
92  return;
93 
94  SetLight(m_CameraLight == null);
95  }
96 
97  //------------------------------------------------------------------------------------------------
101  void SetLight(bool enable, bool noSound = false)
102  {
103  //--- No change, ignore
104  if (enable == (m_CameraLight != null))
105  return;
106 
107  m_bIsLightOn = enable;
108  Event_OnLightChanged.Invoke(enable);
109 
110  if (enable)
111  {
112  m_CameraLight = LightEntity.Cast(GetGame().SpawnEntityPrefab(Resource.Load(m_LightPrefab)));
113 
114  GetCameraEntity().AddChild(m_CameraLight, EAddChildFlags.NONE);
115 
116  vector lightTrasform[4];
117  Math3D.MatrixIdentity4(lightTrasform);
118  lightTrasform[3] = Vector(0, 0, m_fLongitudinalOffset);
119  m_CameraLight.SetLocalTransform(lightTrasform);
120 
121  vector cameraTransform[4];
122  GetCameraEntity().GetWorldTransform(cameraTransform);
123  CameraLightIntensityUpdate(cameraTransform);
124  }
125  else
126  {
127  delete m_CameraLight;
128 
129  if (m_PointingLight)
130  delete m_PointingLight;
131  }
132 
133  if (!noSound && !m_sSoundEvent.IsEmpty())
134  SCR_UISoundEntity.SoundEvent(m_sSoundEvent);
135  }
136 
137  //------------------------------------------------------------------------------------------------
138  //~ On mouse and keyboard changed
139  protected void OnInputDeviceIsGamepad(bool isGamepad)
140  {
141  m_bIsUsingKeyboardAndMouse = !isGamepad;
142  }
143 
144  //------------------------------------------------------------------------------------------------
146  bool IsLightOn()
147  {
148  return m_bIsLightOn;
149  }
150 
151  //------------------------------------------------------------------------------------------------
154  ScriptInvoker GetOnLightChanged()
155  {
156  return Event_OnLightChanged;
157  }
158 
159  //------------------------------------------------------------------------------------------------
160  override void EOnCameraSave(SCR_ManualCameraComponentSave data)
161  {
162  if (m_bIsLightOn)
163  data.m_aValues = {m_bIsLightOn};
164  }
165 
166  //------------------------------------------------------------------------------------------------
167  override void EOnCameraLoad(SCR_ManualCameraComponentSave data)
168  {
169  if (data.m_aValues && !data.m_aValues.IsEmpty())
170  SetLight(data.m_aValues[0] != 0, true);
171  }
172 
173  //------------------------------------------------------------------------------------------------
174  override void EOnCameraFrame(SCR_ManualCameraParam param)
175  {
176  //~ If there is no light do check the distance from the camera to ground
177  if (!m_bIsLightOn || !m_CameraLight)
178  return;
179 
180  //~ Update camera light intensity depending on distance to ground
181  CameraLightIntensityUpdate(param.transform);
182 
183  //~ Check if the light needs to be moved and move it
184  if (m_bIsUsingKeyboardAndMouse)
185  PointingLightTransformUpdateKeyboard(param);
186  else
187  PointingLightTransformUpdateGamepad(param);
188  }
189 
190  //------------------------------------------------------------------------------------------------
191  //~ Updates the camera light intensity depending on how far the camera is from the ground
192  protected void CameraLightIntensityUpdate(vector cameraTransform[4])
193  {
194  //~ Get light intensity using distance from ground and max distance intensity and using that value as alpha in the m_cCameraLightIntensityCurve
195  float lightIntensity = Math.Lerp(m_fCameraLightIntesityMin, m_fCameraLightIntesityMax, Math3D.Curve(ECurveType.CurveProperty2D, Math.Clamp(SCR_TerrainHelper.GetHeightAboveTerrain(cameraTransform[3], m_World, true) / m_fCameraLightIntensityMaxHeight, 0, 1), m_cCameraLightIntensityCurve)[1]);
196  m_CameraLight.SetColor(m_cCameraLightColor, Math.Clamp(lightIntensity, m_fLightMinLV, m_fLightMaxLV));
197  }
198 
199  //------------------------------------------------------------------------------------------------
200  //~ Keyboard function to give LightTransformUpdate the correct values
201  protected void PointingLightTransformUpdateKeyboard(SCR_ManualCameraParam param)
202  {
203  PointingLightTransformUpdate(param, GetCursorWorldPosition(), m_fCameraHeightBeforeShowPointing_keyboard, m_fShowPointingLightDistance_keyboard);
204  }
205 
206  //------------------------------------------------------------------------------------------------
207  //~ Gamepad function to give LightTransformUpdate the correct values
208  protected void PointingLightTransformUpdateGamepad(SCR_ManualCameraParam param)
209  {
210  PointingLightTransformUpdate(param, GetCameraCenterRayCastPosition(), m_fCameraHeightBeforeShowPointing_gamepad, m_fShowPointingLightDistance_gamepad);
211  }
212 
213  //------------------------------------------------------------------------------------------------
214  //~ Checks if pointing light needs to be spawned and set it to pointing position
215  protected void PointingLightTransformUpdate(SCR_ManualCameraParam param, vector pointingPosition, float cameraHeightBeforeDeatach, float lightDetachDistanceSq)
216  {
217  //~ Get Camera Transform
218  vector cameraTransform[4];
219  GetCameraEntity().GetWorldTransform(cameraTransform);
220 
221  bool showPointingLight = false;
222  float distanceSq;
223 
224  //~ Raycast distance greater than LIGHT_TRACE_DISTANCE so keep light on camera
225  if (pointingPosition != vector.Zero)
226  {
227  //~ Get distance between camera and pointing position
228  distanceSq = vector.DistanceSq(cameraTransform[3], pointingPosition);
229 
230  //~ Check if the distance is greater then the light detach distance
231  if (distanceSq >= lightDetachDistanceSq)
232  {
233  //~ Check Camera is higher then start detach hight
234  float cameraHeightAboveTerrain = SCR_TerrainHelper.GetHeightAboveTerrain(cameraTransform[3], m_World, true);
235  if (cameraHeightAboveTerrain >= cameraHeightBeforeDeatach)
236  showPointingLight = true;
237  }
238  }
239 
240  //~ Check if should dettach camera
241  if (showPointingLight)
242  {
243  //~ Spawn a pointing light if there is none
244  if (!m_PointingLight)
245  m_PointingLight = LightEntity.Cast(GetGame().SpawnEntityPrefab(Resource.Load(m_LightPrefab)));
246 
247  vector lightTransform[4] = cameraTransform;
248  lightTransform[3] = Vector(pointingPosition[0], pointingPosition[1] + m_fPointingLightHeight, pointingPosition[2]);
249 
250  //~ Override rotation Y
251  if (m_bPointingLightRotationOverride)
252  {
253  //~ Todo: This should use look at rotation (Camera to cursor position) so it looks like you are shining from the camera
254  vector angles = Math3D.MatrixToAngles(cameraTransform);
255  angles[1] = m_fPointingLightRotationOverrideY;
256 
257  Math3D.AnglesToMatrix(angles, lightTransform);
258  }
259 
260  //~ Set Light position
261  m_PointingLight.SetWorldTransform(lightTransform);
262 
263  //~ Set light intensity depending on distance
264  float lightIntensity = Math.Lerp(m_fPointingLightIntesityMin, m_fPointingLightIntesityMax, Math3D.Curve(ECurveType.CurveProperty2D, Math.Clamp((distanceSq - lightDetachDistanceSq) / (m_fPointingLightIntensityMaxDistance - lightDetachDistanceSq), 0, 1), m_cPointingLightIntensityCurve)[1]);
265  m_PointingLight.SetColor(m_cPointingLightColor, Math.Clamp(lightIntensity, m_fLightMinLV, m_fLightMaxLV));
266  }
267  //~ Delete the light if there is any
268  else if (m_PointingLight)
269  {
270  delete m_PointingLight;
271  }
272  }
273 
274  //------------------------------------------------------------------------------------------------
275  //~ Get world cursor position. Though returns Camera center raycast if hovering over UI or if the raycast is too far
276  protected vector GetCursorWorldPosition()
277  {
278  vector cursorWorldPos;
279 
280  int mouseX, mouseY;
281  WidgetManager.GetMousePos(mouseX, mouseY);
282 
283  vector outDir;
284  vector startPos = m_WorkSpace.ProjScreenToWorld(m_WorkSpace.DPIUnscale(mouseX), m_WorkSpace.DPIUnscale(mouseY + LIGHT_MOUSE_Y_OFFSET), outDir, m_World, -1);
285  outDir *= LIGHT_TRACE_DISTANCE;
286 
287  autoptr TraceParam trace = new TraceParam();
288  trace.Start = startPos;
289  trace.End = startPos + outDir;
290  trace.Flags = TraceFlags.WORLD;
291  trace.LayerMask = TRACE_LAYER_CAMERA;
292 
293  //~ If under the Ocean also hit the water
294  if (startPos[1] > m_World.GetOceanBaseHeight())
295  trace.Flags = trace.Flags | TraceFlags.OCEAN;
296 
297  float rayDistance = m_World.TraceMove(trace, null);
298 
299  //~ Max trace reached so make sure light hidden
300  if (rayDistance >= 1)
301  cursorWorldPos = Vector(0, - 1000, 0);
302 
303  cursorWorldPos = startPos + outDir * rayDistance;
304  return cursorWorldPos;
305  }
306 
307  //------------------------------------------------------------------------------------------------
308  //~ Get camera raycast position
309  protected vector GetCameraCenterRayCastPosition()
310  {
311  //~ Get Camera Transform
312  vector transform[4];
313  GetCameraEntity().GetWorldCameraTransform(transform);
314 
315  //~ Get Starting position and rightVector of camera
316  vector startPos = transform[3];
317  vector rightVector = {transform[2][0], transform[2][1], transform[2][2]};
318 
319  //~ Set trace params
320  autoptr TraceParam trace = new TraceParam();
321  trace.Start = startPos;
322  trace.End = startPos + rightVector * LIGHT_TRACE_DISTANCE;
323  trace.Flags = TraceFlags.WORLD;
324  trace.LayerMask = TRACE_LAYER_CAMERA;
325 
326  //~ Set trace to ocean as well
327  if (startPos[1] > m_World.GetOceanBaseHeight())
328  trace.Flags = trace.Flags | TraceFlags.OCEAN;
329 
330  //~ Get hitDist (value between 0 and 1)
331  float rayDistance = m_World.TraceMove(trace, null);
332 
333  //~ Trace hit nothing or was super far so set light to hidden
334  if (rayDistance >= 1)
335  return Vector(0, - 1000, 0);
336 
337  //~ Get hit position
338  vector hitPos = startPos + rightVector * (rayDistance * LIGHT_TRACE_DISTANCE);
339 
340  return hitPos;
341  }
342 
343  //------------------------------------------------------------------------------------------------
344  override bool EOnCameraInit()
345  {
346  m_World = GetGame().GetWorld();
347 
348  if (!m_World)
349  Print("SCR_LightManualCameraComponent could not find World!", LogLevel.WARNING);
350 
351  m_WorkSpace = GetGame().GetWorkspace();
352  if (!m_WorkSpace)
353  Print("SCR_LightManualCameraComponent could not find Workspace!", LogLevel.WARNING);
354 
355  m_fShowPointingLightDistance_keyboard = Math.Pow(m_fShowPointingLightDistance_keyboard, 2);
356  m_fShowPointingLightDistance_gamepad = Math.Pow(m_fShowPointingLightDistance_gamepad, 2);
357  m_fPointingLightIntensityMaxDistance = Math.Pow(m_fPointingLightIntensityMaxDistance, 2);
358 
359  GetGame().OnInputDeviceIsGamepadInvoker().Insert(OnInputDeviceIsGamepad);
360 
361  if (m_LightPrefab.IsEmpty())
362  {
363  Print("SCR_LightManualCameraComponent: Cannot initialize, m_LightPrefab not defined!", LogLevel.WARNING);
364  return false;
365  }
366 
367  InputManager inputManager = GetInputManager();
368  if (!inputManager)
369  return false;
370 
371  inputManager.AddActionListener("ManualCameraLight", EActionTrigger.DOWN, ToggleLight);
372 
373  return true;
374  }
375 
376  //------------------------------------------------------------------------------------------------
377  override void EOnCameraExit()
378  {
379  if (m_CameraLight)
380  delete m_CameraLight;
381 
382  if (m_PointingLight)
383  delete m_PointingLight;
384 
385  if (m_World && m_WorkSpace)
386  GetGame().OnInputDeviceIsGamepadInvoker().Remove(OnInputDeviceIsGamepad);
387 
388  InputManager inputManager = GetInputManager();
389  if (!inputManager)
390  return;
391 
392  inputManager.RemoveActionListener("ManualCameraLight", EActionTrigger.DOWN, ToggleLight);
393  }
394 }
SCR_TerrainHelper
Definition: SCR_TerrainHelper.c:1
SCR_LightManualCameraComponent
Create a light on camera position.
Definition: SCR_LightManualCameraComponent.c:5
SCR_BaseManualCameraComponent
Parent class from which all SCR_ManualCamera components inherit.
Definition: SCR_BaseManualCameraComponent.c:5
SCR_UISoundEntity
Definition: SCR_UISoundEntity.c:7
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
Attribute
typedef Attribute
Post-process effect of scripted camera.
IsEnabled
int IsEnabled()
Definition: SCR_BaseManualCameraComponent.c:99
TRACE_LAYER_CAMERA
const int TRACE_LAYER_CAMERA
Definition: Constants.c:14
m_World
protected BaseWorld m_World
Definition: SCR_PreviewEntityEditorUIComponent.c:46
SCR_ManualCameraComponentSave
Definition: SCR_ManualCameraSave.c:15
GetCameraEntity
protected SCR_ManualCamera GetCameraEntity()
Definition: SCR_BaseManualCameraComponent.c:59
SCR_ManualCameraParam
Parameter for carrying information between individual camera components.
Definition: SCR_ManualCameraParam.c:5
GetInputManager
protected InputManager GetInputManager()
Definition: SCR_BaseManualCameraComponent.c:65
data
Get all prefabs that have the spawner data
Definition: SCR_EntityCatalogManagerComponent.c:305
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
BaseContainerProps
SCR_AIGoalReaction_Follow BaseContainerProps
Handles insects that are supposed to be spawned around selected prefabs defined in prefab names array...
Definition: SCR_AIGoalReaction.c:468