1 #define ENABLE_BASE_DESTRUCTION
6 [
Attribute(
"", UIWidgets.Object,
"Initial damage phase data",
category:
"Destruction Multi-Phase")]
7 ref SCR_DamagePhaseData InitialData;
10 [
ComponentEditorProps(
category:
"GameScripted/Destruction", description:
"Tire destruction component, for destruction and deformation of tires")]
11 class SCR_DestructionTireComponentClass: SCR_DestructionMultiPhaseComponentClass
16 class SCR_DestructionTireComponent : SCR_DestructionMultiPhaseComponent
18 protected static const int MAX_BONES = 36;
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;
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;
30 [
Attribute(
"Tyre_", UIWidgets.EditBox,
"Name prefix (followed then by index) of the tire deformation joints",
category:
"Tire Destruction")]
31 protected string m_sTireJointNamePrefix;
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;
40 [
Attribute(
"1", UIWidgets.Slider,
"Ground deformation of the tire (in %)",
"0 1 0.01",
category:
"Tire Deformation Simple")]
41 protected float m_fGroundSlumpScale;
43 [
Attribute(
"1", UIWidgets.Slider,
"Radial deformation of the tire (in %)",
"0 1 0.01",
category:
"Tire Deformation Simple")]
44 protected float m_fRadiusScale;
46 [
Attribute(
"1", UIWidgets.Slider,
"Width deformation of the tire (in %)",
"0 1 0.01",
category:
"Tire Deformation Simple")]
47 protected float m_fTireWidthScale;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
87 protected VehicleWheeledSimulation m_VehicleWheeledSimulation;
88 protected VehicleWheeledSimulation_SA m_VehicleWheeledSimulation_SA;
90 protected int m_iWheelIndex = -1;
97 m_iWheelIndex = wheelIndex;
101 if (m_iWheelIndex > -1 && m_VehicleWheeledSimulation && m_iWheelIndex < m_VehicleWheeledSimulation.WheelCount())
102 m_fWheelRadius = m_VehicleWheeledSimulation.WheelGetRadius(m_iWheelIndex);
106 if (m_iWheelIndex > -1 && m_VehicleWheeledSimulation_SA && m_iWheelIndex < m_VehicleWheeledSimulation_SA.WheelCount())
107 m_fWheelRadius = m_VehicleWheeledSimulation_SA.WheelGetRadius(m_iWheelIndex);
114 bool GetShouldHandleDeformation(
int damagePhase)
116 return m_DeformPhaseIndexes && m_DeformPhaseIndexes.Find(damagePhase) != -1;
122 void EnableTireDeformation(
bool enable)
124 #ifdef ENABLE_DEFORMATION
125 m_bHandleDeformation = enable;
128 m_WheelBones.Clear();
129 if (!m_bHandleDeformation)
132 for (
int i = 0; i < MAX_BONES; i++)
134 int boneIndex =
GetOwner().GetAnimation().GetBoneIndex(m_sTireJointNamePrefix + i.ToString());
136 m_WheelBones.Insert(boneIndex);
140 protected float groundContactPct1 = 1;
143 override void OnFrame(IEntity owner,
float timeSlice)
145 super.OnFrame(owner, timeSlice);
147 if (!m_bHandleDeformation)
153 if (m_VehicleWheeledSimulation && m_fWheelRadius > 0)
155 float targetWheelRadius = (0.5 + m_fInflation * 0.5) * m_fWheelRadius;
156 if (targetWheelRadius != m_VehicleWheeledSimulation.WheelGetRadius(m_iWheelIndex))
158 m_VehicleWheeledSimulation.WheelSetRadiusState(m_iWheelIndex, targetWheelRadius);
160 Physics physics =
null;
161 IEntity parent = owner.GetParent();
164 physics = parent.GetPhysics();
165 if (physics && !physics.IsActive())
166 physics.SetActive(ActiveState.ACTIVE);
173 if (m_VehicleWheeledSimulation_SA && m_fWheelRadius > 0)
175 float targetWheelRadius = (0.5 + m_fInflation * 0.5) * m_fWheelRadius;
176 if (targetWheelRadius != m_VehicleWheeledSimulation_SA.WheelGetRadius(m_iWheelIndex))
178 m_VehicleWheeledSimulation_SA.WheelSetRadiusState(m_iWheelIndex, targetWheelRadius);
180 Physics physics =
null;
181 IEntity parent = owner.GetParent();
184 physics = parent.GetPhysics();
186 if (physics && !physics.IsActive())
187 physics.SetActive(ActiveState.ACTIVE);
194 vector floorNorm = vector.Up;
196 owner.GetTransform(wheelMat);
198 m_fInflation = Math.Clamp(timeSlice * -m_fDeflationRate + m_fInflation, 0, 1);
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;
211 vector boneMatLocal[4];
212 int numBones = m_WheelBones.Count();
213 for (
int i = 0; i < numBones; i++)
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);
224 float widthScale = 1;
225 widthScale += tyreBottom * deflationPct * m_fDeformParam_ScaleAdd_SquishWidthGround * m_fGroundSlumpScale * groundContactPct;
226 widthScale += tyreTop * deflationExpPct * m_fDeformParam_ScaleAdd_SquishWidthTop * m_fTireWidthScale * groundContactPct;
227 widthScale += deflationExpPct * m_fDeformParam_ScaleAdd_SquishWidthTop * m_fTireWidthScale * (1 - groundContactPct);
229 float heightOffset = 0;
230 heightOffset += boneTopDot * deflationExpPct2 * m_fDeformParam_Offset_FlattenTop * m_fRadiusScale * tyreTop;
231 heightOffset += boneTopDot * deflationExpPct * m_fDeformParam_Offset_GroundSlump * m_fGroundSlumpScale * (1 - tyreTop);
232 heightOffset += Math.Sin(tyreBottom * 180 * Math.DEG2RAD) * deflationPct * -m_fDeformParam_Offset_ExtrudeBottomOutward;
234 float squishHeightOffset = 0;
235 squishHeightOffset += tyreBottom * deflationPct * m_fDeformParam_Offset_ExtrudeBottomUpward * groundContactPct;
236 squishHeightOffset += tyreTop * deflationPct * m_fDeformParam_Offset_ExtrudeTopDownward * (1 - groundContactPct);
238 int sidePct = (i % 3);
239 float sideOffset = (-1 + (float)sidePct * 2) * deflationExpPct * m_fDeformParam_Offset_ExtrudeSidewardSkew * m_fTireSideSkewScale;
241 vector localBoneMat[4];
242 Math3D.MatrixIdentity4(localBoneMat);
244 localBoneMat[0] = vector.Right * widthScale;
245 localBoneMat[3] = vector.Forward * (heightOffset + squishHeightOffset) + vector.Right * sideOffset;
247 owner.GetAnimation().SetBoneMatrix(owner, boneIndex, localBoneMat);
254 void ReturnToInitialDamagePhase(SCR_DamagePhaseData pData)
256 if (GetDamagePhase() != 0)
259 if (GetTargetDamagePhase() != 0)
260 SetTargetDamagePhase(0);
262 ApplyDamagePhaseData(pData,
false);
271 if (damagePhase == 0)
272 ReturnToInitialDamagePhase(m_InitialData);
274 super.GoToDamagePhase(damagePhase, delayMeshChange);
276 EnableTireDeformation(GetShouldHandleDeformation(GetDamagePhase()));
284 super.OnPostInit(owner);
293 m_InitialData =
data.InitialData;
296 EnableTireDeformation(GetShouldHandleDeformation(GetDamagePhase()));
298 IEntity parent = owner.GetParent();
303 m_VehicleWheeledSimulation = VehicleWheeledSimulation.Cast(parent.FindComponent(VehicleWheeledSimulation));
305 m_VehicleWheeledSimulation_SA = VehicleWheeledSimulation_SA.Cast(parent.FindComponent(VehicleWheeledSimulation_SA));