Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_PowerLineJointEntity.c
Go to the documentation of this file.
1[EntityEditorProps(category: "GameScripted/Power", description: "2019 Cable prototype through debug lines")]
2class SCR_PowerLineJointEntityClass : GenericEntityClass
3{
4}
5
6class SCR_PowerLineJointEntity : GenericEntity
7{
8 [Attribute(defvalue: "1", uiwidget: UIWidgets.Slider, params: "0 30")]
9 protected float m_fSagInMeters;
10
11 [Attribute(defvalue: "0.1", uiwidget: UIWidgets.Slider, params: "-" + Math.PI + " " + Math.PI)]
12 protected float m_AngleRad;
13
14 [Attribute(defvalue: "0.5", uiwidget: UIWidgets.Slider, params: "0 10")]
15 protected float m_MovementSpeed;
16
17#ifdef WORKBENCH
18
19 protected static const int SEGMENTS = 64;
20 protected static const int POINTS = SEGMENTS + 1;
21
22 protected vector m_aDebugLine[POINTS];
23 protected vector m_aDebugLinePivots[POINTS];
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 = {};
29
30 protected float m_fTimeAccu;
31
32 //------------------------------------------------------------------------------------------------
33 bool GetJoint()
34 {
35 WorldEditorAPI api = _WB_GetEditorAPI();
36 IEntitySource entSrc = api.EntityToSource(this);
37 int childCount = entSrc.GetNumChildren();
38
39 if (childCount > 0)
40 {
41 m_vConnectedJointPos = api.SourceToEntity(entSrc.GetChild(childCount - 1)).GetOrigin();
42 //Print(m_vConnectedJointPos);
43 return true;
44 }
45 else
46 {
47 //IEntitySource parent = entSrc.GetParent();
48 //SCR_PowerLineJointEntity parentEnt = SCR_PowerLineJointEntity.Cast(api.SourceToEntity(parent));
49 //parentEnt.OnChildMoved();
50 return false;
51 }
52 }
53
54 //------------------------------------------------------------------------------------------------
55 void OnChildMoved()
56 {
57 //DrawDebug();
58 }
59
60 //------------------------------------------------------------------------------------------------
61 void GenerateCurve()
62 {
63 m_aCurve.Clear();
64 m_aCurvePivots.Clear();
65 if (m_fSagInMeters <= 0)
66 m_fSagInMeters = 0.0001;
67
68 vector posThis = GetOrigin();
69 //m_vConnectedJointPos = posThis + "50 10 0";//remove
70
71 vector jointPos1, jointPos2;
72 if (posThis[1] <= m_vConnectedJointPos[1])
73 {
74 jointPos1 = posThis;
75 jointPos2 = m_vConnectedJointPos;
76 }
77 else
78 {
79 jointPos1 = m_vConnectedJointPos;
80 jointPos2 = posThis;
81 }
82
83 m_vDirectionLevelNorm = jointPos2 - jointPos1;
84 m_vDirectionLevelNorm[1] = 0;
85 m_vDirectionLevelNorm.Normalize();
86
87 float heightDifferenceM = jointPos2[1] - jointPos1[1];
88
89 vector jointPos1Adj = jointPos1;//this pos adjusted to height of the connected joint
90 jointPos1Adj[1] = jointPos2[1];
91 float distanceLevel = vector.Distance(jointPos1Adj, jointPos2);
92
93 float s1 = m_fSagInMeters / distanceLevel; // step 1
94
95 float c = (0.5 * 0.5) / s1; // step 2
96
97 float s2 = (heightDifferenceM / distanceLevel) + s1; // step 3
98
99 float x2 = Math.Sqrt(s2 * c); // step 4
100
101 float xc = 0.5 + x2; // step 5
102
103 float x1f = (0.5 / xc) * -1; // step 6
104
105 float x2f = x2 / xc; // step 6
106
107 float segmentSize = distanceLevel / SEGMENTS;
108
109 float step = 1 / SEGMENTS;
110 float value;
111
112 array<float> curveYValues = {};
113 for (int i; i < POINTS; i++)
114 {
115 //Print(i);
116 float x = Math.Lerp(x1f, x2f, value) * xc;
117 value += step;
118 //Print(value);
119 //Print(x);
120 float y = (x * x) / c;
121 //Print(y);
122 curveYValues.Insert(y);
123 }
124
125 foreach (int i, float curveY : curveYValues)
126 {
127 float y = curveY * distanceLevel;
128 y -= m_fSagInMeters;
129
130 vector pos = m_vDirectionLevelNorm * (segmentSize * i);
131 pos[1] = pos[1] + y;
132 pos = pos + jointPos1;
133 m_aCurve.Insert(pos);
134 //Print(pos);
135 }
136 }
137
138 //------------------------------------------------------------------------------------------------
139 void GetPivots()
140 {
141 vector firstPoint = m_aCurve[0];
142 vector lastPoint = m_aCurve[SEGMENTS];
143
144 for (float i; i <= POINTS; i++)
145 {
146 vector pivot = vector.Lerp(firstPoint, lastPoint, i / SEGMENTS);
147 //Print(i / POINTS);
148 m_aCurvePivots.Insert(pivot);
149 //Print(pos);
150 }
151 }
152
153 //------------------------------------------------------------------------------------------------
154 void DrawDebugShape()
155 {
156 for (int i = 0; i < POINTS; i++)
157 {
158 m_aDebugLine[i] = m_aCurve[i];
159 //Print(m_aDebugLine[i]);
160 }
161
162 //m_aShapes.Insert(Shape.CreateLines(ARGB(255, 255, 255, 0), 0, m_aDebugLine, POINTS));
163 Shape.CreateLines(ARGB(255, 5, 5, 5), ShapeFlags.ONCE, m_aDebugLine, POINTS);
164 //m_aShapes.Insert(Shape.CreateSphere(ARGB(255, 255, 0, 0), ShapeFlags.NOZBUFFER, m_vConnectedJointPos, 0.1));
165 }
166
167 //------------------------------------------------------------------------------------------------
168 void DrawDebugShapePivots()
169 {
170 for (int i = 0; i < POINTS; i++)
171 {
172 m_aDebugLinePivots[i] = m_aCurvePivots[i];
173 }
174
175 m_aShapes.Insert(Shape.CreateLines(ARGB(123, 0, 0, 0), 0, m_aDebugLinePivots, POINTS));
176 //m_aShapes.Insert(Shape.CreateSphere(ARGB(255, 255, 0, 0), ShapeFlags.NOZBUFFER, m_vConnectedJointPos, 0.1));
177 }
178
179 //------------------------------------------------------------------------------------------------
180 void ModifyShape(float timeSlice)
181 {
182 m_fTimeAccu += m_MovementSpeed * timeSlice;
183 //Print(m_fTimeAccu);
184 float val1 = Math.Sin(m_fTimeAccu) * 0.5 + 0.5;
185 float val2 = Math.Lerp(-m_AngleRad, m_AngleRad, val1);
186
187 float sin = Math.Sin(val2);
188 float cos = Math.Cos(val2);
189
190 //rotation matrix start
191 vector rotMat[4];
192 rotMat[0][0] = cos;
193 rotMat[0][1] = sin;
194// rotMat[0][2] = 0;
195
196 rotMat[1][0] = -sin;
197 rotMat[1][1] = cos;
198 rotMat[1][2] = 0;
199
200// rotMat[2][0] = 0;
201// rotMat[2][1] = 0;
202 rotMat[2][2] = 1;
203
204// rotMat[3][0] = 0;
205// rotMat[3][1] = 0;
206// rotMat[3][2] = 0;
207 //rotation matrix end
208
209 vector rightDir = m_vDirectionLevelNorm * vector.Up;
210
211 vector pointMat[4];
212 pointMat[0] = rightDir.Normalized();
213 pointMat[1] = -vector.Up;
214 pointMat[2] = m_vDirectionLevelNorm;
215 //Print(pointMat);
216 vector resultMat[4];
217 Math3D.MatrixMultiply4(pointMat, rotMat, resultMat);
218 //Print(resultMat);
219 for (int i = 0; i < POINTS; i++)
220 {
221 float length = vector.Distance(m_aCurve[i], m_aCurvePivots[i]);
222 vector v = resultMat[1] * length + m_aCurvePivots[i];
223 //Print(v);
224 m_aCurve[i] = v;
225 }
226 }
227
228 //------------------------------------------------------------------------------------------------
229 void DrawDebug(float timeSlice)
230 {
231 if (m_vConnectedJointPos != vector.Zero)
232 {
233 ModifyShape(timeSlice);
235 }
236 }
237
238 //------------------------------------------------------------------------------------------------
239 override bool _WB_OnKeyChanged(BaseContainer src, string key, BaseContainerList ownerContainers, IEntity parent)
240 {
241 if (key == "m_fSagInMeters")
242 src.Get(key, m_fSagInMeters);
243 else
244 if (key == "m_AngleRad")
245 src.Get(key, m_AngleRad);
246 else
247 if (key == "m_MovementSpeed")
248 src.Get(key, m_MovementSpeed);
249
250 if (GetJoint())
251 {
252 if (m_vConnectedJointPos != vector.Zero)
253 {
254 m_aShapes.Clear();
255 GenerateCurve();
256 GetPivots();
257 //DrawDebugShapePivots();
258 }
259 }
260
261 m_MovementSpeed = Math.RandomFloat(m_MovementSpeed * 0.9, m_MovementSpeed * 1.1);
262 m_fTimeAccu = Math.RandomFloat(0, 100);
263 return true;
264 }
265
266 //------------------------------------------------------------------------------------------------
267 override int _WB_GetAfterWorldUpdateSpecs(IEntitySource src)
268 {
269 return EEntityFrameUpdateSpecs.CALL_WHEN_ENTITY_VISIBLE;
270 }
271
272 //------------------------------------------------------------------------------------------------
273 override void _WB_AfterWorldUpdate(float timeSlice)
274 {
275 if (m_vConnectedJointPos == vector.Zero)
276 {
277 if (GetJoint())
278 {
279 if (m_vConnectedJointPos != vector.Zero)
280 {
281 m_aShapes.Clear();
282 GenerateCurve();
283 GetPivots();
284 //DrawDebugShapePivots();
285 }
286 }
287 }
288
289 DrawDebug(timeSlice);
290 }
291
292 //------------------------------------------------------------------------------------------------
293 void SCR_PowerLineJointEntity(IEntitySource src, IEntity parent)
294 {
295 m_fTimeAccu = Math.RandomFloat(0, 100);
296 m_MovementSpeed = Math.RandomFloat(m_MovementSpeed * 0.9, m_MovementSpeed * 1.1);
297 //Print(m_AngleRad);
298 }
299
300#endif // WORKBENCH
301}
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
float m_AngleRad
float m_MovementSpeed
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()
Definition Math.c:13
ShapeFlags
Definition ShapeFlags.c:13
SCR_FieldOfViewSettings Attribute
proto int ARGB(int a, int r, int g, int b)