Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
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("90", 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;
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}
const int TRACE_LAYER_CAMERA
Definition Constants.c:14
ArmaReforgerScripted GetGame()
Definition game.c:1398
ref array< string > angles
SCR_AIAnimation_Loitering BaseContainerProps
Commanding menu commanding element class.
void EOnCameraFrame(SCR_ManualCameraParam param)
InputManager GetInputManager()
enum EVehicleType IEntity
proto external vector CoordToParent(vector coord)
proto external vector CoordToLocal(vector coord)
Parent class from which all SCR_ManualCamera components inherit.
Parameter for carrying information between individual camera components.
float timeSlice
Frame time slice.
ShapeFlags
Definition ShapeFlags.c:13
SCR_FieldOfViewSettings Attribute
EManualCameraFlag
proto native vector Vector(float x, float y, float z)
TraceFlags
Definition TraceFlags.c:13
proto int ARGBF(float fa, float fr, float fg, float fb)
Converts <0.0, 1.0> ARGB into color.