8 protected ResourceName m_LightPrefab;
11 protected float m_fLongitudinalOffset;
14 protected string m_sSoundEvent;
16 [
Attribute(defvalue:
"255,255,255,0",
desc:
"Color of Camera attached light")]
17 protected ref Color m_cCameraLightColor;
19 [
Attribute(defvalue:
"255,255,255,0",
desc:
"Color of pointing light")]
20 protected ref Color m_cPointingLightColor;
23 protected ref Curve m_cCameraLightIntensityCurve;
26 protected ref Curve m_cPointingLightIntensityCurve;
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;
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;
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;
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;
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;
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;
46 [
Attribute(
"-75",
desc:
"Will set pointing light rotation Y to this value if m_bPointingLightRotationOverride is true")]
47 protected float m_fPointingLightRotationOverrideY;
49 [
Attribute(
"100",
desc:
"Distance from ground when Camera light is at max intensity",
params:
"0 99999")]
50 protected float m_fCameraLightIntensityMaxHeight;
52 [
Attribute(
"200",
desc:
"Pointing light will be max light intensity fi this distance from light or higher")]
53 protected float m_fPointingLightIntensityMaxDistance;
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;
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;
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;
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;
69 protected bool m_bIsUsingKeyboardAndMouse =
true;
72 protected float m_fLightMaxLV = 21;
73 protected float m_fLightMinLV = -8;
75 protected LightEntity m_CameraLight;
76 protected LightEntity m_PointingLight;
77 protected BaseWorld m_World;
78 protected WorkspaceWidget m_WorkSpace;
80 protected bool m_bIsLightOn;
81 protected ref ScriptInvoker Event_OnLightChanged =
new ScriptInvoker();
83 protected bool m_bLightAtCameraPosition =
true;
84 private const float LIGHT_TRACE_DISTANCE = 1500;
85 private const float LIGHT_MOUSE_Y_OFFSET = 20;
94 SetLight(m_CameraLight ==
null);
101 void SetLight(
bool enable,
bool noSound =
false)
104 if (enable == (m_CameraLight !=
null))
107 m_bIsLightOn = enable;
108 Event_OnLightChanged.Invoke(enable);
112 m_CameraLight = LightEntity.Cast(
GetGame().SpawnEntityPrefab(Resource.Load(m_LightPrefab)));
116 vector lightTrasform[4];
117 Math3D.MatrixIdentity4(lightTrasform);
118 lightTrasform[3] = Vector(0, 0, m_fLongitudinalOffset);
119 m_CameraLight.SetLocalTransform(lightTrasform);
121 vector cameraTransform[4];
123 CameraLightIntensityUpdate(cameraTransform);
127 delete m_CameraLight;
130 delete m_PointingLight;
133 if (!noSound && !m_sSoundEvent.IsEmpty())
139 protected void OnInputDeviceIsGamepad(
bool isGamepad)
141 m_bIsUsingKeyboardAndMouse = !isGamepad;
154 ScriptInvoker GetOnLightChanged()
156 return Event_OnLightChanged;
163 data.m_aValues = {m_bIsLightOn};
169 if (
data.m_aValues && !
data.m_aValues.IsEmpty())
170 SetLight(
data.m_aValues[0] != 0,
true);
177 if (!m_bIsLightOn || !m_CameraLight)
181 CameraLightIntensityUpdate(param.transform);
184 if (m_bIsUsingKeyboardAndMouse)
185 PointingLightTransformUpdateKeyboard(param);
187 PointingLightTransformUpdateGamepad(param);
192 protected void CameraLightIntensityUpdate(vector cameraTransform[4])
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));
203 PointingLightTransformUpdate(param, GetCursorWorldPosition(), m_fCameraHeightBeforeShowPointing_keyboard, m_fShowPointingLightDistance_keyboard);
210 PointingLightTransformUpdate(param, GetCameraCenterRayCastPosition(), m_fCameraHeightBeforeShowPointing_gamepad, m_fShowPointingLightDistance_gamepad);
215 protected void PointingLightTransformUpdate(
SCR_ManualCameraParam param, vector pointingPosition,
float cameraHeightBeforeDeatach,
float lightDetachDistanceSq)
218 vector cameraTransform[4];
221 bool showPointingLight =
false;
225 if (pointingPosition != vector.Zero)
228 distanceSq = vector.DistanceSq(cameraTransform[3], pointingPosition);
231 if (distanceSq >= lightDetachDistanceSq)
235 if (cameraHeightAboveTerrain >= cameraHeightBeforeDeatach)
236 showPointingLight =
true;
241 if (showPointingLight)
244 if (!m_PointingLight)
245 m_PointingLight = LightEntity.Cast(
GetGame().SpawnEntityPrefab(Resource.Load(m_LightPrefab)));
247 vector lightTransform[4] = cameraTransform;
248 lightTransform[3] = Vector(pointingPosition[0], pointingPosition[1] + m_fPointingLightHeight, pointingPosition[2]);
251 if (m_bPointingLightRotationOverride)
254 vector angles = Math3D.MatrixToAngles(cameraTransform);
255 angles[1] = m_fPointingLightRotationOverrideY;
257 Math3D.AnglesToMatrix(angles, lightTransform);
261 m_PointingLight.SetWorldTransform(lightTransform);
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));
268 else if (m_PointingLight)
270 delete m_PointingLight;
276 protected vector GetCursorWorldPosition()
278 vector cursorWorldPos;
281 WidgetManager.GetMousePos(mouseX, mouseY);
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;
287 autoptr TraceParam trace =
new TraceParam();
288 trace.Start = startPos;
289 trace.End = startPos + outDir;
290 trace.Flags = TraceFlags.WORLD;
294 if (startPos[1] >
m_World.GetOceanBaseHeight())
295 trace.Flags = trace.Flags | TraceFlags.OCEAN;
297 float rayDistance =
m_World.TraceMove(trace,
null);
300 if (rayDistance >= 1)
301 cursorWorldPos = Vector(0, - 1000, 0);
303 cursorWorldPos = startPos + outDir * rayDistance;
304 return cursorWorldPos;
309 protected vector GetCameraCenterRayCastPosition()
316 vector startPos = transform[3];
317 vector rightVector = {transform[2][0], transform[2][1], transform[2][2]};
320 autoptr TraceParam trace =
new TraceParam();
321 trace.Start = startPos;
322 trace.End = startPos + rightVector * LIGHT_TRACE_DISTANCE;
323 trace.Flags = TraceFlags.WORLD;
327 if (startPos[1] >
m_World.GetOceanBaseHeight())
328 trace.Flags = trace.Flags | TraceFlags.OCEAN;
331 float rayDistance =
m_World.TraceMove(trace,
null);
334 if (rayDistance >= 1)
335 return Vector(0, - 1000, 0);
338 vector hitPos = startPos + rightVector * (rayDistance * LIGHT_TRACE_DISTANCE);
344 override bool EOnCameraInit()
349 Print(
"SCR_LightManualCameraComponent could not find World!", LogLevel.WARNING);
351 m_WorkSpace =
GetGame().GetWorkspace();
353 Print(
"SCR_LightManualCameraComponent could not find Workspace!", LogLevel.WARNING);
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);
359 GetGame().OnInputDeviceIsGamepadInvoker().Insert(OnInputDeviceIsGamepad);
361 if (m_LightPrefab.IsEmpty())
363 Print(
"SCR_LightManualCameraComponent: Cannot initialize, m_LightPrefab not defined!", LogLevel.WARNING);
371 inputManager.AddActionListener(
"ManualCameraLight", EActionTrigger.DOWN, ToggleLight);
377 override void EOnCameraExit()
380 delete m_CameraLight;
383 delete m_PointingLight;
386 GetGame().OnInputDeviceIsGamepadInvoker().Remove(OnInputDeviceIsGamepad);
392 inputManager.RemoveActionListener(
"ManualCameraLight", EActionTrigger.DOWN, ToggleLight);