Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_OrbitingManualCameraComponent.c
Go to the documentation of this file.
1 //#define DEBUG_ORBIT
2 
4 
6 [BaseContainerProps(), SCR_BaseManualCameraComponentTitle()]
8 {
9  protected static const float INERTIA_THRESHOLD = 0.001;
10 
11  [Attribute("0.01", UIWidgets.Auto, "")]
12  private float m_fSpeed;
13 
14  [Attribute(defvalue: "0.042")]
15  private float m_fInertiaStrength;
16 
17  [Attribute(defvalue: "0.5")]
18  private float m_fMinPivotHeight;
19 
20  private BaseWorld m_World;
21  private vector m_vTarget;
22  private float m_vTargetHeightATL;
23  private float m_vDistance;
24  private vector m_vDirection;
25 
26  private bool m_bIsInertia;
27  private vector m_vAngleVelocity;
28 
29  private float m_fYaw;
30  private float m_fPitch;
31  private vector m_vPivotOffset;
32 
33  //------------------------------------------------------------------------------------------------
35  bool GetCenterPos()
36  {
37  WorkspaceWidget workspace = GetGame().GetWorkspace();
38  if (!workspace)
39  return false;
40 
41  m_World = GetGame().GetWorld();
42  if (!m_World)
43  return false;
44 
45  int screenW;
46  int screenH;
47  screenW = workspace.GetWidth();
48  screenH = workspace.GetHeight();
49 
50  vector outDir;
51  vector startPos = workspace.ProjScreenToWorld(workspace.DPIUnscale(screenW * 0.5), workspace.DPIUnscale(screenH * 0.5), outDir, m_World, -1);
52  outDir *= 10000;
53 
54  // Set initial position by tracing from the camera
55  TraceParam trace = new TraceParam();
56  trace.Start = startPos - m_vPivotOffset;
57  trace.End = startPos + outDir - m_vPivotOffset;
58  trace.Flags = TraceFlags.WORLD | TraceFlags.ENTS;
59  trace.LayerMask = TRACE_LAYER_CAMERA;
60 
61  float traceDis = m_World.TraceMove(trace, null);
62  if (traceDis == 1)
63  return false;
64 
65  m_vTarget = startPos + outDir * traceDis;
66  //m_vTarget[1] = Math.Max(m_vTarget[1], 0); // Dissalow moving below sea level
67  return true;
68  }
69 
70  //------------------------------------------------------------------------------------------------
71  override void EOnCameraFrame(SCR_ManualCameraParam param)
72  {
73  if (!param.isManualInputEnabled)
74  return;
75 
76  //--- ToDo: Better flag handling in his component
77  if (
78  (param.flag & EManualCameraFlag.ROTATE)
79  &&
80  (
81  GetInputManager().GetActionValue("ManualCameraModifier")
82  //--- On gamepad, these editor actions block the orbit action because they use it as a modifer (e.g, lshoulder + lstick horizontal)
83  //--- ToDo: Cleaner?
84  || GetInputManager().GetActionValue("EditorTransformRotateYaw")
85  || GetInputManager().GetActionValue("EditorTransformMoveVertical")
86  )
87  )
88  {
89  //--- Input movement
90  if (m_vTarget == vector.Zero || param.isDirtyExternal)// || param.isManualInput)
91  {
92  //--- Update orbit target (on orbiting start or upon input from other components)
93  if (GetInputManager().IsUsingMouseAndKeyboard())
94  {
95  if (!GetCenterPos())
96  return;
97  }
98  else
99  {
100  if (!param.GetCursorWorldPos(m_vTarget))
101  return;
102  }
103  m_vTargetHeightATL = m_vTarget[1] - m_World.GetSurfaceY(m_vTarget[0], m_vTarget[2]);
104  m_vTarget = CoordToCamera(m_vTarget);
105  m_vDistance = vector.Distance(param.transform[3], m_vTarget);
106  m_vDirection = -param.transform[2];
107  }
108 
109  m_vAngleVelocity = Vector
110  (
111  GetInputManager().GetActionValue("ManualCameraRotateYaw"),
112  -GetInputManager().GetActionValue("ManualCameraRotatePitch"),
113  0
114  );
115  m_vAngleVelocity *= m_fSpeed * param.timeSlice * 100; //--- ToDo: Remove hardcoded coef after new camera is enabled
116  if (m_vAngleVelocity != vector.Zero)
117  {
118  m_bIsInertia = true;
119  param.isManualInput = true;
120  }
121  }
122  else if (m_bIsInertia)
123  {
124  //--- Inertia movement
125  m_vAngleVelocity = vector.Lerp(m_vAngleVelocity, vector.Zero, Math.Min(param.timeSlice / m_fInertiaStrength, 1));
126  if (m_vAngleVelocity.Length() < INERTIA_THRESHOLD)
127  m_bIsInertia = false;
128  }
129  else
130  {
131  //--- No movement, terminate
132  m_vTarget = vector.Zero;
133  return;
134  }
135 
136  //--- Mark camera as orbiting, not moving
137  param.flag = param.flag | EManualCameraFlag.ORBIT;
138  param.flag = param.flag &~ EManualCameraFlag.MOVE;
139 
140  //--- No change, terminate
141  if (!m_bIsInertia && m_vAngleVelocity == vector.Zero)
142  return;
143 
144  //--- Add rotation
145  vector angles = m_vDirection.VectorToAngles().MapAngles();
146  vector anglesModified = angles + m_vAngleVelocity;
147  anglesModified[1] = Math.Clamp(anglesModified[1], -89, 89);
148  m_vDirection = anglesModified.AnglesToVector();
149 
150  //--- Don't go below terrain level
151  vector pos;
152  if (param.flag & EManualCameraFlag.ABOVE_TERRAIN)
153  {
154  //--- Set target height
155  vector target = CoordFromCamera(m_vTarget);
156  target[1] = m_World.GetSurfaceY(target[0], target[2]) + m_vTargetHeightATL;
157  target = CoordToCamera(target);
158 
159 #ifdef DEBUG_ORBIT
160  Shape.CreateSphere(ARGBF(10, 0, 1, 1), ShapeFlags.ONCE, CoordFromCamera(target), 0.6);
161 #endif
162 
163  //--- Adjust only if camera position is expected to end up below terrain
164  pos = target + m_vDirection * m_vDistance;
165  vector posWorld = CoordFromCamera(pos - m_vPivotOffset);
166  if (posWorld[1] < m_World.GetSurfaceY(posWorld[0], posWorld[2]))
167  {
168  //--- Move camera to terrain intersection leading from target to expected camera position
169  TraceParam trace = new TraceParam();
170  trace.Start = CoordFromCamera(target);
171  trace.End = CoordFromCamera(target + m_vDirection * m_vDistance - m_vPivotOffset);
172  trace.Flags = TraceFlags.WORLD;
173  trace.LayerMask = TRACE_LAYER_CAMERA;
174 
175  pos = target + m_vDirection * m_vDistance * m_World.TraceMove(trace, null);
176  }
177  }
178  else
179  {
180  pos = m_vTarget + m_vDirection * m_vDistance;
181  }
182  //--- Apply
183  param.transform[2] = -m_vDirection;
184  param.transform[3] = pos;
185  param.rotDelta = vector.Zero;
186  param.isDirty = true;
187 
188 #ifdef DEBUG_ORBIT
189  Shape.CreateSphere(ARGBF(1, 1, 0, 1), ShapeFlags.ONCE, CoordFromCamera(m_vTarget), 0.5);
190 #endif
191  }
192 
193  //------------------------------------------------------------------------------------------------
194  override bool EOnCameraInit()
195  {
196  m_World = GetCameraEntity().GetWorld();
197  m_vPivotOffset = Vector(0, m_fMinPivotHeight, 0);
198  return true;
199  }
200 
201  //------------------------------------------------------------------------------------------------
202  override void EOnCameraParentChange(bool attached, IEntity parent)
203  {
204  if (attached)
205  m_vTarget = parent.CoordToLocal(m_vTarget);
206  else
207  m_vTarget = parent.CoordToParent(m_vTarget);
208  }
209 }
CoordFromCamera
protected vector CoordFromCamera(vector pos)
Definition: SCR_BaseManualCameraComponent.c:80
m_fInertiaStrength
private float m_fInertiaStrength
Definition: SCR_TooltipManagerEditorUIComponent.c:14
SCR_BaseManualCameraComponent
Parent class from which all SCR_ManualCamera components inherit.
Definition: SCR_BaseManualCameraComponent.c:5
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
CoordToCamera
protected vector CoordToCamera(vector pos)
Definition: SCR_BaseManualCameraComponent.c:71
EManualCameraFlag
EManualCameraFlag
Definition: EManualCameraFlag.c:7
Attribute
typedef Attribute
Post-process effect of scripted camera.
TRACE_LAYER_CAMERA
const int TRACE_LAYER_CAMERA
Definition: Constants.c:14
m_World
protected BaseWorld m_World
Definition: SCR_PreviewEntityEditorUIComponent.c:46
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
SCR_OrbitingManualCameraComponent
Camera orbitting around a target.
Definition: SCR_OrbitingManualCameraComponent.c:7
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