Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_DestructionTireComponent.c
Go to the documentation of this file.
1 #define ENABLE_BASE_DESTRUCTION
2 
3 [ComponentEditorProps(category: "GameScripted")]
5 {
6  [Attribute("", UIWidgets.Object, "Initial damage phase data", category: "Destruction Multi-Phase")]
7  ref SCR_DamagePhaseData InitialData;
8 }
9 
10 [ComponentEditorProps(category: "GameScripted/Destruction", description: "Tire destruction component, for destruction and deformation of tires")]
11 class SCR_DestructionTireComponentClass: SCR_DestructionMultiPhaseComponentClass
12 {
13 }
14 
16 class SCR_DestructionTireComponent : SCR_DestructionMultiPhaseComponent
17 {
18  protected static const int MAX_BONES = 36;
19 
20  //
21  // Category: Tire Destruction
22  //
23 
24  [Attribute("", UIWidgets.EditBox, "List of phases in which the tire should handle deformation (this also means deflating)", category: "Tire Destruction")]
25  protected ref array<int> m_DeformPhaseIndexes;
26 
27  [Attribute("0.15", UIWidgets.Slider, "Rate at which the tire deflates when in a tire deformation damage phase (in %/s)", "0.01 1000 0.01", category: "Tire Destruction")]
28  protected float m_fDeflationRate;
29 
30  [Attribute("Tyre_", UIWidgets.EditBox, "Name prefix (followed then by index) of the tire deformation joints", category: "Tire Destruction")]
31  protected string m_sTireJointNamePrefix;
32 
33  [Attribute("1", UIWidgets.CheckBox, "If true, tire damage and destruction will affect vehicle physics (if attached to such)", category: "Tire Destruction")]
34  protected bool m_bAffectPhysics;
35 
36  //
37  // Category: Tire Deformation Simple
38  //
39 
40  [Attribute("1", UIWidgets.Slider, "Ground deformation of the tire (in %)", "0 1 0.01", category: "Tire Deformation Simple")]
41  protected float m_fGroundSlumpScale;
42 
43  [Attribute("1", UIWidgets.Slider, "Radial deformation of the tire (in %)", "0 1 0.01", category: "Tire Deformation Simple")]
44  protected float m_fRadiusScale;
45 
46  [Attribute("1", UIWidgets.Slider, "Width deformation of the tire (in %)", "0 1 0.01", category: "Tire Deformation Simple")]
47  protected float m_fTireWidthScale;
48 
49  [Attribute("1", UIWidgets.Slider, "Sideward skew deformation of the tire (in %)", "0 1 0.01", category: "Tire Deformation Simple")]
50  protected float m_fTireSideSkewScale;
51 
52  //
53  // Category: Tire Deformation Advanced
54  //
55 
56  [Attribute("0.75", UIWidgets.Slider, "Ground contact width scale addition (in %) - [Scaled by m_fGroundSlumpScale]", "-2 2 0.01", category: "Tire Deformation Advanced")]
57  protected float m_fDeformParam_ScaleAdd_SquishWidthGround;
58 
59  [Attribute("-0.3", UIWidgets.Slider, "Opposite to ground width scale addition (in %) - [Scaled by m_fTireWidthScale]", "-2 2 0.01", category: "Tire Deformation Advanced")]
60  protected float m_fDeformParam_ScaleAdd_SquishWidthTop;
61 
62  [Attribute("0.25", UIWidgets.Slider, "Flatten tire top offset (in m) - [Scaled by m_fRadiusScale]", "-10 10 0.01", category: "Tire Deformation Advanced")]
63  protected float m_fDeformParam_Offset_FlattenTop;
64 
65  [Attribute("0.25", UIWidgets.Slider, "Outward slump of tire on front/back of ground contact point (in m) - [Scaled by m_fGroundSlumpScale]", "-10 10 0.01", category: "Tire Deformation Advanced")]
66  protected float m_fDeformParam_Offset_GroundSlump;
67 
68  [Attribute("0.1", UIWidgets.Slider, "Outward extrusion near ground contact point (in m)", "-10 10 0.01", category: "Tire Deformation Advanced")]
69  protected float m_fDeformParam_Offset_ExtrudeBottomOutward;
70 
71  [Attribute("0.35", UIWidgets.Slider, "Upward extrusion near ground contact point (in m)", "-10 10 0.01", category: "Tire Deformation Advanced")]
72  protected float m_fDeformParam_Offset_ExtrudeBottomUpward;
73 
74  [Attribute("0.1", UIWidgets.Slider, "Downward extrusion of top opposite ground contact point (in m)", "-10 10 0.01", category: "Tire Deformation Advanced")]
75  protected float m_fDeformParam_Offset_ExtrudeTopDownward;
76 
77  [Attribute("0.01", UIWidgets.Slider, "Sideward skew extrusion all around the tire (in m) - [Scaled by m_fTireSideSkewScale]", "-10 10 0.01", category: "Tire Deformation Advanced")]
78  protected float m_fDeformParam_Offset_ExtrudeSidewardSkew;
79 
80 #ifdef ENABLE_BASE_DESTRUCTION
81  protected bool m_bHandleDeformation;
82  protected float m_fInflation = 1;
83  protected float m_fWheelRadius = -1;
84  protected ref array<int> m_WheelBones = {};
85  protected ref SCR_DamagePhaseData m_InitialData;
86 
87  protected VehicleWheeledSimulation m_VehicleWheeledSimulation;
88  protected VehicleWheeledSimulation_SA m_VehicleWheeledSimulation_SA;
89 
90  protected int m_iWheelIndex = -1;
91 
92  //------------------------------------------------------------------------------------------------
95  void SetWheelIndex(int wheelIndex)
96  {
97  m_iWheelIndex = wheelIndex;
98 
100  {
101  if (m_iWheelIndex > -1 && m_VehicleWheeledSimulation && m_iWheelIndex < m_VehicleWheeledSimulation.WheelCount())
102  m_fWheelRadius = m_VehicleWheeledSimulation.WheelGetRadius(m_iWheelIndex);
103  }
104  else
105  {
106  if (m_iWheelIndex > -1 && m_VehicleWheeledSimulation_SA && m_iWheelIndex < m_VehicleWheeledSimulation_SA.WheelCount())
107  m_fWheelRadius = m_VehicleWheeledSimulation_SA.WheelGetRadius(m_iWheelIndex);
108  }
109  }
110 
111  //------------------------------------------------------------------------------------------------
114  bool GetShouldHandleDeformation(int damagePhase)
115  {
116  return m_DeformPhaseIndexes && m_DeformPhaseIndexes.Find(damagePhase) != -1;
117  }
118 
119  //------------------------------------------------------------------------------------------------
122  void EnableTireDeformation(bool enable)
123  {
124 #ifdef ENABLE_DEFORMATION
125  m_bHandleDeformation = enable;
126 #endif
127 
128  m_WheelBones.Clear();
129  if (!m_bHandleDeformation)
130  return;
131 
132  for (int i = 0; i < MAX_BONES; i++)
133  {
134  int boneIndex = GetOwner().GetAnimation().GetBoneIndex(m_sTireJointNamePrefix + i.ToString());
135  if (boneIndex > -1)
136  m_WheelBones.Insert(boneIndex);
137  }
138  }
139 
140  protected float groundContactPct1 = 1;
141 
142  //------------------------------------------------------------------------------------------------
143  override void OnFrame(IEntity owner, float timeSlice)
144  {
145  super.OnFrame(owner, timeSlice);
146 
147  if (!m_bHandleDeformation)
148  return;
149 
150  // Update the physics wheel radius
152  {
153  if (m_VehicleWheeledSimulation && m_fWheelRadius > 0)
154  {
155  float targetWheelRadius = (0.5 + m_fInflation * 0.5) * m_fWheelRadius;
156  if (targetWheelRadius != m_VehicleWheeledSimulation.WheelGetRadius(m_iWheelIndex))
157  {
158  m_VehicleWheeledSimulation.WheelSetRadiusState(m_iWheelIndex, targetWheelRadius);
159 
160  Physics physics = null;
161  IEntity parent = owner.GetParent();
162  if (parent)
163  {
164  physics = parent.GetPhysics();
165  if (physics && !physics.IsActive())
166  physics.SetActive(ActiveState.ACTIVE);
167  }
168  }
169  }
170  }
171  else
172  {
173  if (m_VehicleWheeledSimulation_SA && m_fWheelRadius > 0)
174  {
175  float targetWheelRadius = (0.5 + m_fInflation * 0.5) * m_fWheelRadius;
176  if (targetWheelRadius != m_VehicleWheeledSimulation_SA.WheelGetRadius(m_iWheelIndex))
177  {
178  m_VehicleWheeledSimulation_SA.WheelSetRadiusState(m_iWheelIndex, targetWheelRadius);
179 
180  Physics physics = null;
181  IEntity parent = owner.GetParent();
182  if (parent)
183  {
184  physics = parent.GetPhysics();
185 
186  if (physics && !physics.IsActive())
187  physics.SetActive(ActiveState.ACTIVE);
188  }
189  }
190  }
191  }
192 
193  // Handle deformation and deflation of the tire
194  vector floorNorm = vector.Up;
195  vector wheelMat[4];
196  owner.GetTransform(wheelMat);
197 
198  m_fInflation = Math.Clamp(timeSlice * -m_fDeflationRate + m_fInflation, 0, 1);
199 
200  float deflationPct = 1 - Math.Pow(1 - Math.Clamp((1 - m_fInflation) * 2, 0, 1), 1.5);
201  float deflationExpPct = (1 - Math.Clamp(m_fInflation * 1.7, 0, 1));
202  deflationExpPct += (1 - deflationExpPct) * deflationExpPct;
203  deflationExpPct *= deflationExpPct;
204  float deflationExpPct2 = (1 - Math.Clamp(m_fInflation * 1.1, 0, 1));
205  deflationExpPct2 += (1 - deflationExpPct2) * deflationExpPct2;
206  deflationExpPct2 *= deflationExpPct2;
207  groundContactPct1 = Math.Clamp(groundContactPct1 + (Debug.KeyState(KeyCode.KC_RIGHT) - Debug.KeyState(KeyCode.KC_LEFT)) * timeSlice, 0, 1);
208  float groundContactPct = groundContactPct1;
209 
210  // Apply deformation
211  vector boneMatLocal[4];
212  int numBones = m_WheelBones.Count();
213  for (int i = 0; i < numBones; i++)
214  {
215  int boneIndex = m_WheelBones.Get(i);
216  owner.GetAnimation().GetBoneMatrix(boneIndex, boneMatLocal);
217  vector boneUp = boneMatLocal[2].Normalized();
218  boneUp = boneUp.Multiply3(wheelMat);
219  float boneFloorDot = Math.Clamp(floorNorm * boneUp, 0, 1);
220  float boneTopDot = 1 - boneFloorDot;
221  float tyreBottom = Math.Pow(boneFloorDot, 2);
222  float tyreTop = Math.Pow(boneTopDot, 2);
223 
224  float widthScale = 1;
225  widthScale += tyreBottom * deflationPct * m_fDeformParam_ScaleAdd_SquishWidthGround * m_fGroundSlumpScale * groundContactPct; // Squish out the tyre at the floor
226  widthScale += tyreTop * deflationExpPct * m_fDeformParam_ScaleAdd_SquishWidthTop * m_fTireWidthScale * groundContactPct; // Thin out the tyre above
227  widthScale += deflationExpPct * m_fDeformParam_ScaleAdd_SquishWidthTop * m_fTireWidthScale * (1 - groundContactPct); // Thin out the tyre above
228 
229  float heightOffset = 0;
230  heightOffset += boneTopDot * deflationExpPct2 * m_fDeformParam_Offset_FlattenTop * m_fRadiusScale * tyreTop; // Flatten top of the tyre
231  heightOffset += boneTopDot * deflationExpPct * m_fDeformParam_Offset_GroundSlump * m_fGroundSlumpScale * (1 - tyreTop); // Flatten all but bottom and top of the tyre
232  heightOffset += Math.Sin(tyreBottom * 180 * Math.DEG2RAD) * deflationPct * -m_fDeformParam_Offset_ExtrudeBottomOutward; // Offset bottom-sides outward
233 
234  float squishHeightOffset = 0;
235  squishHeightOffset += tyreBottom * deflationPct * m_fDeformParam_Offset_ExtrudeBottomUpward * groundContactPct; // Offset bottom upward
236  squishHeightOffset += tyreTop * deflationPct * m_fDeformParam_Offset_ExtrudeTopDownward * (1 - groundContactPct); // Offset top downward
237 
238  int sidePct = (i % 3);
239  float sideOffset = (-1 + (float)sidePct * 2) * deflationExpPct * m_fDeformParam_Offset_ExtrudeSidewardSkew * m_fTireSideSkewScale; // Offset based on joint num
240 
241  vector localBoneMat[4];
242  Math3D.MatrixIdentity4(localBoneMat);
243 
244  localBoneMat[0] = vector.Right * widthScale;
245  localBoneMat[3] = vector.Forward * (heightOffset + squishHeightOffset) + vector.Right * sideOffset;
246 
247  owner.GetAnimation().SetBoneMatrix(owner, boneIndex, localBoneMat);
248  }
249  }
250 
251  //------------------------------------------------------------------------------------------------
254  void ReturnToInitialDamagePhase(SCR_DamagePhaseData pData)
255  {
256  if (GetDamagePhase() != 0)
257  SetDamagePhase(0);
258 
259  if (GetTargetDamagePhase() != 0)
260  SetTargetDamagePhase(0);
261 
262  ApplyDamagePhaseData(pData, false);
263  }
264 
265  //------------------------------------------------------------------------------------------------
269  override void GoToDamagePhase(int damagePhase, bool delayMeshChange)
270  {
271  if (damagePhase == 0)
272  ReturnToInitialDamagePhase(m_InitialData);
273  else
274  super.GoToDamagePhase(damagePhase, delayMeshChange);
275 
276  EnableTireDeformation(GetShouldHandleDeformation(GetDamagePhase()));
277 // if (m_bHandleDeformation)
278 // EnableOnFrame(true);
279  }
280 
281  //------------------------------------------------------------------------------------------------
282  override void OnPostInit(IEntity owner)
283  {
284  super.OnPostInit(owner);
285  if (!owner)
286  return;
287 
288  EntityComponentPrefabData prefabData = owner.FindComponentData(SCR_DestructionTireInitialDamageDataComponentClass);
289  if (prefabData)
290  {
292  if (data)
293  m_InitialData = data.InitialData;
294  }
295 
296  EnableTireDeformation(GetShouldHandleDeformation(GetDamagePhase()));
297 
298  IEntity parent = owner.GetParent();
299 
300  if (parent)
301  {
303  m_VehicleWheeledSimulation = VehicleWheeledSimulation.Cast(parent.FindComponent(VehicleWheeledSimulation));
304  else
305  m_VehicleWheeledSimulation_SA = VehicleWheeledSimulation_SA.Cast(parent.FindComponent(VehicleWheeledSimulation_SA));
306 
307  }
308  }
309 #endif
310 }
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
SCR_DestructionTireInitialDamageDataComponentClass
Definition: SCR_DestructionTireComponent.c:4
OnFrame
event protected void OnFrame(IEntity owner, float timeSlice)
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
GoToDamagePhase
protected void GoToDamagePhase(int damagePhaseIndex, int previousDamagePhaseIndex, SCR_DestructionData destructionData, bool streamed)
Only call from OnStateChanged, otherwise you have HUGE desync.
Definition: SCR_DestructibleEntity.c:221
GetIsClientAuthority
override bool GetIsClientAuthority()
Definition: game.c:268
Attribute
typedef Attribute
Post-process effect of scripted camera.
OnPostInit
override void OnPostInit(IEntity owner)
Called on PostInit when all components are added.
Definition: SCR_AIConfigComponent.c:72
GetOwner
IEntity GetOwner()
Owner entity of the fuel tank.
Definition: SCR_FuelNode.c:128
data
Get all prefabs that have the spawner data
Definition: SCR_EntityCatalogManagerComponent.c:305
SetWheelIndex
void SetWheelIndex(int index)
Definition: SCR_WheelHitZone.c:74
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180