8 static ref array<ref Shape> m_aDebugShapes = {};
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;
17 protected float m_fLengthTraced;
19 protected ref ScriptInvoker<vector, IEntity> m_OnTraceFinished;
21 protected ref TraceParam m_TraceParam;
24 protected int m_iNextDebugColor = COLOR_RED;
27 protected const float DEFAULT_TRACE_SEGMENT_LENGTH = 100;
30 static void InitPhysicsHelper()
32 DiagMenu.RegisterMenu(
SCR_DebugMenuID.DEBUGUI_SCRIPTS_MENU,
"Scripts",
"Physics");
33 DiagMenu.RegisterBool(
SCR_DebugMenuID.DEBUGUI_SHOW_PHYSICS_HELPER_TRACE,
"",
"Show helper trace",
"Scripts");
39 static int RemapInteractionLayer(notnull Physics physicsObject, EPhysicsLayerDefs inputLayer, EPhysicsLayerDefs replaceLayer)
42 for (
int i = physicsObject.GetNumGeoms() - 1; i >= 0; i--)
44 int layerMask = physicsObject.GetGeomInteractionLayer(i);
45 if (!(layerMask & inputLayer))
48 layerMask &= ~inputLayer;
49 layerMask |= replaceLayer;
51 physicsObject.SetGeomInteractionLayer(i, layerMask);
60 private void TraceSegment(TraceFlags flags, EPhysicsLayerDefs layerMask, IEntity exclude,
float segmentSize)
62 m_fLengthTraced = m_fLengthTraced + segmentSize;
65 if (m_fLengthTraced > m_fLength)
66 m_TraceParam.End = m_vOriginalEnd;
68 m_TraceParam.End = m_vCurrentEndPosition;
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;
76 float traceResult =
GetGame().GetWorld().TraceMove(m_TraceParam,
null);
79 if (m_TraceParam.TraceEnt || traceResult == 1 && m_vOriginalEnd == m_TraceParam.End)
82 if (DiagMenu.GetBool(
SCR_DebugMenuID.DEBUGUI_SHOW_PHYSICS_HELPER_TRACE))
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));
89 vector traceHitPosition;
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);
98 if (DiagMenu.GetBool(
SCR_DebugMenuID.DEBUGUI_SHOW_PHYSICS_HELPER_TRACE))
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;
105 m_iNextDebugColor = COLOR_RED;
110 m_vCurrentStartPosition = m_TraceParam.End;
111 m_vCurrentStartPosition = m_TraceParam.End;
112 m_vCurrentEndPosition = m_vOriginalStart + (m_fLengthTraced + segmentSize) * m_vDirection;
120 void TraceSegmented(vector start, vector end, TraceFlags flags = TraceFlags.DEFAULT, EPhysicsLayerDefs layerMask = EPhysicsLayerDefs.Default, IEntity exclude =
null,
float segmentSize = DEFAULT_TRACE_SEGMENT_LENGTH)
123 m_vDirection = end - start;
124 m_fLength= m_vDirection.NormalizeSize();
126 m_TraceParam =
new TraceParam();
130 m_vOriginalEnd = end;
131 m_vOriginalStart = start;
133 if (m_fLength < segmentSize)
134 m_vCurrentEndPosition = end;
136 m_vCurrentEndPosition = start + m_vDirection * segmentSize;
138 m_vCurrentStartPosition = start;
141 GetGame().GetCallqueue().CallLater(TraceSegment, 0,
true, flags, layerMask, exclude, segmentSize);
145 ScriptInvoker GetOnTraceFinished()
147 if (!m_OnTraceFinished)
148 m_OnTraceFinished =
new ScriptInvoker();
150 return m_OnTraceFinished;
154 static void ChangeSimulationState(IEntity ent, SimulationState simState,
bool recursively =
false)
156 Physics physics = ent.GetPhysics();
158 physics.ChangeSimulationState(simState);
163 for (IEntity child = ent.GetChildren(); child; child = child.GetSibling())
165 ChangeSimulationState(child, simState, recursively);