Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_PreviewEntityEditorUIComponent.c
Go to the documentation of this file.
1//--- For gamepad only
8
10
11class SCR_PreviewEntityEditorUIComponent : SCR_BaseEditorUIComponent
12{
13 protected static const int MIN_CURSOR_DIS_TO_TRANSFORM = 10; //--- Upon clicking, how far must cursor move to initiate
14 protected static const float TRACE_DIS = 2000;
15
16 [Attribute(defvalue: "30")]
17 protected float m_fMoveVerticalCoef;
18
19 [Attribute(defvalue: "-500")]
20 protected float m_fRotationCoef;
21
22 [Attribute(defvalue: "0.05")]
23 protected float m_fRotationInertia;
24
25 [Attribute(defvalue: "0.25")]
26 protected float m_fUnsnapDuration;
27
28 [Attribute(defvalue: "45", desc: "When vertical mode is GEOMETRY, hovering over surface with at least this slope will place preview entity below the surface, not on it.\n\nCurrently disabled, entity editing will be disable beyond this angle.")]
29 protected float m_fMinAngleWall;
30
31 [Attribute(defvalue: "101", desc: "When vertical mode is GEOMETRY, hovering over surface with at least this slope will prevent showing preview entity and confirming the change.")]
32 protected float m_fMinAngleCeiling;
33
34 [Attribute(defvalue: "1", desc: "When adjusting entity height, camera will move together with the entity when above this vertical offset.\nWhen below, the camera will rotate towards the entity instead.")]
36
37 [Attribute(uiwidget: UIWidgets.ResourcePickerThumbnail, params: "et")]
39
46 protected BaseWorld m_World;
50 protected bool m_bMouseMoved;
53 protected float m_fTargetYaw;
54 protected float m_fUnsnapProgress;
59 protected bool m_bIsAnimated;
63 protected float m_fDirIndicatorScale;
65
66 //------------------------------------------------------------------------------------------------
67 protected void OnHoverChange(EEditableEntityState state, set<SCR_EditableEntityComponent> entitiesInsert, set<SCR_EditableEntityComponent> entitiesRemove)
68 {
70 return;
71
72 if (entitiesRemove && entitiesRemove.Count() == 1)
73 {
75 m_bIsAnimated = m_PreviewEntityManager.SetTarget(null);
76
77 m_Target = null;
79 }
80
81 if (entitiesInsert && entitiesInsert.Count() == 1)
82 {
83 SCR_EditableEntityComponent entity = entitiesInsert[0];
84 bool isDelegate = true;
85 if (m_HoverFilter)
86 isDelegate = m_HoverFilter.IsDelegate();
87
88 if (m_PreviewEntityManager.SetTarget(entity, isDelegate))
89 {
90 m_Target = entity;
92 }
93 }
94 }
95
96 //------------------------------------------------------------------------------------------------
97 protected void OnPreviewCreate()
98 {
99 m_PreviewEntityManager.GetPreviewTransformOrigin(m_vTransformOrigin);
100 m_vAnglesOrigin = m_vTransformOrigin[2].VectorToAngles();
101 m_bIsAnimated = false;
103
104 //--- Hotfix: OnEditorTransformRotationModifierUp is not called when not editing, this will reset it. ToDo: Remove
105 if (!m_InputManagerBase.GetActionTriggered("EditorTransformRotateYawModifier"))
107
108 //--- Activate currently hovered entity.
109 //--- For example, on client, dragging a soldier on a vehicle before server callback about transformation arrives would not recognize the hover.
110 set<SCR_EditableEntityComponent> hoverEntities = new set<SCR_EditableEntityComponent>();
111 m_HoverFilter.GetEntities(hoverEntities);
112 OnHoverChange(EEditableEntityState.HOVER, hoverEntities, null);
113 }
114
115 //------------------------------------------------------------------------------------------------
116 protected void OnPreviewDelete()
117 {
119 delete m_DirIndicator;
120 }
121
122 //------------------------------------------------------------------------------------------------
124 {
125 m_PreviewEntityManager.ResetPreviewHeight();
126 }
127
128 //------------------------------------------------------------------------------------------------
130 {
132 return;
133
135 SetClickPos(m_CursorComponentBase.GetCursorPos());
137 }
138
139 //------------------------------------------------------------------------------------------------
141 {
143 return;
144
145 //m_PreviewEntityManager.SetTarget(null); //--- Don't reset, messes up restoring pre-snap transformation
147 m_PreviewEntityManager.SetIsRotating(false);
148
149 //--- Return cursor back
151 {
152 m_CursorComponentBase.SetCursorPos(m_vClickPosBase, true);
153 m_vClickPosCancel = m_vClickPosBase;
154 }
155 }
156
157 //------------------------------------------------------------------------------------------------
159 {
160 if (!m_PreviewEntityManager.IsRotating())
161 SetClickPos(m_CursorComponentBase.GetCursorPos());
162 }
163
164 //------------------------------------------------------------------------------------------------
166 {
167 if (!m_PreviewEntityManager.IsEditing())// || !m_bIsRotatingTowardsCursor)
168 return;
169
170 //--- Return cursor back
171 if (m_CursorComponentBase && !m_PreviewEntityManager.IsRotating() && m_PreviewEntityManager.GetVerticalMode() == EEditorTransformVertical.GEOMETRY)
172 {
173 m_CursorComponentBase.SetCursorPos(m_vClickPosBase, true);
174 m_vClickPosCancel = m_vClickPosBase;
175 }
176 }
177
178 //------------------------------------------------------------------------------------------------
179 protected void SetRotationPivot()
180 {
181 vector previewTransform[4];
182 if (m_PreviewEntityManager.GetPreviewTransform(previewTransform))
183 {
184 m_vClickTransformBase = previewTransform;
185 }
186 else
187 {
188 vector worldPos;
189 if (!m_CursorComponentBase.GetCursorWorldPos(worldPos))
190 return;
191
192 m_vClickTransformBase[3] = worldPos;
193 }
194
195 m_RotationTrace = null;
196 if (m_PreviewEntityManager.GetVerticalMode() == EEditorTransformVertical.GEOMETRY)
197 {
199 m_RotationTrace.ExcludeArray = m_PreviewEntityManager.GetExcludeArray();
200 }
201
204 }
205
206 //---- REFACTOR NOTE START: Unclear hardcoded multiplier
207
208 //------------------------------------------------------------------------------------------------
209 protected void SetClickPos(vector clickPos)
210 {
211 m_vClickPosBase = clickPos;
212 m_bMouseMoved = false;
213
214 ArmaReforgerScripted game = GetGame();
215 if (!game || !m_World)
216 return;
217
218 WorkspaceWidget workspace = game.GetWorkspace();
219 if (!workspace)
220 return;
221
222 vector clickDir;
223 vector cameraPos = workspace.ProjScreenToWorld(clickPos[0], clickPos[1], clickDir, m_World, -1);
224 m_vClickPosWorldBase = cameraPos + clickDir * 10;
225 }
226
227 //---- REFACTOR NOTE END ----
228
229 //------------------------------------------------------------------------------------------------
230 protected bool HasMouseMoved()
231 {
232 if (m_bMouseMoved || !m_InputManagerBase.IsUsingMouseAndKeyboard())
233 return true;
234
235 ArmaReforgerScripted game = GetGame();
236 if (!game || !m_World)
237 return false;
238
239 WorkspaceWidget workspace = game.GetWorkspace();
240 if (!workspace)
241 return false;
242
243 //--- Check not only if cursor moved, but also if camera moved, resulting in cursor movement in the world
244 vector clickPos = workspace.ProjWorldToScreen(m_vClickPosWorldBase, m_World);
245
246 m_bMouseMoved = vector.Distance(m_CursorComponentBase.GetCursorPos(), clickPos/*m_vClickPosBase*/) > MIN_CURSOR_DIS_TO_TRANSFORM;
247 return m_bMouseMoved;
248 }
249
250 protected void GetCursorPos(out vector cameraPos, out vector cursorDir)
251 {
252 ArmaReforgerScripted game = GetGame();
253 if (!game || !m_World)
254 return;
255
256 WorkspaceWidget workspace = game.GetWorkspace();
257 if (!workspace)
258 return;
259
260 vector cursorPos = m_CursorComponentBase.GetCursorPos();
261 cameraPos = workspace.ProjScreenToWorld(cursorPos[0], cursorPos[1], cursorDir, m_World, -1);
262 }
263
264 //------------------------------------------------------------------------------------------------
265 protected float GetTraceDis(vector pos, vector dir, float cameraHeight)
266 {
267 TraceParam trace = new TraceParam();
268 trace.Start = pos;
269 trace.End = trace.Start + dir;
270 if (cameraHeight >= m_World.GetOceanBaseHeight())
271 trace.Flags = TraceFlags.WORLD | TraceFlags.OCEAN;
272 else
273 trace.Flags = TraceFlags.WORLD; //--- Don't check for water intersection when under water
274
275 trace.LayerMask = TRACE_LAYER_CAMERA;
276
277 return m_World.TraceMove(trace, null);
278 }
279
280 //------------------------------------------------------------------------------------------------
281 protected void UpdateDirIndicator(vector previewTransform[4])
282 {
284 {
285 //--- Show dir indicator
286 if (!m_DirIndicator && m_DirIndicatorPrefab && m_PreviewEntityManager.GetPreviewEntity())
287 {
288 //--- Create object
289 EntitySpawnParams spawnParams = new EntitySpawnParams();
290 spawnParams.Parent = m_PreviewEntityManager.GetPreviewEntity();
291 m_DirIndicator = GetGame().SpawnEntityPrefab(Resource.Load(m_DirIndicatorPrefab), spawnParams.Parent.GetWorld(), spawnParams);
292
293 //--- Get object size
294 vector previewBoundMin, previewBoundMax;
295 m_PreviewEntityManager.GetPreviewEntity().GetPreviewBounds(previewBoundMin, previewBoundMax);
296 float previewSize = vector.DistanceXZ(previewBoundMin, previewBoundMax);
297 float offsetSize = vector.DistanceXZ(vector.Zero, previewBoundMin + previewBoundMax);
298 float localOffsetSize = vector.DistanceXZ(vector.Zero, m_PreviewEntityManager.GetLocalOffset());
299 m_fDirIndicatorScale = (previewSize + offsetSize + localOffsetSize) * 0.5;
300 }
301
302 if (m_DirIndicator)
303 {
304 //--- Align the indicator to surface
305 vector angles = Math3D.MatrixToAngles(previewTransform);
306 angles[1] = 0; //--- Reset pitch
307 angles[2] = 0; //--- Reset roll
308
309 vector orientedTransform[4];
310 Math3D.AnglesToMatrix(angles, orientedTransform);
311
312 orientedTransform[3] = m_vRotationPivot;
313 SCR_TerrainHelper.OrientToTerrain(orientedTransform, trace: m_RotationTrace);
314
315 m_DirIndicator.SetWorldTransform(orientedTransform);
317 }
318 }
319 else if (m_DirIndicator)
320 {
321 m_RotationTrace = null;
322 delete m_DirIndicator;
323 }
324 }
325
326 //------------------------------------------------------------------------------------------------
329
331 //--- Transformation methods
333
334 //------------------------------------------------------------------------------------------------
335 protected void MoveHorizontalTowardsCursor(float tDelta, out vector transform[4], out bool canTransform, out EEditorTransformVertical verticalMode)
336 {
337 vector cameraPos, cursorDir;
338 GetCursorPos(cameraPos, cursorDir);
339 cursorDir *= TRACE_DIS;
340 vector pos = transform[3];
341
342 switch (verticalMode)
343 {
344 case EEditorTransformVertical.GEOMETRY:
345 {
346 canTransform = GetPreviewPosAboveGeometry(cameraPos, cursorDir, pos, verticalMode);
347 break;
348 }
349 case EEditorTransformVertical.TERRAIN:
350 {
351 canTransform = GetPreviewPosAboveTerrain(cameraPos, cursorDir, pos, verticalMode);
352 break;
353 }
355 {
356 canTransform = GetPreviewPosAboveSea(cameraPos, cursorDir, pos, verticalMode);
357 break;
358 }
359 }
360
361 pos[1] = Math.Max(pos[1], GetGame().GetWorld().GetSurfaceY(pos[0], pos[2]));
362 transform[3] = pos;
364 m_PreviewEntityManager.SetIsMovingVertically(false);
365 }
366
367 //------------------------------------------------------------------------------------------------
368 protected bool MoveVertical(float tDelta, out vector transform[4], float moveVertical, EEditorTransformVertical verticalMode)
369 {
370 //--- Gamepad move vertical
371 if (m_PreviewEntityManager.CanUnsnap(moveVertical))
372 {
373 m_fUnsnapProgress += tDelta;
375 return false;
376 }
377 else
378 {
380 }
381
382 //--- Apply changes
383 vector pos = transform[3];
384 transform[3][1] = pos[1] + moveVertical;// * tDelta;
385
386 //--- Snap vertically (not when unsnapped recently)
387 if (m_fUnsnapProgress == 0)
388 transform[3] = m_PreviewEntityManager.SnapVertically(transform[3]);
389
390 //-- Update height
391 m_PreviewEntityManager.SetPreviewHeight(transform[3]);
392
393 //--- Adjust camera to keep looking at preview
394 SCR_ManualCamera camera;
395 if (verticalMode != EEditorTransformVertical.GEOMETRY && m_CameraManagerBase && m_CameraManagerBase.GetCamera(camera))
396 {
397 vector cameraPos = camera.GetWorldTransformAxis(3) + transform[3] - pos;
398 pos = transform[3];
399
400 if (cameraPos[1] > pos[1] + m_fMinCameraVerticalOffset && m_PreviewEntityManager.GetPreviewHeightAboveTerrain() > 0)
401 {
402 //--- Move camera with the entity when it's above the entity and the entity is above ground
403 camera.SetOrigin(cameraPos);
404 }
405 else
406 {
407 //--- Rotate camera towards the entity in all other cases
408 vector cameraTransform[4] = {vector.Right, vector.Up, vector.Forward, camera.GetWorldTransformAxis(3)};
409 Math3D.DirectionAndUpMatrix(transform[3] - cameraTransform[3], vector.Up, cameraTransform);
410 camera.SetTransform(cameraTransform);
411 }
412
413 camera.SetDirty(true);
414 }
415
416 m_PreviewEntityManager.SetIsMovingVertically(true);
417 return true;
418 }
419
420 //------------------------------------------------------------------------------------------------
421 protected void MoveVerticalTowardsCursor(float tDelta, out vector transform[4])
422 {
423 vector cameraPos, cursorDir;
424 GetCursorPos(cameraPos, cursorDir);
425
426 float dis = vector.DistanceXZ(cameraPos, transform[3]);
427 float angle = cursorDir.VectorToAngles()[1];
428 vector tracePos = cameraPos + cursorDir * (dis / Math.Cos(angle * Math.DEG2RAD));
429 transform[3][1] = tracePos[1];
430 transform[3] = m_PreviewEntityManager.SnapVertically(transform[3]);
431 m_PreviewEntityManager.SetPreviewHeight(transform[3]);
432 m_PreviewEntityManager.SetIsMovingVertically(true);
433
434#ifdef ENABLE_DIAG
435 if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_SHOW_DEBUG))
436 {
437 string text = string.Format(" %1 m", m_PreviewEntityManager.GetPreviewHeightAboveTerrain().ToString(lenDec: 3));
438 DebugTextWorldSpace.Create(m_World, text, DebugTextFlags.ONCE | DebugTextFlags.FACE_CAMERA, transform[3][0], transform[3][1], transform[3][2], color: Color.PINK);
439 }
440#endif
441 }
442
443 //------------------------------------------------------------------------------------------------
444 protected void Rotate(float tDelta, out vector transform[4], float rotationValue)
445 {
446 vector angles = transform[2].VectorToAngles();
447 bool freeRotation = true;
449 if (target)
450 {
451 if (!RotateInSlot(target, rotationValue, angles, freeRotation))
452 return;
453 }
454
455 if (freeRotation)
456 {
458 angles[0] = angles[0] + rotationValue;// * tDelta;
459 }
460
461 vector basis[4];
462 Math3D.AnglesToMatrix(angles, basis);
463 Math3D.MatrixMultiply3(basis, m_vTransformOrigin, transform);
464 m_vRotationPivot = transform[3];
465 }
466
467 //------------------------------------------------------------------------------------------------
468 protected bool RotateInSlot(SCR_EditableEntityComponent slot, float rotationValue, out vector angles, out bool freeRotation)
469 {
470 if (m_fTargetYaw)
471 {
472 angles[0] = m_fTargetYaw;
473 return true;
474 }
475
476 SCR_SiteSlotEntity slotEntity = SCR_SiteSlotEntity.Cast(slot.GetOwner());
477 if (!slotEntity)
478 return false;
479
480 float step = slotEntity.GetRotationStep();
481 if (step == -1)
482 return false;
483
484 if (step == 0)
485 return true;
486
487 angles[0] = angles[0] + step * rotationValue.Sign();
488 m_fTargetYaw = angles[0];
489 return true;
490 }
491
492 //------------------------------------------------------------------------------------------------
493 protected void RotateTowardsCursor(float tDelta, out vector transform[4])
494 {
495 //--- Reset when camera starts moving
496 if (m_CameraManagerBase && m_CameraManagerBase.GetCamera() && m_CameraManagerBase.GetCamera().IsManualInput())
497 {
499 return;
500 }
501
502 vector pivotPos;
504 if (target)
505 {
506 //--- Attached to a target - use its center instead of relative click position
507 vector targetTransform[4];
508 target.GetTransform(targetTransform);
509 pivotPos = targetTransform[3];
510 }
511 else
512 {
513 pivotPos = m_vClickTransformBase[3];
514 pivotPos[1] = pivotPos[1] - m_PreviewEntityManager.GetLocalOffset()[1];
515 }
516
517 //--- Get intersection with terrain plane
518 vector cameraPos, cursorDir;
519 GetCursorPos(cameraPos, cursorDir);
520 vector worldPos = SCR_Math3D.IntersectPlane(cameraPos, cursorDir * TRACE_DIS, pivotPos, m_vTerrainNormal);
521 float dir = (worldPos - pivotPos).VectorToAngles()[0] - m_vAnglesOrigin[0];
522
523 vector basis[4];
524 Math3D.AnglesToMatrix(Vector(dir, 0, 0), basis);
525 Math3D.MatrixMultiply3(basis, m_vTransformOrigin, transform);
526
527 m_vRotationPivot = pivotPos;
528 m_PreviewEntityManager.SetIsRotating(true);
530
531 //--- Debug
532 //Shape.CreateSphere(Color.White.PackToInt(), ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, m_vClickTransformBase[3], 1);
533 //Shape.CreateSphere(Color.Red.PackToInt(), ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, worldPos, 1);
534 }
535
537 //--- Intersections
539
540 //------------------------------------------------------------------------------------------------
541 protected bool GetPreviewPosAboveGeometry(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
542 {
543 //--- Trace entity under cursor
544 TraceParam trace = new TraceParam();
545 trace.Start = cameraPos;
546 trace.End = trace.Start + cursorDir;
547 trace.LayerMask = EPhysicsLayerPresets.Projectile; //--- Use more detailed mask which can also detect e.g., rack shelves
548 trace.Flags = TraceFlags.ENTS | TraceFlags.WORLD;
549 if (cameraPos[1] >= m_World.GetOceanBaseHeight())
550 trace.Flags |= TraceFlags.OCEAN;
551
552 trace.ExcludeArray = m_PreviewEntityManager.GetExcludeArray();
553 float traceCursor = m_World.TraceMove(trace, null);
554
555 //--- No entity intersection, calculate by terrain
556 if (traceCursor == 1)// || (trace.TraceEnt && trace.TraceEnt.IsInherited(GenericTerrainEntity)))
557 return GetPreviewPosAboveTerrain(cameraPos, cursorDir, worldPos, verticalMode);
558
559 worldPos = cameraPos + cursorDir * traceCursor;
560
561 //--- Terrain or sea is under cursor, change real vertical mode type
562 if (!trace.TraceEnt || trace.TraceEnt.Type() == GenericTerrainEntity || trace.TraceEnt.Type() == RoadEntity)
563 verticalMode = EEditorTransformVertical.TERRAIN;
564
565 //--- Check slope of intersected surface
566 //vector basePos = worldPos;
567 float dotProduct = vector.Dot(trace.TraceNorm, vector.Up);
568 float slope = 90 - Math.Tan(dotProduct) * Math.RAD2DEG;
569
570 //--- When intersecting ceiling, prevent editing altogether
571 if (slope > m_fMinAngleCeiling)
572 return false;
573
574 //--- When intersecting wall, find surface at its base.
575 //--- Proved to be quite unreliable when the entity was moved vertically before (Alt+ LMB drag).
576 //--- Let's disable walls for now, but keep the code in case we need in in the future.
577 if (slope > m_fMinAngleWall)
578 {
579 return false;
580
581// //--- Rotate trace normal vector to point down
582// vector matrixNorm[3];
583// Math3D.MatrixFromForwardVec(trace.TraceNorm, matrixNorm);
584//
585// vector matrixConvert[3];
586// matrixConvert[0] = vector.Up;
587// matrixConvert[1] = vector.Right;
588// matrixConvert[2] = vector.Forward;
589//
590// Math3D.MatrixMultiply3(matrixNorm, matrixConvert, matrixNorm);
591// vector vectorNorm = matrixNorm[0] * 100;
592// if (vectorNorm[1] > 0)
593// vectorNorm = -vectorNorm;
594//
595// //--- Trace down along the wall
596// vector offsetNorm = trace.TraceNorm * 0.01;
597// TraceParam traceBase = new TraceParam();
598// traceBase.Start = worldPos + offsetNorm;
599// traceBase.End = trace.Start + vectorNorm;
600// traceBase.Flags = TraceFlags.ENTS | TraceFlags.WORLD;
601// traceBase.ExcludeArray = m_PreviewEntityManager.GetSourceEntities();
602// float traceBaseDis = m_World.TraceMove(traceBase, null);
603//
604// basePos = traceBase.Start + vectorNorm * traceBaseDis - offsetNorm;
605 }
606
607// worldPos = basePos;
608
609 //--- Add entity height
610 worldPos[1] = worldPos[1] + m_PreviewEntityManager.GetPreviewHeightAboveTerrain();
611
612 return true;
613 }
614
615 //------------------------------------------------------------------------------------------------
616 protected bool GetPreviewPosAboveTerrain(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
617 {
618 //float heightASL = m_PreviewEntityManager.GetPreviewHeightAboveSea();
619 float heightATL = m_PreviewEntityManager.GetPreviewHeightAboveTerrain();
620
621 //--- Cursor below horizon
622 vector offsetPos = cameraPos;
623 if (verticalMode != EEditorTransformVertical.GEOMETRY && cameraPos[1] > worldPos[1]) //--- When camera is above ground, offset tracing pos by entity height to keep preview under cursor
624 offsetPos -= vector.Up * heightATL;
625
626 float traceDis = GetTraceDis(offsetPos, cursorDir, cameraPos[1]);
627 if (traceDis != 1)
628 {
629 //--- Cursor on the ground: Use intersection positon
630 worldPos = offsetPos + cursorDir * traceDis;
631 worldPos[1] = worldPos[1] + heightATL;
632
633 verticalMode = EEditorTransformVertical.TERRAIN;
634 return true;
635 }
636 else
637 {
638 if (cursorDir[1] > 0)
639 return false;
640
641 //--- Cursor above horizon: Use ASL
642 return GetPreviewPosAboveSea(cameraPos, cursorDir, worldPos, verticalMode);
643 }
644 }
645
646 //------------------------------------------------------------------------------------------------
647 protected bool GetPreviewPosAboveSea(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
648 {
649 float heightASL = m_PreviewEntityManager.GetPreviewHeightAboveSea();
650
651 float traceDis = 1;
652 if (verticalMode != EEditorTransformVertical.SEA && cursorDir[1] < 0)
653 {
654 //--- Cursor points below the camera: Use ground intersection
655 traceDis = GetTraceDis(cameraPos, cursorDir, cameraPos[1]);
656 if (traceDis == 1)
657 return false;
658 }
659
660 //--- Force ASL mode to prevent snapping to terrain
661 verticalMode = EEditorTransformVertical.SEA;
662
663 //--- Check for intersection with horizontal plane in entity's ASL height
664 if (traceDis == 1)
665 traceDis = Math3D.IntersectionRayBox(cameraPos, cameraPos + cursorDir, Vector(-float.MAX, heightASL, -float.MAX), Vector(float.MAX, heightASL, float.MAX));
666
667 //--- No plane intersection: Ignore (e.g., when camera is above the entity and cursor points at the sky)
668 if (traceDis == -1)
669 return false;
670
671 worldPos = cameraPos + cursorDir * traceDis;
672 worldPos[1] = heightASL; //--- Make sure ASL height is maintained
673
674 return true;
675 }
676
678 //--- Main Loop
680
681 //------------------------------------------------------------------------------------------------
682 protected void ProcessInput(float tDelta)
683 {
684 if (!m_InputManagerBase || !m_PlacingManager || !m_PreviewEntityManager || m_PreviewEntityManager.IsFixedPosition() || !m_PreviewEntityManager.GetPreviewEntity())
685 return;
686
687 //--- Transforming
688 bool canTransform = true;
689 bool instant = false;
690 vector previewTransform[4];
691 m_PreviewEntityManager.GetPreviewTransform(previewTransform);
692 EEditorTransformVertical verticalMode = m_PreviewEntityManager.GetVerticalMode();
694
695 SCR_EPreviewState previewState = SCR_EPreviewState.PLACEABLE;
697 m_PlacingManager.CanCreateEntity(previewStateToShow: previewState, params: params);
698 m_PreviewEntityManager.SetPreviewState(previewState);
699
700 //--- There are numerous issues with editing along geometry, so it's disabled for now
701 if (verticalMode == EEditorTransformVertical.GEOMETRY && m_PreviewEntityManager.GetPreviewEntity().HasMultipleEditableEntities())
702 verticalMode = EEditorTransformVertical.TERRAIN;
703
704 //--- Automatic animation when restoring transformation after unsnapping from a target
705 if (m_bIsAnimated)
706 {
707 previewTransform[0] = m_vAnimatedTransform[0];
708 previewTransform[1] = m_vAnimatedTransform[1];
709 previewTransform[2] = m_vAnimatedTransform[2];
710 }
711
712 float moveVertical = m_InputManagerBase.GetActionValue("EditorTransformMoveVertical") * tDelta;
713 float rotateYaw = m_InputManagerBase.GetActionValue("EditorTransformRotateYaw") * tDelta;
714
715 if (rotateYaw != 0 && Math.AbsFloat(rotateYaw) > Math.AbsFloat(moveVertical) && (m_Operation == EPreviewEntityEditorOperation.MOVE_HORIZONTAL || m_Operation == EPreviewEntityEditorOperation.ROTATE))
716 {
717 //--- Gamepad rotation
718 Rotate(tDelta, previewTransform, rotateYaw * m_fRotationCoef);
719 m_bIsAnimated = false;
720 moveVertical = 0;
722 }
723 else
724 {
725 m_fTargetYaw = 0;
726 }
727
729 {
730 //--- Rotation towards cursor
731 RotateTowardsCursor(tDelta, previewTransform);
732 m_bIsAnimated = false;
733 }
734 else if (m_InputManagerBase.GetActionTriggered("EditorTransformMoveVerticalModifier") && HasMouseMoved())
735 {
736 //--- Vertical movement towards cursor
737 MoveVerticalTowardsCursor(tDelta, previewTransform);
738 }
739 else if (moveVertical != 0 && (m_Operation == EPreviewEntityEditorOperation.MOVE_HORIZONTAL || m_Operation == EPreviewEntityEditorOperation.MOVE_VERTICAL))
740 {
741 //--- Vertical movement
742 instant = MoveVertical(tDelta, previewTransform, moveVertical * m_fMoveVerticalCoef, verticalMode);
744 }
745 else
746 {
747 //--- Horizontal movement towards cursor
748 MoveHorizontalTowardsCursor(tDelta, previewTransform, canTransform, verticalMode);
749 }
750
751 UpdateDirIndicator(previewTransform);
752
753 //--- Apply
754 if (canTransform)
755 m_PreviewEntityManager.SetPreviewTransform(previewTransform, tDelta, instant, verticalMode);
756 else
757 m_PreviewEntityManager.ResetPreviewTransform();
758 }
759
760 //------------------------------------------------------------------------------------------------
761 protected void ActivatePreviewContext()
762 {
763 m_InputManagerBase.ActivateContext(m_PreviewEntityManager.GetActionContext());
764 }
765
767 //--- Default methods
769
770 //------------------------------------------------------------------------------------------------
772 {
773 MenuRootComponent root = GetRootComponent();
774 if (!root)
775 return;
776
778
780 return;
781
784 return;
785
787
788 m_PreviewEntityManager.GetOnPreviewCreate().Insert(OnPreviewCreate);
789 m_PreviewEntityManager.GetOnPreviewDelete().Insert(OnPreviewDelete);
790
793 return;
794
796 if (m_HoverFilter)
797 m_HoverFilter.GetOnChanged().Insert(OnHoverChange);
798
799 ArmaReforgerScripted game = GetGame();
800 if (game)
801 {
802 m_World = game.GetWorld();
803
804 m_InputManagerBase = game.GetInputManager();
806 {
807 m_InputManagerBase.AddActionListener("EditorTransformSnapToSurface", EActionTrigger.DOWN, OnEditorTransformSnapToSurface);
808
809 m_InputManagerBase.AddActionListener("EditorTransformMoveVerticalModifier", EActionTrigger.DOWN, OnEditorTransformMoveVerticalModifierDown);
810 m_InputManagerBase.AddActionListener("EditorTransformMoveVerticalModifier", EActionTrigger.UP, OnEditorTransformMoveVerticalModifierUp);
811
812 m_InputManagerBase.AddActionListener("EditorTransformRotateYawModifier", EActionTrigger.DOWN, OnEditorTransformRotationModifierDown);
813 m_InputManagerBase.AddActionListener("EditorTransformRotateYawModifier", EActionTrigger.UP, OnEditorTransformRotationModifierUp);
814 }
815 }
816
818 }
819
820 //------------------------------------------------------------------------------------------------
821 override void HandlerDeattached(Widget w)
822 {
823 super.HandlerDeattached(w);
824
826 {
827 m_PreviewEntityManager.GetOnPreviewCreate().Remove(OnPreviewCreate);
828 m_PreviewEntityManager.GetOnPreviewDelete().Remove(OnPreviewDelete);
829 }
830
831 if (m_HoverFilter)
832 m_HoverFilter.GetOnChanged().Remove(OnHoverChange);
833
835 {
836 m_InputManagerBase.RemoveActionListener("EditorTransformSnapToSurface", EActionTrigger.DOWN, OnEditorTransformSnapToSurface);
837
838 m_InputManagerBase.RemoveActionListener("EditorTransformMoveVerticalModifier", EActionTrigger.DOWN, OnEditorTransformMoveVerticalModifierDown);
839 m_InputManagerBase.RemoveActionListener("EditorTransformMoveVerticalModifier", EActionTrigger.UP, OnEditorTransformMoveVerticalModifierUp);
840
841 m_InputManagerBase.RemoveActionListener("EditorTransformRotateYawModifier", EActionTrigger.DOWN, OnEditorTransformRotationModifierDown);
842 m_InputManagerBase.RemoveActionListener("EditorTransformRotateYawModifier", EActionTrigger.UP, OnEditorTransformRotationModifierUp);
843 }
844 }
845}
ref DSGameConfig game
Definition DSConfig.c:81
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition DebugMenuID.c:4
const int TRACE_LAYER_CAMERA
Definition Constants.c:14
ArmaReforgerScripted GetGame()
Definition game.c:1398
ref array< string > angles
class SCR_AIPolar m_Target
override void HandlerAttachedScripted(Widget w)
vector GetCursorPos()
void OnEditorTransformMoveVerticalModifierUp(float value, EActionTrigger reason)
EPreviewEntityEditorOperation m_Operation
SCR_PreviewEntityEditorComponent m_PreviewEntityManager
ResourceName m_DirIndicatorPrefab
void Rotate(float tDelta, out vector transform[4], float rotationValue)
bool MoveVertical(float tDelta, out vector transform[4], float moveVertical, EEditorTransformVertical verticalMode)
bool GetPreviewPosAboveGeometry(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
void OnEditorTransformRotationModifierUp(float value, EActionTrigger reason)
SCR_PlacingEditorComponent m_PlacingManager
void MoveVerticalTowardsCursor(float tDelta, out vector transform[4])
SCR_EPreviewState GetPreviewStateToShow()
void OnHoverChange(EEditableEntityState state, set< SCR_EditableEntityComponent > entitiesInsert, set< SCR_EditableEntityComponent > entitiesRemove)
SCR_CameraEditorComponent m_CameraManagerBase
vector m_vClickTransformBase[4]
void SetClickPos(vector clickPos)
bool RotateInSlot(SCR_EditableEntityComponent slot, float rotationValue, out vector angles, out bool freeRotation)
void OnEditorTransformMoveVerticalModifierDown(float value, EActionTrigger reason)
void OnEditorTransformRotationModifierDown(float value, EActionTrigger reason)
InputManager m_InputManagerBase
void RotateTowardsCursor(float tDelta, out vector transform[4])
void MoveHorizontalTowardsCursor(float tDelta, out vector transform[4], out bool canTransform, out EEditorTransformVertical verticalMode)
float GetTraceDis(vector pos, vector dir, float cameraHeight)
void ProcessInput(float tDelta)
void OnEditorTransformSnapToSurface()
vector m_vAnimatedTransform[4]
SCR_CursorEditorUIComponent m_CursorComponentBase
ref TraceParam m_RotationTrace
vector m_vTransformOrigin[4]
bool GetPreviewPosAboveSea(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
void UpdateDirIndicator(vector previewTransform[4])
SCR_HoverEditableEntityFilter m_HoverFilter
bool GetPreviewPosAboveTerrain(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
override void HandlerDeattached(Widget w)
Definition Color.c:13
Diagnostic and developer menu system.
Definition DiagMenu.c:18
Input management system for user interactions.
Definition Math.c:13
MenuRootSubComponent FindComponent(typename type, bool showError=false)
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25
static SCR_BaseEditableEntityFilter GetInstance(EEditableEntityState state, bool showError=false)
bool GetTransform(out vector outTransform[4])
Network packet of variables for entity placing and transformation.
static SCR_EditorPreviewParams CreateParamsFromPreview(SCR_PreviewEntityEditorComponent previewManager, SCR_EditableEntityComponent parent=null, bool parentChanged=false)
void SetDirty(bool isDirty)
Contains various scripted 3D math functions.
Definition SCR_Math3D.c:3
static bool OrientToTerrain(out vector transform[4], BaseWorld world=null, bool noUnderwater=false, TraceParam trace=null)
static vector GetTerrainNormal(inout vector pos, BaseWorld world=null, bool noUnderwater=false, TraceParam trace=null)
void EntitySpawnParams()
Definition gameLib.c:130
EPhysicsLayerPresets
Enum is filled by C++ by data in project config PhysicsSettings.LayerPresets.
Definition gameLib.c:19
DebugTextFlags
EEditableEntityState
SCR_FieldOfViewSettings Attribute
EEditorTransformVertical
Vertical transformation mode.
enum EPreviewEntityEditorOperation MIN_CURSOR_DIS_TO_TRANSFORM
EActionTrigger
@ ROTATE
Camera is rotating.
@ MAX
proto native vector Vector(float x, float y, float z)
TraceFlags
Definition TraceFlags.c:13