9 protected float m_fSagInMeters;
19 protected static const int SEGMENTS = 64;
20 protected static const int POINTS = SEGMENTS + 1;
24 protected vector m_vDirectionLevelNorm;
25 protected vector m_vConnectedJointPos;
26 protected ref array<vector> m_aCurve = {};
27 protected ref array<vector> m_aCurvePivots = {};
28 protected ref array<ref Shape>
m_aShapes = {};
30 protected float m_fTimeAccu;
36 IEntitySource entSrc = api.EntityToSource(
this);
37 int childCount = entSrc.GetNumChildren();
41 m_vConnectedJointPos = api.SourceToEntity(entSrc.GetChild(childCount - 1)).
GetOrigin();
64 m_aCurvePivots.Clear();
65 if (m_fSagInMeters <= 0)
66 m_fSagInMeters = 0.0001;
71 vector jointPos1, jointPos2;
72 if (posThis[1] <= m_vConnectedJointPos[1])
75 jointPos2 = m_vConnectedJointPos;
79 jointPos1 = m_vConnectedJointPos;
83 m_vDirectionLevelNorm = jointPos2 - jointPos1;
84 m_vDirectionLevelNorm[1] = 0;
85 m_vDirectionLevelNorm.Normalize();
87 float heightDifferenceM = jointPos2[1] - jointPos1[1];
89 vector jointPos1Adj = jointPos1;
90 jointPos1Adj[1] = jointPos2[1];
91 float distanceLevel = vector.Distance(jointPos1Adj, jointPos2);
93 float s1 = m_fSagInMeters / distanceLevel;
95 float c = (0.5 * 0.5) / s1;
97 float s2 = (heightDifferenceM / distanceLevel) + s1;
99 float x2 = Math.Sqrt(s2 * c);
103 float x1f = (0.5 / xc) * -1;
107 float segmentSize = distanceLevel / SEGMENTS;
109 float step = 1 / SEGMENTS;
112 array<float> curveYValues = {};
113 for (
int i; i <
POINTS; i++)
116 float x = Math.Lerp(x1f, x2f, value) * xc;
120 float y = (x * x) / c;
122 curveYValues.Insert(y);
125 foreach (
int i,
float curveY : curveYValues)
127 float y = curveY * distanceLevel;
130 vector pos = m_vDirectionLevelNorm * (segmentSize * i);
132 pos = pos + jointPos1;
133 m_aCurve.Insert(pos);
141 vector firstPoint = m_aCurve[0];
142 vector lastPoint = m_aCurve[SEGMENTS];
144 for (
float i; i <=
POINTS; i++)
146 vector pivot = vector.Lerp(firstPoint, lastPoint, i / SEGMENTS);
148 m_aCurvePivots.Insert(pivot);
156 for (
int i = 0; i <
POINTS; i++)
158 m_aDebugLine[i] = m_aCurve[i];
168 void DrawDebugShapePivots()
170 for (
int i = 0; i <
POINTS; i++)
172 m_aDebugLinePivots[i] = m_aCurvePivots[i];
180 void ModifyShape(
float timeSlice)
184 float val1 = Math.Sin(m_fTimeAccu) * 0.5 + 0.5;
187 float sin = Math.Sin(val2);
188 float cos = Math.Cos(val2);
209 vector rightDir = m_vDirectionLevelNorm * vector.Up;
212 pointMat[0] = rightDir.Normalized();
213 pointMat[1] = -vector.Up;
214 pointMat[2] = m_vDirectionLevelNorm;
217 Math3D.MatrixMultiply4(pointMat, rotMat, resultMat);
219 for (
int i = 0; i <
POINTS; i++)
221 float length = vector.Distance(m_aCurve[i], m_aCurvePivots[i]);
222 vector v = resultMat[1] * length + m_aCurvePivots[i];
231 if (m_vConnectedJointPos != vector.Zero)
233 ModifyShape(timeSlice);
239 override bool _WB_OnKeyChanged(BaseContainer src,
string key, BaseContainerList ownerContainers,
IEntity parent)
241 if (key ==
"m_fSagInMeters")
242 src.Get(key, m_fSagInMeters);
244 if (key ==
"m_AngleRad")
247 if (key ==
"m_MovementSpeed")
252 if (m_vConnectedJointPos != vector.Zero)
262 m_fTimeAccu = Math.RandomFloat(0, 100);
269 return EEntityFrameUpdateSpecs.CALL_WHEN_ENTITY_VISIBLE;
275 if (m_vConnectedJointPos == vector.Zero)
279 if (m_vConnectedJointPos != vector.Zero)
293 void SCR_PowerLineJointEntity(IEntitySource src,
IEntity parent)
295 m_fTimeAccu = Math.RandomFloat(0, 100);
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
ref array< ref Shape > m_aShapes
void DrawDebugShape(bool draw)
enum EVehicleType IEntity
event void _WB_AfterWorldUpdate(float timeSlice)
Called after updating world in Workbench. The entity must be visible in frustum, selected or named....
proto external WorldEditorAPI _WB_GetEditorAPI()
This returns world editor API, which is safe to use from editor events bellow.
event bool _WB_OnKeyChanged(BaseContainer src, string key, BaseContainerList ownerContainers, IEntity parent)
Any property value has been changed. You can use editor API here and do some additional edit actions ...
event int _WB_GetAfterWorldUpdateSpecs(IEntitySource src)
Called after _WB_OnInit or also later when editor needs to know whether _WB_AfterWorldUpdate needs to...
proto external vector GetOrigin()
SCR_FieldOfViewSettings Attribute
proto int ARGB(int a, int r, int g, int b)