Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_PreviewEntityEditorUIComponent.c
Go to the documentation of this file.
1 //--- For gamepad only
3 {
7 }
8 
10 
11 class 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.")]
35  protected float m_fMinCameraVerticalOffset;
36 
37  [Attribute(uiwidget: UIWidgets.ResourcePickerThumbnail, params: "et")]
38  protected ResourceName m_DirIndicatorPrefab;
39 
40  protected InputManager m_InputManagerBase;
46  protected BaseWorld m_World;
47  protected vector m_vClickTransformBase[4];
48  protected vector m_vClickPosBase;
49  protected vector m_vClickPosWorldBase;
50  protected bool m_bMouseMoved;
53  protected float m_fTargetYaw;
54  protected float m_fUnsnapProgress;
55  protected vector m_vTransformOrigin[4];
56  protected vector m_vAnglesOrigin;
57  protected vector m_vAnimatedTransform[4];
58  protected vector m_vRotationPivot;
59  protected bool m_bIsAnimated;
60  protected vector m_vTerrainNormal;
62  protected IEntity m_DirIndicator;
63  protected float m_fDirIndicatorScale;
64  protected ref TraceParam m_RotationTrace;
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;
78  m_PreviewEntityManager.GetPreviewTransform(m_vAnimatedTransform);
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;
91  m_PreviewEntityManager.GetPreviewTransform(m_vAnimatedTransform);
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  //------------------------------------------------------------------------------------------------
129  protected void OnEditorTransformRotationModifierDown(float value, EActionTrigger reason)
130  {
132  return;
133 
135  SetClickPos(m_CursorComponentBase.GetCursorPos());
137  }
138 
139  //------------------------------------------------------------------------------------------------
140  protected void OnEditorTransformRotationModifierUp(float value, EActionTrigger reason)
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  //------------------------------------------------------------------------------------------------
158  protected void OnEditorTransformMoveVerticalModifierDown(float value, EActionTrigger reason)
159  {
160  if (!m_PreviewEntityManager.IsRotating())
161  SetClickPos(m_CursorComponentBase.GetCursorPos());
162  }
163 
164  //------------------------------------------------------------------------------------------------
165  protected void OnEditorTransformMoveVerticalModifierUp(float value, EActionTrigger reason)
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  {
198  m_RotationTrace = new TraceParam();
199  m_RotationTrace.ExcludeArray = m_PreviewEntityManager.GetExcludeArray();
200  }
201 
202  vector pos = m_vClickTransformBase[3];
203  m_vTerrainNormal = SCR_TerrainHelper.GetTerrainNormal(pos, m_World, !m_PreviewEntityManager.IsUnderwater(), m_RotationTrace);
204  }
205 
206  //------------------------------------------------------------------------------------------------
207  protected void SetClickPos(vector clickPos)
208  {
209  m_vClickPosBase = clickPos;
210  m_bMouseMoved = false;
211 
212  ArmaReforgerScripted game = GetGame();
213  if (!game || !m_World)
214  return;
215 
216  WorkspaceWidget workspace = game.GetWorkspace();
217  if (!workspace)
218  return;
219 
220  vector clickDir;
221  vector cameraPos = workspace.ProjScreenToWorld(clickPos[0], clickPos[1], clickDir, m_World, -1);
222  m_vClickPosWorldBase = cameraPos + clickDir * 10;
223  }
224 
225  //------------------------------------------------------------------------------------------------
226  protected bool HasMouseMoved()
227  {
228  if (m_bMouseMoved || !m_InputManagerBase.IsUsingMouseAndKeyboard())
229  return true;
230 
231  ArmaReforgerScripted game = GetGame();
232  if (!game || !m_World)
233  return false;
234 
235  WorkspaceWidget workspace = game.GetWorkspace();
236  if (!workspace)
237  return false;
238 
239  //--- Check not only if cursor moved, but also if camera moved, resulting in cursor movement in the world
240  vector clickPos = workspace.ProjWorldToScreen(m_vClickPosWorldBase, m_World);
241 
242  m_bMouseMoved = vector.Distance(m_CursorComponentBase.GetCursorPos(), clickPos/*m_vClickPosBase*/) > MIN_CURSOR_DIS_TO_TRANSFORM;
243  return m_bMouseMoved;
244  }
245 
246  protected void GetCursorPos(out vector cameraPos, out vector cursorDir)
247  {
248  ArmaReforgerScripted game = GetGame();
249  if (!game || !m_World)
250  return;
251 
252  WorkspaceWidget workspace = game.GetWorkspace();
253  if (!workspace)
254  return;
255 
256  vector cursorPos = m_CursorComponentBase.GetCursorPos();
257  cameraPos = workspace.ProjScreenToWorld(cursorPos[0], cursorPos[1], cursorDir, m_World, -1);
258  }
259 
260  //------------------------------------------------------------------------------------------------
261  protected float GetTraceDis(vector pos, vector dir, float cameraHeight)
262  {
263  TraceParam trace = new TraceParam();
264  trace.Start = pos;
265  trace.End = trace.Start + dir;
266  if (cameraHeight >= m_World.GetOceanBaseHeight())
267  trace.Flags = TraceFlags.WORLD | TraceFlags.OCEAN;
268  else
269  trace.Flags = TraceFlags.WORLD; //--- Don't check for water intersection when under water
270 
271  trace.LayerMask = TRACE_LAYER_CAMERA;
272 
273  return m_World.TraceMove(trace, null);
274  }
275 
276  //------------------------------------------------------------------------------------------------
277  protected void UpdateDirIndicator(vector previewTransform[4])
278  {
280  {
281  //--- Show dir indicator
282  if (!m_DirIndicator && m_DirIndicatorPrefab && m_PreviewEntityManager.GetPreviewEntity())
283  {
284  //--- Create object
285  EntitySpawnParams spawnParams = new EntitySpawnParams();
286  spawnParams.Parent = m_PreviewEntityManager.GetPreviewEntity();
287  m_DirIndicator = GetGame().SpawnEntityPrefab(Resource.Load(m_DirIndicatorPrefab), spawnParams.Parent.GetWorld(), spawnParams);
288 
289  //--- Get object size
290  vector previewBoundMin, previewBoundMax;
291  m_PreviewEntityManager.GetPreviewEntity().GetPreviewBounds(previewBoundMin, previewBoundMax);
292  float previewSize = vector.DistanceXZ(previewBoundMin, previewBoundMax);
293  float offsetSize = vector.DistanceXZ(vector.Zero, previewBoundMin + previewBoundMax);
294  float localOffsetSize = vector.DistanceXZ(vector.Zero, m_PreviewEntityManager.GetLocalOffset());
295  m_fDirIndicatorScale = (previewSize + offsetSize + localOffsetSize) * 0.5;
296  }
297 
298  if (m_DirIndicator)
299  {
300  //--- Align the indicator to surface
301  vector angles = Math3D.MatrixToAngles(previewTransform);
302  angles[1] = 0; //--- Reset pitch
303  angles[2] = 0; //--- Reset roll
304 
305  vector orientedTransform[4];
306  Math3D.AnglesToMatrix(angles, orientedTransform);
307 
308  orientedTransform[3] = m_vRotationPivot;
309  SCR_TerrainHelper.OrientToTerrain(orientedTransform, trace: m_RotationTrace);
310 
311  m_DirIndicator.SetWorldTransform(orientedTransform);
313  }
314  }
315  else if (m_DirIndicator)
316  {
317  m_RotationTrace = null;
318  delete m_DirIndicator;
319  }
320  }
321 
322  //------------------------------------------------------------------------------------------------
325 
327  //--- Transformation methods
329 
330  //------------------------------------------------------------------------------------------------
331  protected void MoveHorizontalTowardsCursor(float tDelta, out vector transform[4], out bool canTransform, out EEditorTransformVertical verticalMode)
332  {
333  vector cameraPos, cursorDir;
334  GetCursorPos(cameraPos, cursorDir);
335  cursorDir *= TRACE_DIS;
336  vector pos = transform[3];
337 
338  switch (verticalMode)
339  {
340  case EEditorTransformVertical.GEOMETRY:
341  {
342  canTransform = GetPreviewPosAboveGeometry(cameraPos, cursorDir, pos, verticalMode);
343  break;
344  }
345  case EEditorTransformVertical.TERRAIN:
346  {
347  canTransform = GetPreviewPosAboveTerrain(cameraPos, cursorDir, pos, verticalMode);
348  break;
349  }
350  case EEditorTransformVertical.SEA:
351  {
352  canTransform = GetPreviewPosAboveSea(cameraPos, cursorDir, pos, verticalMode);
353  break;
354  }
355  }
356 
357  transform[3] = pos;
358  m_fUnsnapProgress = 0;
359  m_PreviewEntityManager.SetIsMovingVertically(false);
360  }
361 
362  //------------------------------------------------------------------------------------------------
363  protected bool MoveVertical(float tDelta, out vector transform[4], float moveVertical, EEditorTransformVertical verticalMode)
364  {
365  //--- Gamepad move vertical
366  if (m_PreviewEntityManager.CanUnsnap(moveVertical))
367  {
368  m_fUnsnapProgress += tDelta;
370  return false;
371  }
372  else
373  {
374  m_fUnsnapProgress = 0;
375  }
376 
377  //--- Apply changes
378  vector pos = transform[3];
379  transform[3][1] = pos[1] + moveVertical;// * tDelta;
380 
381  //--- Snap vertically (not when unsnapped recently)
382  if (m_fUnsnapProgress == 0)
383  transform[3] = m_PreviewEntityManager.SnapVertically(transform[3]);
384 
385  //-- Update height
386  m_PreviewEntityManager.SetPreviewHeight(transform[3]);
387 
388  //--- Adjust camera to keep looking at preview
389  SCR_ManualCamera camera;
390  if (verticalMode != EEditorTransformVertical.GEOMETRY && m_CameraManagerBase && m_CameraManagerBase.GetCamera(camera))
391  {
392  vector cameraPos = camera.GetWorldTransformAxis(3) + transform[3] - pos;
393  pos = transform[3];
394 
395  if (cameraPos[1] > pos[1] + m_fMinCameraVerticalOffset && m_PreviewEntityManager.GetPreviewHeightAboveTerrain() > 0)
396  {
397  //--- Move camera with the entity when it's above the entity and the entity is above ground
398  camera.SetOrigin(cameraPos);
399  }
400  else
401  {
402  //--- Rotate camera towards the entity in all other cases
403  vector cameraTransform[4] = {vector.Right, vector.Up, vector.Forward, camera.GetWorldTransformAxis(3)};
404  Math3D.DirectionAndUpMatrix(transform[3] - cameraTransform[3], vector.Up, cameraTransform);
405  camera.SetTransform(cameraTransform);
406  }
407 
408  camera.SetDirty(true);
409  }
410 
411  m_PreviewEntityManager.SetIsMovingVertically(true);
412  return true;
413  }
414 
415  //------------------------------------------------------------------------------------------------
416  protected void MoveVerticalTowardsCursor(float tDelta, out vector transform[4])
417  {
418  vector cameraPos, cursorDir;
419  GetCursorPos(cameraPos, cursorDir);
420 
421  float dis = vector.DistanceXZ(cameraPos, transform[3]);
422  float angle = cursorDir.VectorToAngles()[1];
423  vector tracePos = cameraPos + cursorDir * (dis / Math.Cos(angle * Math.DEG2RAD));
424  transform[3][1] = tracePos[1];
425  transform[3] = m_PreviewEntityManager.SnapVertically(transform[3]);
426  m_PreviewEntityManager.SetPreviewHeight(transform[3]);
427  m_PreviewEntityManager.SetIsMovingVertically(true);
428 
429 #ifdef ENABLE_DIAG
430  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_EDITOR_SHOW_DEBUG))
431  {
432  string text = string.Format(" %1 m", m_PreviewEntityManager.GetPreviewHeightAboveTerrain().ToString(lenDec: 3));
433  DebugTextWorldSpace.Create(m_World, text, DebugTextFlags.ONCE | DebugTextFlags.FACE_CAMERA, transform[3][0], transform[3][1], transform[3][2], color: Color.PINK);
434  }
435 #endif
436  }
437 
438  //------------------------------------------------------------------------------------------------
439  protected void Rotate(float tDelta, out vector transform[4], float rotationValue)
440  {
441  vector angles = transform[2].VectorToAngles();
442  bool freeRotation = true;
444  if (target)
445  {
446  if (!RotateInSlot(target, rotationValue, angles, freeRotation))
447  return;
448  }
449 
450  if (freeRotation)
451  {
452  angles -= m_vAnglesOrigin;
453  angles[0] = angles[0] + rotationValue;// * tDelta;
454  }
455 
456  vector basis[4];
457  Math3D.AnglesToMatrix(angles, basis);
458  Math3D.MatrixMultiply3(basis, m_vTransformOrigin, transform);
459  m_vRotationPivot = transform[3];
460  }
461 
462  //------------------------------------------------------------------------------------------------
463  protected bool RotateInSlot(SCR_EditableEntityComponent slot, float rotationValue, out vector angles, out bool freeRotation)
464  {
465  if (m_fTargetYaw)
466  {
467  angles[0] = m_fTargetYaw;
468  return true;
469  }
470 
471  SCR_SiteSlotEntity slotEntity = SCR_SiteSlotEntity.Cast(slot.GetOwner());
472  if (!slotEntity)
473  return false;
474 
475  float step = slotEntity.GetRotationStep();
476  if (step == -1)
477  return false;
478 
479  if (step == 0)
480  return true;
481 
482  angles[0] = angles[0] + step * rotationValue.Sign();
483  m_fTargetYaw = angles[0];
484  return true;
485  }
486 
487  //------------------------------------------------------------------------------------------------
488  protected void RotateTowardsCursor(float tDelta, out vector transform[4])
489  {
490  //--- Reset when camera starts moving
491  if (m_CameraManagerBase && m_CameraManagerBase.GetCamera() && m_CameraManagerBase.GetCamera().IsManualInput())
492  {
494  return;
495  }
496 
497  vector pivotPos;
499  if (target)
500  {
501  //--- Attached to a target - use its center instead of relative click position
502  vector targetTransform[4];
503  target.GetTransform(targetTransform);
504  pivotPos = targetTransform[3];
505  }
506  else
507  {
508  pivotPos = m_vClickTransformBase[3];
509  pivotPos[1] = pivotPos[1] - m_PreviewEntityManager.GetLocalOffset()[1];
510  }
511 
512  //--- Get intersection with terrain plane
513  vector cameraPos, cursorDir;
514  GetCursorPos(cameraPos, cursorDir);
515  vector worldPos = SCR_Math3D.IntersectPlane(cameraPos, cursorDir * TRACE_DIS, pivotPos, m_vTerrainNormal);
516  float dir = (worldPos - pivotPos).VectorToAngles()[0] - m_vAnglesOrigin[0];
517 
518  vector basis[4];
519  Math3D.AnglesToMatrix(Vector(dir, 0, 0), basis);
520  Math3D.MatrixMultiply3(basis, m_vTransformOrigin, transform);
521 
522  m_vRotationPivot = pivotPos;
523  m_PreviewEntityManager.SetIsRotating(true);
525 
526  //--- Debug
527  //Shape.CreateSphere(Color.White.PackToInt(), ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, m_vClickTransformBase[3], 1);
528  //Shape.CreateSphere(Color.Red.PackToInt(), ShapeFlags.ONCE | ShapeFlags.NOZBUFFER, worldPos, 1);
529  }
530 
532  //--- Intersections
534 
535  //------------------------------------------------------------------------------------------------
536  protected bool GetPreviewPosAboveGeometry(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
537  {
538  //--- Trace entity under cursor
539  TraceParam trace = new TraceParam();
540  trace.Start = cameraPos;
541  trace.End = trace.Start + cursorDir;
542  trace.LayerMask = EPhysicsLayerPresets.Projectile; //--- Use more detailed mask which can also detect e.g., rack shelves
543  trace.Flags = TraceFlags.ENTS | TraceFlags.WORLD;
544  if (cameraPos[1] >= m_World.GetOceanBaseHeight())
545  trace.Flags |= TraceFlags.OCEAN;
546 
547  trace.ExcludeArray = m_PreviewEntityManager.GetExcludeArray();
548  float traceCursor = m_World.TraceMove(trace, null);
549 
550  //--- No entity intersection, calculate by terrain
551  if (traceCursor == 1)// || (trace.TraceEnt && trace.TraceEnt.IsInherited(GenericTerrainEntity)))
552  return GetPreviewPosAboveTerrain(cameraPos, cursorDir, worldPos, verticalMode);
553 
554  worldPos = cameraPos + cursorDir * traceCursor;
555 
556  //--- Terrain or sea is under cursor, change real vertical mode type
557  if (!trace.TraceEnt || trace.TraceEnt.Type() == GenericTerrainEntity || trace.TraceEnt.Type() == RoadEntity)
558  verticalMode = EEditorTransformVertical.TERRAIN;
559 
560  //--- Check slope of intersected surface
561  //vector basePos = worldPos;
562  float dotProduct = vector.Dot(trace.TraceNorm, vector.Up);
563  float slope = 90 - Math.Tan(dotProduct) * Math.RAD2DEG;
564 
565  //--- When intersecting ceiling, prevent editing altogether
566  if (slope > m_fMinAngleCeiling)
567  return false;
568 
569  //--- When intersecting wall, find surface at its base.
570  //--- Proved to be quite unreliable when the entity was moved vertically before (Alt+ LMB drag).
571  //--- Let's disable walls for now, but keep the code in case we need in in the future.
572  if (slope > m_fMinAngleWall)
573  {
574  return false;
575 
576 // //--- Rotate trace normal vector to point down
577 // vector matrixNorm[3];
578 // Math3D.MatrixFromForwardVec(trace.TraceNorm, matrixNorm);
579 //
580 // vector matrixConvert[3];
581 // matrixConvert[0] = vector.Up;
582 // matrixConvert[1] = vector.Right;
583 // matrixConvert[2] = vector.Forward;
584 //
585 // Math3D.MatrixMultiply3(matrixNorm, matrixConvert, matrixNorm);
586 // vector vectorNorm = matrixNorm[0] * 100;
587 // if (vectorNorm[1] > 0)
588 // vectorNorm = -vectorNorm;
589 //
590 // //--- Trace down along the wall
591 // vector offsetNorm = trace.TraceNorm * 0.01;
592 // TraceParam traceBase = new TraceParam();
593 // traceBase.Start = worldPos + offsetNorm;
594 // traceBase.End = trace.Start + vectorNorm;
595 // traceBase.Flags = TraceFlags.ENTS | TraceFlags.WORLD;
596 // traceBase.ExcludeArray = m_PreviewEntityManager.GetSourceEntities();
597 // float traceBaseDis = m_World.TraceMove(traceBase, null);
598 //
599 // basePos = traceBase.Start + vectorNorm * traceBaseDis - offsetNorm;
600  }
601 
602 // worldPos = basePos;
603 
604  //--- Add entity height
605  worldPos[1] = worldPos[1] + m_PreviewEntityManager.GetPreviewHeightAboveTerrain();
606 
607  return true;
608  }
609 
610  //------------------------------------------------------------------------------------------------
611  protected bool GetPreviewPosAboveTerrain(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
612  {
613  //float heightASL = m_PreviewEntityManager.GetPreviewHeightAboveSea();
614  float heightATL = m_PreviewEntityManager.GetPreviewHeightAboveTerrain();
615 
616  //--- Cursor below horizon
617  vector offsetPos = cameraPos;
618  if (verticalMode != EEditorTransformVertical.GEOMETRY && cameraPos[1] > worldPos[1]) //--- When camera is above ground, offset tracing pos by entity height to keep preview under cursor
619  offsetPos -= vector.Up * heightATL;
620 
621  float traceDis = GetTraceDis(offsetPos, cursorDir, cameraPos[1]);
622  if (traceDis != 1)
623  {
624  //--- Cursor on the ground: Use intersection positon
625  worldPos = offsetPos + cursorDir * traceDis;
626  worldPos[1] = worldPos[1] + heightATL;
627 
628  verticalMode = EEditorTransformVertical.TERRAIN;
629  return true;
630  }
631  else
632  {
633  if (cursorDir[1] > 0)
634  return false;
635 
636  //--- Cursor above horizon: Use ASL
637  return GetPreviewPosAboveSea(cameraPos, cursorDir, worldPos, verticalMode);
638  }
639  }
640 
641  //------------------------------------------------------------------------------------------------
642  protected bool GetPreviewPosAboveSea(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
643  {
644  float heightASL = m_PreviewEntityManager.GetPreviewHeightAboveSea();
645 
646  float traceDis = 1;
647  if (verticalMode != EEditorTransformVertical.SEA && cursorDir[1] < 0)
648  {
649  //--- Cursor points below the camera: Use ground intersection
650  traceDis = GetTraceDis(cameraPos, cursorDir, cameraPos[1]);
651  if (traceDis == 1)
652  return false;
653  }
654 
655  //--- Force ASL mode to prevent snapping to terrain
656  verticalMode = EEditorTransformVertical.SEA;
657 
658  //--- Check for intersection with horizontal plane in entity's ASL height
659  if (traceDis == 1)
660  traceDis = Math3D.IntersectionRayBox(cameraPos, cameraPos + cursorDir, Vector(-float.MAX, heightASL, -float.MAX), Vector(float.MAX, heightASL, float.MAX));
661 
662  //--- No plane intersection: Ignore (e.g., when camera is above the entity and cursor points at the sky)
663  if (traceDis == -1)
664  return false;
665 
666  worldPos = cameraPos + cursorDir * traceDis;
667  worldPos[1] = heightASL; //--- Make sure ASL height is maintained
668 
669  return true;
670  }
671 
673  //--- Main Loop
675 
676  //------------------------------------------------------------------------------------------------
677  protected void ProcessInput(float tDelta)
678  {
679  if (!m_InputManagerBase || !m_PlacingManager || !m_PreviewEntityManager || m_PreviewEntityManager.IsFixedPosition() || !m_PreviewEntityManager.GetPreviewEntity())
680  return;
681 
682  //--- Transforming
683  bool canTransform = true;
684  bool instant = false;
685  vector previewTransform[4];
686  m_PreviewEntityManager.GetPreviewTransform(previewTransform);
687  EEditorTransformVertical verticalMode = m_PreviewEntityManager.GetVerticalMode();
688  m_Operation = EPreviewEntityEditorOperation.MOVE_HORIZONTAL;
689 
690  SCR_EPreviewState previewState = SCR_EPreviewState.PLACEABLE;
691  ENotification outNotification;
692  m_PlacingManager.CanCreateEntity(outNotification, previewState);
693  m_PreviewEntityManager.SetPreviewState(previewState);
694 
695  //--- There are numerous issues with editing along geometry, so it's disabled for now
696  if (verticalMode == EEditorTransformVertical.GEOMETRY && m_PreviewEntityManager.GetPreviewEntity().HasMultipleEditableEntities())
697  verticalMode = EEditorTransformVertical.TERRAIN;
698 
699  //--- Automatic animation when restoring transformation after unsnapping from a target
700  if (m_bIsAnimated)
701  {
702  previewTransform[0] = m_vAnimatedTransform[0];
703  previewTransform[1] = m_vAnimatedTransform[1];
704  previewTransform[2] = m_vAnimatedTransform[2];
705  }
706 
707  float moveVertical = m_InputManagerBase.GetActionValue("EditorTransformMoveVertical") * tDelta;
708  float rotateYaw = m_InputManagerBase.GetActionValue("EditorTransformRotateYaw") * tDelta;
709 
710  if (rotateYaw != 0 && Math.AbsFloat(rotateYaw) > Math.AbsFloat(moveVertical) && (m_Operation == EPreviewEntityEditorOperation.MOVE_HORIZONTAL || m_Operation == EPreviewEntityEditorOperation.ROTATE))
711  {
712  //--- Gamepad rotation
713  Rotate(tDelta, previewTransform, rotateYaw * m_fRotationCoef);
714  m_bIsAnimated = false;
715  moveVertical = 0;
717  }
718  else
719  {
720  m_fTargetYaw = 0;
721  }
722 
724  {
725  //--- Rotation towards cursor
726  RotateTowardsCursor(tDelta, previewTransform);
727  m_bIsAnimated = false;
728  }
729  else if (m_InputManagerBase.GetActionTriggered("EditorTransformMoveVerticalModifier") && HasMouseMoved())
730  {
731  //--- Vertical movement towards cursor
732  MoveVerticalTowardsCursor(tDelta, previewTransform);
733  }
734  else if (moveVertical != 0 && (m_Operation == EPreviewEntityEditorOperation.MOVE_HORIZONTAL || m_Operation == EPreviewEntityEditorOperation.MOVE_VERTICAL))
735  {
736  //--- Vertical movement
737  instant = MoveVertical(tDelta, previewTransform, moveVertical * m_fMoveVerticalCoef, verticalMode);
739  }
740  else
741  {
742  //--- Horizontal movement towards cursor
743  MoveHorizontalTowardsCursor(tDelta, previewTransform, canTransform, verticalMode);
744  }
745 
746  UpdateDirIndicator(previewTransform);
747 
748  //--- Apply
749  if (canTransform)
750  m_PreviewEntityManager.SetPreviewTransform(previewTransform, tDelta, instant, verticalMode);
751  else
752  m_PreviewEntityManager.ResetPreviewTransform();
753  }
754 
755  //------------------------------------------------------------------------------------------------
756  protected void ActivatePreviewContext()
757  {
758  m_InputManagerBase.ActivateContext(m_PreviewEntityManager.GetActionContext());
759  }
760 
762  //--- Default methods
764 
765  //------------------------------------------------------------------------------------------------
766  override void HandlerAttachedScripted(Widget w)
767  {
768  MenuRootComponent root = GetRootComponent();
769  if (!root)
770  return;
771 
773 
775  return;
776 
779  return;
780 
782 
783  m_PreviewEntityManager.GetOnPreviewCreate().Insert(OnPreviewCreate);
784  m_PreviewEntityManager.GetOnPreviewDelete().Insert(OnPreviewDelete);
785 
787  if (!m_CameraManagerBase)
788  return;
789 
791  if (m_HoverFilter)
792  m_HoverFilter.GetOnChanged().Insert(OnHoverChange);
793 
794  ArmaReforgerScripted game = GetGame();
795  if (game)
796  {
797  m_World = game.GetWorld();
798 
799  m_InputManagerBase = game.GetInputManager();
800  if (m_InputManagerBase)
801  {
802  m_InputManagerBase.AddActionListener("EditorTransformSnapToSurface", EActionTrigger.DOWN, OnEditorTransformSnapToSurface);
803 
804  m_InputManagerBase.AddActionListener("EditorTransformMoveVerticalModifier", EActionTrigger.DOWN, OnEditorTransformMoveVerticalModifierDown);
805  m_InputManagerBase.AddActionListener("EditorTransformMoveVerticalModifier", EActionTrigger.UP, OnEditorTransformMoveVerticalModifierUp);
806 
807  m_InputManagerBase.AddActionListener("EditorTransformRotateYawModifier", EActionTrigger.DOWN, OnEditorTransformRotationModifierDown);
808  m_InputManagerBase.AddActionListener("EditorTransformRotateYawModifier", EActionTrigger.UP, OnEditorTransformRotationModifierUp);
809  }
810  }
811 
812  m_fRotationInertia = 1 / Math.Max(m_fRotationInertia, 0.001);
813  }
814 
815  //------------------------------------------------------------------------------------------------
816  override void HandlerDeattached(Widget w)
817  {
818  super.HandlerDeattached(w);
819 
821  {
822  m_PreviewEntityManager.GetOnPreviewCreate().Remove(OnPreviewCreate);
823  m_PreviewEntityManager.GetOnPreviewDelete().Remove(OnPreviewDelete);
824  }
825 
826  if (m_HoverFilter)
827  m_HoverFilter.GetOnChanged().Remove(OnHoverChange);
828 
829  if (m_InputManagerBase)
830  {
831  m_InputManagerBase.RemoveActionListener("EditorTransformSnapToSurface", EActionTrigger.DOWN, OnEditorTransformSnapToSurface);
832 
833  m_InputManagerBase.RemoveActionListener("EditorTransformMoveVerticalModifier", EActionTrigger.DOWN, OnEditorTransformMoveVerticalModifierDown);
834  m_InputManagerBase.RemoveActionListener("EditorTransformMoveVerticalModifier", EActionTrigger.UP, OnEditorTransformMoveVerticalModifierUp);
835 
836  m_InputManagerBase.RemoveActionListener("EditorTransformRotateYawModifier", EActionTrigger.DOWN, OnEditorTransformRotationModifierDown);
837  m_InputManagerBase.RemoveActionListener("EditorTransformRotateYawModifier", EActionTrigger.UP, OnEditorTransformRotationModifierUp);
838  }
839  }
840 }
SCR_TerrainHelper
Definition: SCR_TerrainHelper.c:1
OnEditorTransformRotationModifierUp
protected void OnEditorTransformRotationModifierUp(float value, EActionTrigger reason)
Definition: SCR_PreviewEntityEditorUIComponent.c:140
m_vAnimatedTransform
protected vector m_vAnimatedTransform[4]
Definition: SCR_PreviewEntityEditorUIComponent.c:57
EEditableEntityState
EEditableEntityState
Definition: EEditableEntityState.c:37
UpdateDirIndicator
protected void UpdateDirIndicator(vector previewTransform[4])
Definition: SCR_PreviewEntityEditorUIComponent.c:277
MOVE_VERTICAL
@ MOVE_VERTICAL
Definition: SCR_PreviewEntityEditorUIComponent.c:5
SCR_CursorEditorUIComponent
Definition: SCR_CursorEditorUIComponent.c:3
SCR_ManualCamera
Definition: SCR_ManualCamera.c:16
m_fMoveVerticalCoef
protected float m_fMoveVerticalCoef
Definition: SCR_PreviewEntityEditorUIComponent.c:17
OnEditorTransformMoveVerticalModifierDown
protected void OnEditorTransformMoveVerticalModifierDown(float value, EActionTrigger reason)
Definition: SCR_PreviewEntityEditorUIComponent.c:158
SetClickPos
protected void SetClickPos(vector clickPos)
Definition: SCR_PreviewEntityEditorUIComponent.c:207
Rotate
protected void Rotate(float tDelta, out vector transform[4], float rotationValue)
Definition: SCR_PreviewEntityEditorUIComponent.c:439
m_fDirIndicatorScale
protected float m_fDirIndicatorScale
Definition: SCR_PreviewEntityEditorUIComponent.c:63
OnEditorTransformMoveVerticalModifierUp
protected void OnEditorTransformMoveVerticalModifierUp(float value, EActionTrigger reason)
Definition: SCR_PreviewEntityEditorUIComponent.c:165
m_fMinCameraVerticalOffset
protected float m_fMinCameraVerticalOffset
Definition: SCR_PreviewEntityEditorUIComponent.c:35
m_vAnglesOrigin
protected vector m_vAnglesOrigin
Definition: SCR_PreviewEntityEditorUIComponent.c:56
RotateTowardsCursor
protected void RotateTowardsCursor(float tDelta, out vector transform[4])
Definition: SCR_PreviewEntityEditorUIComponent.c:488
m_fTargetYaw
protected float m_fTargetYaw
Definition: SCR_PreviewEntityEditorUIComponent.c:53
m_fRotationInertia
protected float m_fRotationInertia
Definition: SCR_PreviewEntityEditorUIComponent.c:23
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
SCR_CameraEditorComponent
Definition: SCR_CameraEditorComponent.c:13
m_Target
protected SCR_EditableEntityComponent m_Target
Definition: SCR_PreviewEntityEditorUIComponent.c:52
ROTATE
@ ROTATE
Definition: SCR_PreviewEntityEditorUIComponent.c:6
GetTraceDis
protected float GetTraceDis(vector pos, vector dir, float cameraHeight)
Definition: SCR_PreviewEntityEditorUIComponent.c:261
ProcessInput
protected void ProcessInput(float tDelta)
Definition: SCR_PreviewEntityEditorUIComponent.c:677
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
SCR_EPreviewState
SCR_EPreviewState
Definition: SCR_PreviewEntityEditorComponent.c:1138
MoveVerticalTowardsCursor
protected void MoveVerticalTowardsCursor(float tDelta, out vector transform[4])
Definition: SCR_PreviewEntityEditorUIComponent.c:416
m_Operation
protected EPreviewEntityEditorOperation m_Operation
Definition: SCR_PreviewEntityEditorUIComponent.c:61
m_DirIndicatorPrefab
protected ResourceName m_DirIndicatorPrefab
Definition: SCR_PreviewEntityEditorUIComponent.c:38
SCR_Math3D
Contains various scripted 3D math functions.
Definition: SCR_Math3D.c:2
m_PlacingManager
protected SCR_PlacingEditorComponent m_PlacingManager
Definition: SCR_PreviewEntityEditorUIComponent.c:43
m_fRotationCoef
protected float m_fRotationCoef
Definition: SCR_PreviewEntityEditorUIComponent.c:20
m_bMouseMoved
protected bool m_bMouseMoved
Definition: SCR_PreviewEntityEditorUIComponent.c:50
GetPreviewPosAboveTerrain
protected bool GetPreviewPosAboveTerrain(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
Definition: SCR_PreviewEntityEditorUIComponent.c:611
ENotification
ENotification
Definition: ENotification.c:4
EEditorTransformVertical
EEditorTransformVertical
Vertical transformation mode.
Definition: EEditorTransformVertical.c:5
GetCursorPos
protected void GetCursorPos(out vector cameraPos, out vector cursorDir)
Definition: SCR_PreviewEntityEditorUIComponent.c:246
m_vClickTransformBase
protected vector m_vClickTransformBase[4]
Definition: SCR_PreviewEntityEditorUIComponent.c:47
MoveVertical
protected bool MoveVertical(float tDelta, out vector transform[4], float moveVertical, EEditorTransformVertical verticalMode)
Definition: SCR_PreviewEntityEditorUIComponent.c:363
m_PreviewEntityManager
protected SCR_PreviewEntityEditorComponent m_PreviewEntityManager
Definition: SCR_PreviewEntityEditorUIComponent.c:41
Attribute
typedef Attribute
Post-process effect of scripted camera.
HandlerDeattached
override void HandlerDeattached(Widget w)
Definition: SCR_PreviewEntityEditorUIComponent.c:816
OnEditorTransformRotationModifierDown
protected void OnEditorTransformRotationModifierDown(float value, EActionTrigger reason)
Definition: SCR_PreviewEntityEditorUIComponent.c:129
GetPreviewPosAboveGeometry
protected bool GetPreviewPosAboveGeometry(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
Definition: SCR_PreviewEntityEditorUIComponent.c:536
m_HoverFilter
protected SCR_HoverEditableEntityFilter m_HoverFilter
Definition: SCR_PreviewEntityEditorUIComponent.c:45
m_DirIndicator
protected IEntity m_DirIndicator
Definition: SCR_PreviewEntityEditorUIComponent.c:62
TRACE_LAYER_CAMERA
const int TRACE_LAYER_CAMERA
Definition: Constants.c:14
OnPreviewCreate
protected void OnPreviewCreate()
Definition: SCR_PreviewEntityEditorUIComponent.c:97
GetPreviewPosAboveSea
protected bool GetPreviewPosAboveSea(vector cameraPos, vector cursorDir, out vector worldPos, out EEditorTransformVertical verticalMode)
Definition: SCR_PreviewEntityEditorUIComponent.c:642
HasMouseMoved
protected bool HasMouseMoved()
Definition: SCR_PreviewEntityEditorUIComponent.c:226
OnHoverChange
protected void OnHoverChange(EEditableEntityState state, set< SCR_EditableEntityComponent > entitiesInsert, set< SCR_EditableEntityComponent > entitiesRemove)
Definition: SCR_PreviewEntityEditorUIComponent.c:67
m_CursorComponentBase
protected SCR_CursorEditorUIComponent m_CursorComponentBase
Definition: SCR_PreviewEntityEditorUIComponent.c:44
EPreviewEntityEditorOperation
EPreviewEntityEditorOperation
Definition: SCR_PreviewEntityEditorUIComponent.c:2
SCR_HoverEditableEntityFilter
Definition: SCR_HoverEditableEntityFilter.c:6
m_World
protected BaseWorld m_World
Definition: SCR_PreviewEntityEditorUIComponent.c:46
m_bIsAnimated
protected bool m_bIsAnimated
Definition: SCR_PreviewEntityEditorUIComponent.c:59
MoveHorizontalTowardsCursor
protected void MoveHorizontalTowardsCursor(float tDelta, out vector transform[4], out bool canTransform, out EEditorTransformVertical verticalMode)
Definition: SCR_PreviewEntityEditorUIComponent.c:331
SCR_BaseEditableEntityFilter
Definition: SCR_BaseEditableEntityFilter.c:13
m_fUnsnapProgress
protected float m_fUnsnapProgress
Definition: SCR_PreviewEntityEditorUIComponent.c:54
m_vRotationPivot
protected vector m_vRotationPivot
Definition: SCR_PreviewEntityEditorUIComponent.c:58
SCR_EditableEntityComponent
Definition: SCR_EditableEntityComponent.c:13
MOVE_HORIZONTAL
@ MOVE_HORIZONTAL
Definition: SCR_PreviewEntityEditorUIComponent.c:4
SCR_BaseEditorUIComponent
Definition: SCR_BaseEditorUIComponent.c:3
MenuRootComponent
Definition: MenuRootComponent.c:6
GetPreviewStateToShow
protected SCR_EPreviewState GetPreviewStateToShow()
OnEditorTransformSnapToSurface
protected void OnEditorTransformSnapToSurface()
Definition: SCR_PreviewEntityEditorUIComponent.c:123
m_fMinAngleWall
protected float m_fMinAngleWall
Definition: SCR_PreviewEntityEditorUIComponent.c:29
SCR_SiteSlotEntity
Definition: SCR_SiteSlotEntity.c:26
m_vClickPosWorldBase
protected vector m_vClickPosWorldBase
Definition: SCR_PreviewEntityEditorUIComponent.c:49
OnPreviewDelete
protected void OnPreviewDelete()
Definition: SCR_PreviewEntityEditorUIComponent.c:116
m_RotationTrace
protected ref TraceParam m_RotationTrace
Definition: SCR_PreviewEntityEditorUIComponent.c:64
m_fMinAngleCeiling
protected float m_fMinAngleCeiling
Definition: SCR_PreviewEntityEditorUIComponent.c:32
m_vTransformOrigin
protected vector m_vTransformOrigin[4]
Definition: SCR_PreviewEntityEditorUIComponent.c:55
params
Configs ServerBrowser KickDialogs params
Definition: SCR_NotificationSenderComponent.c:24
SetRotationPivot
protected void SetRotationPivot()
Definition: SCR_PreviewEntityEditorUIComponent.c:179
ActivatePreviewContext
protected void ActivatePreviewContext()
Definition: SCR_PreviewEntityEditorUIComponent.c:756
m_InputManagerBase
protected InputManager m_InputManagerBase
Definition: SCR_PreviewEntityEditorUIComponent.c:40
m_fUnsnapDuration
protected float m_fUnsnapDuration
Definition: SCR_PreviewEntityEditorUIComponent.c:26
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3
MIN_CURSOR_DIS_TO_TRANSFORM
enum EPreviewEntityEditorOperation MIN_CURSOR_DIS_TO_TRANSFORM
SCR_PlacingEditorComponent
Definition: SCR_PlacingEditorComponent.c:118
m_vClickPosBase
protected vector m_vClickPosBase
Definition: SCR_PreviewEntityEditorUIComponent.c:48
m_CameraManagerBase
protected SCR_CameraEditorComponent m_CameraManagerBase
Definition: SCR_PreviewEntityEditorUIComponent.c:42
m_bIsRotatingTowardsCursor
protected bool m_bIsRotatingTowardsCursor
Definition: SCR_PreviewEntityEditorUIComponent.c:51
HandlerAttachedScripted
override void HandlerAttachedScripted(Widget w)
Definition: SCR_PreviewEntityEditorUIComponent.c:766
m_vTerrainNormal
protected vector m_vTerrainNormal
Definition: SCR_PreviewEntityEditorUIComponent.c:60
SCR_PreviewEntityEditorComponent
Definition: SCR_PreviewEntityEditorComponent.c:12
RotateInSlot
protected bool RotateInSlot(SCR_EditableEntityComponent slot, float rotationValue, out vector angles, out bool freeRotation)
Definition: SCR_PreviewEntityEditorUIComponent.c:463