9 protected static const float INERTIA_THRESHOLD = 0.001;
12 private float m_fSpeed;
15 private float m_fInertiaStrength;
18 private float m_fMinPivotHeight;
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;
26 private bool m_bIsInertia;
27 private vector m_vAngleVelocity;
30 private float m_fPitch;
31 private vector m_vPivotOffset;
37 WorkspaceWidget workspace =
GetGame().GetWorkspace();
47 screenW = workspace.GetWidth();
48 screenH = workspace.GetHeight();
51 vector startPos = workspace.ProjScreenToWorld(workspace.DPIUnscale(screenW * 0.5), workspace.DPIUnscale(screenH * 0.5), outDir,
m_World, -1);
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;
61 float traceDis =
m_World.TraceMove(trace,
null);
65 m_vTarget = startPos + outDir * traceDis;
73 if (!param.isManualInputEnabled)
90 if (m_vTarget == vector.Zero || param.isDirtyExternal)
100 if (!param.GetCursorWorldPos(m_vTarget))
103 m_vTargetHeightATL = m_vTarget[1] -
m_World.GetSurfaceY(m_vTarget[0], m_vTarget[2]);
105 m_vDistance = vector.Distance(param.transform[3], m_vTarget);
106 m_vDirection = -param.transform[2];
109 m_vAngleVelocity = Vector
115 m_vAngleVelocity *= m_fSpeed * param.timeSlice * 100;
116 if (m_vAngleVelocity != vector.Zero)
119 param.isManualInput =
true;
122 else if (m_bIsInertia)
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;
132 m_vTarget = vector.Zero;
141 if (!m_bIsInertia && m_vAngleVelocity == vector.Zero)
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();
156 target[1] =
m_World.GetSurfaceY(target[0], target[2]) + m_vTargetHeightATL;
160 Shape.CreateSphere(ARGBF(10, 0, 1, 1), ShapeFlags.ONCE,
CoordFromCamera(target), 0.6);
164 pos = target + m_vDirection * m_vDistance;
166 if (posWorld[1] <
m_World.GetSurfaceY(posWorld[0], posWorld[2]))
169 TraceParam trace =
new TraceParam();
171 trace.End =
CoordFromCamera(target + m_vDirection * m_vDistance - m_vPivotOffset);
172 trace.Flags = TraceFlags.WORLD;
175 pos = target + m_vDirection * m_vDistance *
m_World.TraceMove(trace,
null);
180 pos = m_vTarget + m_vDirection * m_vDistance;
183 param.transform[2] = -m_vDirection;
184 param.transform[3] = pos;
185 param.rotDelta = vector.Zero;
186 param.isDirty =
true;
189 Shape.CreateSphere(ARGBF(1, 1, 0, 1), ShapeFlags.ONCE,
CoordFromCamera(m_vTarget), 0.5);
194 override bool EOnCameraInit()
197 m_vPivotOffset = Vector(0, m_fMinPivotHeight, 0);
202 override void EOnCameraParentChange(
bool attached, IEntity parent)
205 m_vTarget = parent.CoordToLocal(m_vTarget);
207 m_vTarget = parent.CoordToParent(m_vTarget);