1 [
EntityEditorProps(
category:
"GameScripted/Spectating", description:
"Spectator camera, controlled by arrows and numpad keys", color:
"0 0 255 255")]
10 protected float m_fSagInMeters;
13 protected float m_AngleRad;
16 protected float m_MovementSpeed;
19 protected static const int SEGMENTS = 64;
20 protected const int POINTS = SEGMENTS + 1;
22 protected vector m_DebugLine[POINTS];
23 protected vector m_DebugLinePivots[POINTS];
24 protected vector m_vDirectionLevelNorm;
25 protected vector m_vConnectedJointPos;
26 protected ref array<vector> m_Curve = {};
27 protected ref array<vector> m_CurvePivots = {};
28 protected ref array<ref Shape> m_aShapes = {};
30 private float m_fTimeAccu;
36 WorldEditorAPI api = _WB_GetEditorAPI();
37 IEntitySource entSrc = api.EntityToSource(
this);
38 int childCount = entSrc.GetNumChildren();
42 for (
int i = 0; i < childCount; i++)
44 IEntitySource childSrc = entSrc.GetChild(i);
45 IEntity child = api.SourceToEntity(childSrc);
46 m_vConnectedJointPos = child.GetOrigin();
53 IEntitySource parent = entSrc.GetParent();
70 m_CurvePivots.Clear();
71 if(m_fSagInMeters <= 0)
72 m_fSagInMeters = 0.0001;
76 vector jointPos1, jointPos2;
77 if(posThis[1] <= m_vConnectedJointPos[1])
80 jointPos2 = m_vConnectedJointPos;
84 jointPos1 = m_vConnectedJointPos;
88 m_vDirectionLevelNorm = jointPos2 - jointPos1;
89 m_vDirectionLevelNorm[1] = 0;
90 m_vDirectionLevelNorm.Normalize();
92 float heightDifferenceM = jointPos2[1] - jointPos1[1];
94 vector jointPos1Adj = jointPos1;
95 jointPos1Adj[1] = jointPos2[1];
96 float distanceLevel = vector.Distance(jointPos1Adj, jointPos2);
98 float s1 = m_fSagInMeters / distanceLevel;
100 float c = (0.5 * 0.5) / s1;
102 float s2 = (heightDifferenceM / distanceLevel) + s1;
104 float x2 = Math.Sqrt(s2 * c);
108 float x1f = (0.5 / xc) * -1;
112 float segmentSize = distanceLevel / SEGMENTS;
115 array<float> curveYValues = {};
117 float step = 1 / SEGMENTS;
120 for(
int i = 0; i < POINTS;i++)
123 float x = Math.Lerp(x1f, x2f, value) * xc;
129 curveYValues.Insert(y);
133 for(
int i = 0; i < POINTS; i++)
135 float curveY = curveYValues.Get(i);
136 float y = curveY * distanceLevel;
140 vector pos = m_vDirectionLevelNorm * (segmentSize * i);
142 pos = pos + jointPos1;
151 vector firstPoint = m_Curve[0];
152 vector lastPoint = m_Curve[SEGMENTS];
154 for(
int i = 0; i <= POINTS; i++)
156 vector pivot = vector.Lerp(firstPoint,lastPoint,(
float)i/SEGMENTS);
158 m_CurvePivots.Insert(pivot);
166 for(
int i = 0; i < POINTS; i++)
168 m_DebugLine[i] = m_Curve[i];
172 Shape.CreateLines(ARGB(255, 5, 5, 5), ShapeFlags.ONCE, m_DebugLine, POINTS);
177 void DrawDebugShapePivots()
179 for(
int i = 0; i < POINTS; i++)
181 m_DebugLinePivots[i] = m_CurvePivots[i];
183 m_aShapes.Insert(Shape.CreateLines(ARGB(123, 0, 0, 0), 0, m_DebugLinePivots, POINTS));
188 void ModifyShape(
float timeSlice)
190 float speed = m_MovementSpeed;
191 m_fTimeAccu += speed * timeSlice;
193 float val1 = Math.Sin(m_fTimeAccu) * 0.5 + 0.5;
194 float val2 = Math.Lerp(-m_AngleRad, m_AngleRad, val1);
196 float sin = Math.Sin(val2);
197 float cos = Math.Cos(val2);
218 vector rightDir = m_vDirectionLevelNorm *
"0 1 0";
221 pointMat[0] = rightDir.Normalized();
222 pointMat[1] =
"0 -1 0";
223 pointMat[2] = m_vDirectionLevelNorm;
226 Math3D.MatrixMultiply4(pointMat, rotMat, resultMat);
228 for(
int i = 0; i < POINTS; i++)
230 float length = vector.Distance(m_Curve[i], m_CurvePivots[i]);
231 vector v = resultMat[1] * length + m_CurvePivots[i];
240 void DrawDebug(
float timeSlice)
242 if(m_vConnectedJointPos !=
"0 0 0")
244 ModifyShape(timeSlice);
252 override bool _WB_OnKeyChanged(BaseContainer src,
string key, BaseContainerList ownerContainers, IEntity parent)
254 if (key ==
"m_fSagInMeters")
256 src.Get(key, m_fSagInMeters);
259 if (key ==
"m_AngleRad")
261 src.Get(key, m_AngleRad);
264 if (key ==
"m_MovementSpeed")
266 src.Get(key, m_MovementSpeed);
271 if(m_vConnectedJointPos !=
"0 0 0")
279 m_MovementSpeed = Math.RandomFloat(m_MovementSpeed * 0.9, m_MovementSpeed * 1.1);
280 m_fTimeAccu = Math.RandomFloat(0, 100);
285 override void _WB_AfterWorldUpdate(
float timeSlice)
287 if(m_vConnectedJointPos ==
"0 0 0")
291 if(m_vConnectedJointPos !=
"0 0 0")
301 DrawDebug(timeSlice);
309 m_fTimeAccu = Math.RandomFloat(0, 100);
310 m_MovementSpeed = Math.RandomFloat(m_MovementSpeed * 0.9, m_MovementSpeed * 1.1);