Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
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")]
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
11class SCR_HybridPhysicsInfo
12{
13 float m_fMass;
14 ref array<int> m_aLayerMasks = new array<int>;
15}
16
17//------------------------------------------------------------------------------------------------
19class SCR_HybridPhysicsComponent : ScriptComponent
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
170 void ~SCR_HybridPhysicsComponent()
171 {
172 ClearPhysicsInfo();
173 }
174}
ref array< int > m_aLayerMasks
SCR_HybridPhysicsComponentClass m_fMass
Class for storing physics setup info for SCR_HybridPhysicsComponent.
enum EAIGroupCombatMode ComponentEditorProps(category:"GameScripted/AI", description:"Component for utility AI system for groups")
proto external int ClearEventMask(notnull IEntity owner, int mask)
proto external int SetEventMask(notnull IEntity owner, int mask)
proto external Physics GetPhysics()
proto external EntityFlags SetFlags(EntityFlags flags, bool recursively=false)
SCR_FieldOfViewSettings Attribute
EntityEvent
Various entity events.
Definition EntityEvent.c:14
EntityFlags
Various entity flags.
Definition EntityFlags.c:14