Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_PhysicsHelper.c
Go to the documentation of this file.
1 //------------------------------------------------------------------------------------------------
5 //------------------------------------------------------------------------------------------------
7 {
8  static ref array<ref Shape> m_aDebugShapes = {};
9 
10  protected vector m_vCurrentStartPosition;
11  protected vector m_vCurrentEndPosition;
12  protected vector m_vOriginalEnd;
13  protected vector m_vOriginalStart;
14  protected vector m_vDirection;
15  protected float m_fLength;
16 
17  protected float m_fLengthTraced;
18 
19  protected ref ScriptInvoker<vector, IEntity> m_OnTraceFinished;
20 
21  protected ref TraceParam m_TraceParam;
22 
23 #ifdef ENABLE_DIAG
24  protected int m_iNextDebugColor = COLOR_RED;
25 #endif
26 
27  protected const float DEFAULT_TRACE_SEGMENT_LENGTH = 100; //default length of the split-traces
28 
29  //------------------------------------------------------------------------------------------------
30  static void InitPhysicsHelper()
31  {
32  DiagMenu.RegisterMenu(SCR_DebugMenuID.DEBUGUI_SCRIPTS_MENU, "Scripts", "Physics");
33  DiagMenu.RegisterBool(SCR_DebugMenuID.DEBUGUI_SHOW_PHYSICS_HELPER_TRACE, "", "Show helper trace", "Scripts");
34  }
35 
36  //------------------------------------------------------------------------------------------------
39  static int RemapInteractionLayer(notnull Physics physicsObject, EPhysicsLayerDefs inputLayer, EPhysicsLayerDefs replaceLayer)
40  {
41  int numRemapped = 0;
42  for (int i = physicsObject.GetNumGeoms() - 1; i >= 0; i--)
43  {
44  int layerMask = physicsObject.GetGeomInteractionLayer(i);
45  if (!(layerMask & inputLayer))
46  continue;
47 
48  layerMask &= ~inputLayer; // Remove input layer
49  layerMask |= replaceLayer; // Add replace layer
50 
51  physicsObject.SetGeomInteractionLayer(i, layerMask);
52  numRemapped++;
53  }
54 
55  return numRemapped;
56  }
57 
58  //------------------------------------------------------------------------------------------------
60  private void TraceSegment(TraceFlags flags, EPhysicsLayerDefs layerMask, IEntity exclude, float segmentSize)
61  {
62  m_fLengthTraced = m_fLengthTraced + segmentSize;
63 
64  //if this segment of trace would go over complete traced length we use the original
65  if (m_fLengthTraced > m_fLength)
66  m_TraceParam.End = m_vOriginalEnd;
67  else
68  m_TraceParam.End = m_vCurrentEndPosition;
69 
70  m_TraceParam.Start = m_vCurrentStartPosition;
71  m_TraceParam.Flags = flags;
72  m_TraceParam.LayerMask = layerMask;
73  m_TraceParam.Exclude = exclude;
74  m_TraceParam.TraceEnt = null;
75 
76  float traceResult = GetGame().GetWorld().TraceMove(m_TraceParam, null);
77 
78  //m_TraceParam.TraceEnt is filled if the trace hit, otherwise we check if we are at the end of trace
79  if (m_TraceParam.TraceEnt || traceResult == 1 && m_vOriginalEnd == m_TraceParam.End)
80  {
81 #ifdef ENABLE_DIAG
82  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SHOW_PHYSICS_HELPER_TRACE))
83  {
84  float distance = traceResult * (m_TraceParam.End - m_TraceParam.Start).Length();
85  m_aDebugShapes.Insert(Shape.CreateArrow(m_TraceParam.Start, distance * m_vDirection + m_TraceParam.Start , 0.3, COLOR_YELLOW, ShapeFlags.DEFAULT));
86  }
87 #endif
88 
89  vector traceHitPosition;
90  //calculate the position of the hit
91  traceHitPosition = m_TraceParam.Start + m_vDirection * (m_TraceParam.End - m_TraceParam.Start).Length() * traceResult;
92  m_OnTraceFinished.Invoke(traceHitPosition, m_TraceParam.TraceEnt);
93  GetGame().GetCallqueue().Remove(TraceSegment);
94  return;
95  }
96 
97 #ifdef ENABLE_DIAG
98  if (DiagMenu.GetBool(SCR_DebugMenuID.DEBUGUI_SHOW_PHYSICS_HELPER_TRACE))
99  {
100  float distance = traceResult * (m_TraceParam.End - m_TraceParam.Start).Length();
101  m_aDebugShapes.Insert(Shape.CreateArrow(m_TraceParam.Start, distance * m_vDirection + m_TraceParam.Start , 0.3, m_iNextDebugColor, ShapeFlags.DEFAULT));
102  if (m_iNextDebugColor == COLOR_RED)
103  m_iNextDebugColor = COLOR_GREEN;
104  else
105  m_iNextDebugColor = COLOR_RED;
106  }
107 #endif
108 
109  //update vectors for the next segment to be traced
110  m_vCurrentStartPosition = m_TraceParam.End;
111  m_vCurrentStartPosition = m_TraceParam.End;
112  m_vCurrentEndPosition = m_vOriginalStart + (m_fLengthTraced + segmentSize) * m_vDirection;
113  return;
114  }
115 
116  //------------------------------------------------------------------------------------------------
120  void TraceSegmented(vector start, vector end, TraceFlags flags = TraceFlags.DEFAULT, EPhysicsLayerDefs layerMask = EPhysicsLayerDefs.Default, IEntity exclude = null, float segmentSize = DEFAULT_TRACE_SEGMENT_LENGTH)
121  {
122  //calculate and save direction and length there, so we do not have to recalculate it every frame while tracing
123  m_vDirection = end - start;
124  m_fLength= m_vDirection.NormalizeSize();
125 
126  m_TraceParam = new TraceParam();
127 
128  m_fLengthTraced = 0;
129 
130  m_vOriginalEnd = end;
131  m_vOriginalStart = start;
132 
133  if (m_fLength < segmentSize)
134  m_vCurrentEndPosition = end;
135  else
136  m_vCurrentEndPosition = start + m_vDirection * segmentSize;
137 
138  m_vCurrentStartPosition = start;
139 
140  //Call this method every frame to trace segment of the whole length each frame, when the trace is done the method removes itself from the queue
141  GetGame().GetCallqueue().CallLater(TraceSegment, 0, true, flags, layerMask, exclude, segmentSize);
142  }
143 
144  //------------------------------------------------------------------------------------------------
145  ScriptInvoker GetOnTraceFinished()
146  {
147  if (!m_OnTraceFinished)
148  m_OnTraceFinished = new ScriptInvoker();
149 
150  return m_OnTraceFinished;
151  }
152 
153  //------------------------------------------------------------------------------------------------
154  static void ChangeSimulationState(IEntity ent, SimulationState simState, bool recursively = false)
155  {
156  Physics physics = ent.GetPhysics();
157  if (physics)
158  physics.ChangeSimulationState(simState);
159 
160  if (!recursively)
161  return;
162 
163  for (IEntity child = ent.GetChildren(); child; child = child.GetSibling())
164  {
165  ChangeSimulationState(child, simState, recursively);
166  }
167  }
168 
169 };
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
distance
float distance
Definition: SCR_DestructibleTreeV2.c:29
SCR_PhysicsHelper
Definition: SCR_PhysicsHelper.c:6
m_aDebugShapes
protected ref array< ref Shape > m_aDebugShapes
Definition: SCR_PowerlineGeneratorEntity.c:64
SCR_DebugMenuID
SCR_DebugMenuID
This enum contains all IDs for DiagMenu entries added in script.
Definition: DebugMenuID.c:3