Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
HybridPhysicsComponent.c
Go to the documentation of this file.
1 [ComponentEditorProps(category: "GameScripted/Physics", description: "Component that automatically handles switching of between static and dynamic physics of the object")]
2 class SCR_HybridPhysicsComponentClass : ScriptComponentClass
3 {
4 }
5 
6 // TODO:
7 // - Consider implementing the functionality as an extended version of RigidBody component
8 // - Also need API to get damping, sleep thresholds etc
9 
11 class SCR_HybridPhysicsInfo
12 {
13  float m_fMass;
14  ref array<int> m_aLayerMasks = new array<int>;
15 }
16 
17 //------------------------------------------------------------------------------------------------
20 {
21  [Attribute("50", UIWidgets.EditBox, "How large a contact impulse must be to switch the object into dynamic physics")]
22  float m_fDynamicContactImpulse;
23 
24  private ref SCR_HybridPhysicsInfo m_HybridPhysicsInfo = null;
25 
26  //------------------------------------------------------------------------------------------------
28  private void ClearPhysicsInfo()
29  {
30  if (!m_HybridPhysicsInfo)
31  return;
32 
33  delete m_HybridPhysicsInfo;
34  m_HybridPhysicsInfo = null;
35  }
36 
37  //------------------------------------------------------------------------------------------------
40  private void StorePhysicsInfo(IEntity owner)
41  {
42  auto physics = owner.GetPhysics();
43  if (!physics)
44  return;
45 
46  ClearPhysicsInfo();
47 
48  m_HybridPhysicsInfo = new SCR_HybridPhysicsInfo;
49  m_HybridPhysicsInfo.m_fMass = physics.GetMass();
50 
51  int numGeoms = physics.GetNumGeoms();
52  for (int i = 0; i < numGeoms; i++)
53  {
54  m_HybridPhysicsInfo.m_aLayerMasks.Insert(physics.GetGeomInteractionLayer(i));
55  }
56 
57  physics.Destroy();
58  physics = Physics.CreateStatic(owner, -1);
59 
60  int numStoredGeoms = m_HybridPhysicsInfo.m_aLayerMasks.Count();
61  numGeoms = physics.GetNumGeoms();
62  for (int i = 0; i < numStoredGeoms; i++)
63  {
64  if (i >= numGeoms)
65  break;
66 
67  physics.SetGeomInteractionLayer(i, m_HybridPhysicsInfo.m_aLayerMasks.Get(i));
68  }
69  }
70 
71  //------------------------------------------------------------------------------------------------
74  private void ApplyPhysicsInfo(IEntity owner)
75  {
76  auto physics = owner.GetPhysics();
77  if (!physics)
78  {
79  ClearPhysicsInfo();
80  return;
81  }
82 
83  physics.Destroy();
84  physics = Physics.CreateDynamic(owner, m_HybridPhysicsInfo.m_fMass, -1);
85  int numStoredGeoms = m_HybridPhysicsInfo.m_aLayerMasks.Count();
86  int numGeoms = physics.GetNumGeoms();
87  for (int i = 0; i < numStoredGeoms; i++)
88  {
89  if (i >= numGeoms)
90  break;
91 
92  physics.SetGeomInteractionLayer(i, m_HybridPhysicsInfo.m_aLayerMasks.Get(i));
93  }
94 
95  ClearPhysicsInfo();
96  }
97 
98  //------------------------------------------------------------------------------------------------
99  override void EOnContact(IEntity owner, IEntity other, Contact contact)
100  {
101  // We got an impulse large enough to switch us to dynamic physics
102  if (contact.Impulse < m_fDynamicContactImpulse)
103  return;
104 
105  auto physics = owner.GetPhysics();
106  if (physics.IsDynamic())
107  return;
108 
109  // Clear the contact event (not needed anymore)
110  ClearEventMask(owner, EntityEvent.CONTACT);
111 
112  // Add the frame event (this is where we'll switch to dynamic physics)
113  SetEventMask(owner, EntityEvent.FRAME);
114  }
115 
116  //------------------------------------------------------------------------------------------------
117  override void EOnFrame(IEntity owner, float timeSlice)
118  {
119  // Dynamic but sleeping, so switch back to static
120  auto physics = owner.GetPhysics();
121  if (physics.IsDynamic() && !physics.IsActive())
122  {
123  StorePhysicsInfo(owner);
124  SetEventMask(owner, EntityEvent.CONTACT);
125  ClearEventMask(owner, EntityEvent.FRAME);
126  return;
127  }
128 
129  if (m_HybridPhysicsInfo)
130  ApplyPhysicsInfo(owner);
131  }
132 
133  //------------------------------------------------------------------------------------------------
134  override void OnPostInit(IEntity owner)
135  {
136  super.OnPostInit(owner);
137  SetEventMask(owner, EntityEvent.INIT);
138  owner.SetFlags(EntityFlags.ACTIVE);
139  }
140 
141  //------------------------------------------------------------------------------------------------
142  override void EOnInit(IEntity owner)
143  {
144  if (m_fDynamicContactImpulse <= 0)
145  return;
146 
147  auto physics = owner.GetPhysics();
148  if (!physics)
149  return;
150 
151  if (!physics.IsDynamic())
152  return;
153 
154  SetEventMask(owner, EntityEvent.CONTACT);
155 
156  StorePhysicsInfo(owner);
157  }
158 
159  //------------------------------------------------------------------------------------------------
160  // constructor
164  void SCR_HybridPhysicsComponent(IEntityComponentSource src, IEntity ent, IEntity parent)
165  {
166  }
167 
168  //------------------------------------------------------------------------------------------------
169  // destructor
171  {
172  ClearPhysicsInfo();
173  }
174 }
ComponentEditorProps
SCR_FragmentEntityClass ComponentEditorProps
ScriptComponent
SCR_SiteSlotEntityClass ScriptComponent
Attribute
typedef Attribute
Post-process effect of scripted camera.
SCR_HybridPhysicsComponent
Component that automatically handles switching of between static and dynamic physics of the object.
Definition: HybridPhysicsComponent.c:19
m_fMass
SCR_HybridPhysicsComponentClass m_fMass
Class for storing physics setup info for SCR_HybridPhysicsComponent.
m_aLayerMasks
ref array< int > m_aLayerMasks
Definition: HybridPhysicsComponent.c:14
SCR_HybridPhysicsComponentClass
Definition: HybridPhysicsComponent.c:2
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180