Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_JointBaseEntity.c
Go to the documentation of this file.
1 [EntityEditorProps(category: "GameBase/Joints", description: "Physics joint base", sizeMin: "-0.05 -0.05 -0.05", sizeMax: "0.05 0.05 0.05", color: "0 0 255 255")]
2 class SCR_JointBaseEntityClass: GenericEntityClass
3 {
4 };
5 
6 //------------------------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------------------------
12 {
13  [Attribute("-1", UIWidgets.ComboBox, "Snap joint to bone in parent (one-time)", "")]
14  int SNAP_TO_PARENT_BONE;
15  //[Attribute("-1", UIWidgets.ComboBox, "Snap child to joint by bone in child (one-time)", "")]
16  //int SNAP_CHILD_BY_JOINT;
17  [Attribute("1", UIWidgets.CheckBox, "Whether to create collision blocker between parent and child" )]
18  bool m_CollisionBlocker;
19 
20  IEntity m_JointParent = null;
21  IEntity m_JointChild = null;
22  SCR_JointDummyHolderEntity m_JointDummy = null;
23 
24  PhysicsJoint m_Joint = null;
25 
26  // TODO:
27  // - Do stress and breakage (in engine)
28  // - SNAP_CHILD_BY_JOINT does not work! After setting of the property, child is NULL!
29 
30  //------------------------------------------------------------------------------------------------
31  void MoveJointToParentBone()
32  {
33  if (!m_JointParent)
34  return;
35 
36  if (SNAP_TO_PARENT_BONE <= 0)
37  return;
38 
39  vector boneMat[4];
40 
41  m_JointParent.GetAnimation().GetBoneMatrix(SNAP_TO_PARENT_BONE, boneMat);
42 
43  vector angles = Math3D.MatrixToAngles(boneMat);
44  vector pos = boneMat[3];
45 
46  // TODO: Deselect or at least reselect joint after doing following steps
47  #ifdef WORKBENCH
48  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
49  worldEditorAPI.BeginEntityAction("Move to parent bone", "");
50  worldEditorAPI.ClearEntitySelection();
51 
52  IEntitySource src = _WB_GetEditorAPI().EntityToSource(this);
53  worldEditorAPI.SetVariableValue(src, null, "coords", pos.ToString(false));
54  worldEditorAPI.SetVariableValue(src, null, "angleX", angles[1].ToString());
55  worldEditorAPI.SetVariableValue(src, null, "angleY", angles[0].ToString());
56  worldEditorAPI.SetVariableValue(src, null, "angleZ", angles[2].ToString());
57  worldEditorAPI.SetVariableValue(src, null, "SNAP_TO_PARENT_BONE", "-1");
58  worldEditorAPI.EndEntityAction("Move to parent bone");
59  #endif
60  }
61 
62  //------------------------------------------------------------------------------------------------
63  /*void MoveChildToJointByBone()
64  {
65  Print(m_JointChild);
66  if (!m_JointChild)
67  return;
68 
69  if (SNAP_CHILD_BY_JOINT <= 0)
70  return;
71 
72  WorldEditorAPI worldEditorAPI = _WB_GetEditorAPI();
73 
74  // Special case (origin)
75  if (SNAP_CHILD_BY_JOINT == 999999)
76  {
77  // TODO: Deselect or at least reselect joint after doing following steps
78  worldEditorAPI.BeginEntityAction("Move child to joint by bone", "");
79  worldEditorAPI.ClearEntitySelection();
80  worldEditorAPI.SetVariableValue(m_JointChild, null, "coords", "0 0 0");
81  worldEditorAPI.SetVariableValue(m_JointChild, null, "angleX", "0");
82  worldEditorAPI.SetVariableValue(m_JointChild, null, "angleY", "0");
83  worldEditorAPI.SetVariableValue(m_JointChild, null, "angleZ", "0");
84  worldEditorAPI.SetVariableValue(this, null, "SNAP_CHILD_BY_JOINT", "-1");
85  worldEditorAPI.EndEntityAction("Move child to joint by bone");
86  }
87  else
88  {
89  vector boneMat[4], baseMat[4], endBoneMat[4];
90 
91  GetBoneMatrix(m_JointChild, SNAP_CHILD_BY_JOINT, boneMat);
92  Math3D.MatrixIdentity4(baseMat);
93  Math3D.MatrixInvMultiply4(baseMat, boneMat, endBoneMat);
94 
95 
96  vector angles = Math3D.MatrixToAngles(endBoneMat);
97  vector pos = endBoneMat[3];
98 
99  // TODO: Deselect or at least reselect joint after doing following steps
100  worldEditorAPI.BeginEntityAction("Move child to joint by bone", "");
101  worldEditorAPI.ClearEntitySelection();
102  worldEditorAPI.SetVariableValue(m_JointChild, null, "coords", pos.ToString(false));
103  worldEditorAPI.SetVariableValue(m_JointChild, null, "angleX", angles[1].ToString());
104  worldEditorAPI.SetVariableValue(m_JointChild, null, "angleY", angles[0].ToString());
105  worldEditorAPI.SetVariableValue(m_JointChild, null, "angleZ", angles[2].ToString());
106  worldEditorAPI.SetVariableValue(this, null, "SNAP_CHILD_BY_JOINT", "-1");
107  worldEditorAPI.EndEntityAction("Move child to joint by bone");
108  }
109  }*/
110 
111  //------------------------------------------------------------------------------------------------
112  #ifdef WORKBENCH
113  //------------------------------------------------------------------------------------------------
114  override array<ref ParamEnum> _WB_GetUserEnums(string varName, IEntitySource src)
115  {
116  if (varName == "SNAP_TO_PARENT_BONE" && m_JointParent)
117  return SCR_Global.GetBonesAsParamEnums(m_JointParent);
118  /*if (varName == "SNAP_CHILD_BY_JOINT" && m_JointChild)
119  {
120  array<ref ParamEnum> retEnums = SCR_Global.GetBonesAsParamEnums(m_JointChild);
121  retEnums.Insert(new ParamEnum("ORIGIN", "999999", "")); // Always have ORIGIN as an option
122  return retEnums;
123  }*/
124 
125  return null;
126  }
127 
128  //------------------------------------------------------------------------------------------------
129  override void _WB_AfterWorldUpdate(float timeSlice)
130  {
131  if (m_JointParent)
132  Shape.CreateArrow(m_JointParent.GetOrigin(), GetOrigin(), 0.05, ARGB(255, 128, 128, 0), ShapeFlags.ONCE|ShapeFlags.NOZBUFFER);
133  if (m_JointChild)
134  Shape.CreateArrow(GetOrigin(), m_JointChild.GetOrigin(), 0.05, ARGB(255, 128, 128, 0), ShapeFlags.ONCE|ShapeFlags.NOZBUFFER);
135  DebugDisplay();
136  }
137  #endif
138 
139  //------------------------------------------------------------------------------------------------
140  void DestroyJoint()
141  {
142  if (m_Joint)
143  {
144  // TODO: Remove this once deletion of joints is ensured before physics scene deletion
145  if (m_JointParent || m_JointChild)
146  m_Joint.Destroy();
147  }
148  m_Joint = null;
149 
150  if (m_JointDummy)
151  delete m_JointDummy;
152  m_JointDummy = null;
153  }
154 
155  //------------------------------------------------------------------------------------------------
156  void TryCreateJoint(bool showErrors)
157  {
158  DestroyJoint();
159 
160  if (!m_JointParent && !m_JointChild)
161  {
162  if (showErrors)
163  {
164  Print("JointHingeEntity::CreateJoint: ERROR - cannot create joint, no parent and no child!");
165  CreateFailedJointDebug(128, 255, 0, 0);
166  }
167  return;
168  }
169 
170  Physics parentPhysics = null;
171  Physics childPhysics = null;
172  if (m_JointParent)
173  parentPhysics = m_JointParent.GetPhysics();
174  if (m_JointChild)
175  childPhysics = m_JointChild.GetPhysics();
176  if (!parentPhysics && !childPhysics)
177  {
178  if (showErrors)
179  {
180  Print("JointHingeEntity::CreateJoint: ERROR - cannot create joint, neither parent nor child have physics!");
181  CreateFailedJointDebug(128, 255, 0, 0);
182  }
183  return;
184  }
185 
186  if (parentPhysics && childPhysics && !parentPhysics.IsDynamic() && !childPhysics.IsDynamic())
187  {
188  if (showErrors)
189  {
190  Print("JointHingeEntity::CreateJoint: ERROR - cannot create joint, neither parent nor child are dynamic!");
191  CreateFailedJointDebug(128, 255, 0, 0);
192  }
193  return;
194  }
195 
196  IEntity parent = m_JointParent;
197  IEntity child = m_JointChild;
198 
199  // Nullify parent
200  if (parent && parentPhysics && !parentPhysics.IsDynamic())
201  parent = null;
202  if (child && childPhysics && !childPhysics.IsDynamic())
203  child = null;
204 
205  if (showErrors && !parent && !child)
206  {
207  Print("JointHingeEntity::CreateJoint: ERROR - cannot create joint, no connected dynamic entities!");
208  CreateFailedJointDebug(128, 255, 128, 0);
209  }
210 
211  if (!parent || !child) // We have no parent or child, so create a dummy joint attachment point
212  {
214 
215  vector jointDummyMat[4];
216  GetTransform(jointDummyMat);
217  m_JointDummy.SetDummyTransform(jointDummyMat);
218 
219  float mass = 0;
220  if (parent)
221  mass = parentPhysics.GetMass();
222  else
223  mass = childPhysics.GetMass();
224 
225  m_JointDummy.GetPhysics().SetMass(mass * 1000);
226 
227 
228  // Link the static dummy point
229  if (parent)
230  child = m_JointDummy;
231  else
232  parent = m_JointDummy;
233  }
234 
235  // Ensure static entity is the child (must be 'ent2' for the API)
236  if (!parentPhysics || !parentPhysics.IsDynamic())
237  {
238  IEntity tmp = parent;
239  parent = child;
240  child = tmp;
241  }
242 
243  // First get matrices of parent, child and joint
244  vector parentMat[4], childMat[4], jointMat[4];
245  parent.GetTransform(parentMat);
246  child.GetTransform(childMat);
247  GetTransform(jointMat);
248 
249  // Rotate the joint if necessary (inout function)
250  RotateJoint(jointMat);
251 
252  // Now get local matrices of parent and child relative to joint
253  vector jointMatParentLocal[4], jointMatChildLocal[4];
254  Math3D.MatrixInvMultiply4(parentMat, jointMat, jointMatParentLocal);
255  Math3D.MatrixInvMultiply4(childMat, jointMat, jointMatChildLocal);
256 
257  // Subtract center of mass positions
258  if (parentPhysics)
259  jointMatParentLocal[3] = jointMatParentLocal[3] - parentPhysics.GetCenterOfMass();
260  else
261  jointMatParentLocal[3] = jointMatParentLocal[3];
262  if (childPhysics)
263  jointMatChildLocal[3] = jointMatChildLocal[3] - childPhysics.GetCenterOfMass();
264  else
265  jointMatChildLocal[3] = jointMatChildLocal[3];
266 
267  // Create the joint
268  CreateJoint(parent, child, jointMatParentLocal, jointMatChildLocal);
269  }
270 
271  //------------------------------------------------------------------------------------------------
272  void RotateJoint(inout vector jointMat[4])
273  {
274  }
275 
276  //------------------------------------------------------------------------------------------------
277  void CreateJoint(IEntity parent, IEntity child, vector jointMat1[4], vector jointMat2[4])
278  {
279  }
280 
281  //------------------------------------------------------------------------------------------------
282  void CreateFailedJointDebug(int a, int r, int g, int b)
283  {
284  int color = ARGB(a, r, g, b);
285  vector myPos = GetOrigin();
286  Shape.Create(ShapeType.BBOX, color, ShapeFlags.NOOUTLINE|ShapeFlags.NOZBUFFER|ShapeFlags.TRANSP, "-0.1 0.2 -0.1" + myPos, "0.1 1.2 0.1" + myPos);
287  Shape.Create(ShapeType.BBOX, color, ShapeFlags.NOOUTLINE|ShapeFlags.NOZBUFFER|ShapeFlags.TRANSP, "-0.1 -0.1 -0.1" + myPos, "0.1 0.1 0.1" + myPos);
288  }
289 
290  //------------------------------------------------------------------------------------------------
291  void DebugDisplay()
292  {
293  }
294 
295  //------------------------------------------------------------------------------------------------
296  override event void EOnInit(IEntity owner)
297  {
298  m_JointChild = GetChildren();
299 
300  TryCreateJoint(GetGame().GetGameStarted());
301 
302  MoveJointToParentBone();
303  //MoveChildToJointByBone();
304  }
305 
306  //------------------------------------------------------------------------------------------------
307  void SCR_JointBaseEntity(IEntitySource src, IEntity parent)
308  {
309  m_JointParent = parent;
310 
311  SetEventMask(EntityEvent.INIT);
312  }
313 
314  //------------------------------------------------------------------------------------------------
315  void ~SCR_JointBaseEntity()
316  {
317  DestroyJoint();
318  }
319 };
SpawnEntity
protected IEntity SpawnEntity(ResourceName entityResourceName, notnull IEntity slotOwner)
Definition: SCR_CatalogEntitySpawnerComponent.c:1008
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
GetGameStarted
bool GetGameStarted()
Definition: game.c:527
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
GetOrigin
vector GetOrigin()
Definition: SCR_AIUtilityComponent.c:279
SCR_JointBaseEntityClass
Definition: SCR_JointBaseEntity.c:2
Attribute
typedef Attribute
Post-process effect of scripted camera.
SCR_JointDummyHolderEntity
Definition: SCR_JointDummyHolderEntity.c:11
SCR_JointBaseEntity
Definition: SCR_JointBaseEntity.c:11
SCR_Global
Definition: Functions.c:6
GetChildren
void GetChildren(out array< SCR_ScenarioFrameworkLayerBase > children)
Definition: SCR_ScenarioFrameworkLayerBase.c:359
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180