TrueSync: PhysicsWorldManager.cs Source File

TrueSync

PhysicsWorldManager.cs
1 using UnityEngine;
2 using System.Collections.Generic;
3 using System;
4 using TrueSync.Physics3D;
5 
6 namespace TrueSync {
7 
11  public class PhysicsWorldManager : IPhysicsManager {
12 
13  public static PhysicsWorldManager instance;
14 
15  private World world;
16 
17  Dictionary<IBody, GameObject> gameObjectMap;
18 
19  Dictionary<RigidBody, Dictionary<RigidBody, TSCollision>> collisionInfo;
20 
24  public TSVector Gravity {
25  get;
26  set;
27  }
28 
32  public bool SpeculativeContacts {
33  get;
34  set;
35  }
36 
37  public FP LockedTimeStep {
38  get;
39  set;
40  }
41 
42  // Use this for initialization
43  public void Init() {
44  ChecksumExtractor.Init(this);
45 
46  gameObjectMap = new Dictionary<IBody, GameObject>();
47  collisionInfo = new Dictionary<RigidBody, Dictionary<RigidBody, TSCollision>>();
48 
49  CollisionSystemPersistentSAP collisionSystem = new CollisionSystemPersistentSAP();
50  collisionSystem.EnableSpeculativeContacts = SpeculativeContacts;
51 
52  world = new World(collisionSystem);
53  collisionSystem.world = world;
54 
55  world.physicsManager = this;
56  world.Gravity = Gravity;
57 
58  world.Events.BodiesBeginCollide += CollisionEnter;
59  world.Events.BodiesStayCollide += CollisionStay;
60  world.Events.BodiesEndCollide += CollisionExit;
61 
62  world.Events.TriggerBeginCollide += TriggerEnter;
63  world.Events.TriggerStayCollide += TriggerStay;
64  world.Events.TriggerEndCollide += TriggerExit;
65 
66  world.Events.RemovedRigidBody += OnRemovedRigidBody;
67 
68  instance = this;
69 
70  AddRigidBodies();
71  }
72 
76  public void UpdateStep() {
77  world.Step(LockedTimeStep);
78  }
79 
83  public IWorld GetWorld() {
84  return world;
85  }
86 
87  void AddRigidBodies() {
88  TSCollider[] bodies = GameObject.FindObjectsOfType<TSCollider>();
89  List<TSCollider> sortedBodies = new List<TSCollider>(bodies);
90  sortedBodies.Sort(UnityUtils.bodyComparer);
91 
92  for (int i = 0; i < sortedBodies.Count; i++) {
93  AddBody(sortedBodies[i]);
94  }
95  }
96 
102  public void AddBody(ICollider iCollider) {
103  if (!(iCollider is TSCollider)) {
104  Debug.LogError("You have a 2D object but your Physics 2D is disabled.");
105  return;
106  }
107 
108  TSCollider tsCollider = (TSCollider) iCollider;
109 
110  if (tsCollider._body != null) {
111  //already added
112  return;
113  }
114 
115  TSRigidBody tsRB = tsCollider.GetComponent<TSRigidBody>();
116  TSRigidBodyConstraints constraints = tsRB != null ? tsRB.constraints : TSRigidBodyConstraints.None;
117 
118  tsCollider.Initialize();
119  world.AddBody(tsCollider._body);
120  gameObjectMap[tsCollider._body] = tsCollider.gameObject;
121 
122  if (tsCollider.gameObject.transform.parent != null && tsCollider.gameObject.transform.parent.GetComponentInParent<TSCollider>() != null) {
123  TSCollider parentCollider = tsCollider.gameObject.transform.parent.GetComponentInParent<TSCollider>();
124  world.AddConstraint(new ConstraintHierarchy(parentCollider.Body, tsCollider._body, (tsCollider.GetComponent<TSTransform>().position + tsCollider.ScaledCenter) - (parentCollider.GetComponent<TSTransform>().position + parentCollider.ScaledCenter)));
125  }
126 
127  tsCollider._body.FreezeConstraints = constraints;
128  }
129 
130  public void RemoveBody(IBody iBody) {
131  world.RemoveBody((RigidBody) iBody);
132  }
133 
134  public void OnRemoveBody(System.Action<IBody> OnRemoveBody){
135  world.Events.RemovedRigidBody += delegate (RigidBody rb) {
136  OnRemoveBody(rb);
137  };
138  }
139 
140  public bool Raycast(TSVector rayOrigin, TSVector rayDirection, RaycastCallback raycast, out IBody body, out TSVector normal, out FP fraction) {
141  RigidBody rb;
142  bool result = world.CollisionSystem.Raycast(rayOrigin, rayDirection, raycast, out rb, out normal, out fraction);
143  body = rb;
144 
145  return result;
146  }
147 
148  public TSRaycastHit Raycast(TSRay ray, FP maxDistance, RaycastCallback callback = null) {
149  IBody hitBody;
150  TSVector hitNormal;
151  FP hitFraction;
152 
153  TSVector origin = ray.origin;
154  TSVector direction = ray.direction;
155 
156  if (Raycast(origin, direction, callback, out hitBody, out hitNormal, out hitFraction)) {
157  if (hitFraction <= maxDistance) {
158  GameObject other = PhysicsManager.instance.GetGameObject(hitBody);
159  TSRigidBody bodyComponent = other.GetComponent<TSRigidBody>();
160  TSCollider colliderComponent = other.GetComponent<TSCollider>();
161  TSTransform transformComponent = other.GetComponent<TSTransform>();
162  return new TSRaycastHit(bodyComponent, colliderComponent, transformComponent, hitNormal, ray.origin, ray.direction, hitFraction);
163  }
164  } else {
165  direction *= maxDistance;
166  if (Raycast(origin, direction, callback, out hitBody, out hitNormal, out hitFraction)) {
167  GameObject other = PhysicsManager.instance.GetGameObject(hitBody);
168  TSRigidBody bodyComponent = other.GetComponent<TSRigidBody>();
169  TSCollider colliderComponent = other.GetComponent<TSCollider>();
170  TSTransform transformComponent = other.GetComponent<TSTransform>();
171  return new TSRaycastHit(bodyComponent, colliderComponent, transformComponent, hitNormal, ray.origin, direction, hitFraction);
172  }
173  }
174  return null;
175  }
176 
177  private void OnRemovedRigidBody(RigidBody body) {
178  GameObject go = gameObjectMap[body];
179 
180  if (go != null) {
181  GameObject.Destroy(go);
182  }
183  }
184 
185  private void CollisionEnter(Contact c) {
186  CollisionDetected(c.body1, c.body2, c, "OnSyncedCollisionEnter");
187  }
188 
189  private void CollisionStay(Contact c) {
190  CollisionDetected(c.body1, c.body2, c, "OnSyncedCollisionStay");
191  }
192 
193  private void CollisionExit(RigidBody body1, RigidBody body2) {
194  CollisionDetected(body1, body2, null, "OnSyncedCollisionExit");
195  }
196 
197  private void TriggerEnter(Contact c) {
198  CollisionDetected(c.body1, c.body2, c, "OnSyncedTriggerEnter");
199  }
200 
201  private void TriggerStay(Contact c) {
202  CollisionDetected(c.body1, c.body2, c, "OnSyncedTriggerStay");
203  }
204 
205  private void TriggerExit(RigidBody body1, RigidBody body2) {
206  CollisionDetected(body1, body2, null, "OnSyncedTriggerExit");
207  }
208 
209  private void CollisionDetected(RigidBody body1, RigidBody body2, Contact c, string callbackName) {
210  if (!gameObjectMap.ContainsKey(body1) || !gameObjectMap.ContainsKey(body2)) {
211  return;
212  }
213 
214  GameObject b1 = gameObjectMap[body1];
215  GameObject b2 = gameObjectMap[body2];
216 
217  if (b1 == null || b2 == null) {
218  return;
219  }
220 
221  b1.SendMessage(callbackName, GetCollisionInfo(body1, body2, c), SendMessageOptions.DontRequireReceiver);
222  b2.SendMessage(callbackName, GetCollisionInfo(body2, body1, c), SendMessageOptions.DontRequireReceiver);
223 
225  }
226 
227  private TSCollision GetCollisionInfo(RigidBody body1, RigidBody body2, Contact c) {
228  if (!collisionInfo.ContainsKey(body1)) {
229  collisionInfo.Add(body1, new Dictionary<RigidBody, TSCollision>());
230  }
231 
232  Dictionary<RigidBody, TSCollision> collisionInfoBody1 = collisionInfo[body1];
233 
234  TSCollision result = null;
235 
236  if (collisionInfoBody1.ContainsKey(body2)) {
237  result = collisionInfoBody1[body2];
238  } else {
239  result = new TSCollision();
240  collisionInfoBody1.Add(body2, result);
241  }
242 
243 
244  result.Update(gameObjectMap[body2], c);
245 
246  return result;
247  }
248 
254  public GameObject GetGameObject(IBody rigidBody) {
255  if (!gameObjectMap.ContainsKey(rigidBody)) {
256  return null;
257  }
258 
259  return gameObjectMap[rigidBody];
260  }
261 
262  public int GetBodyLayer(IBody body) {
263  GameObject go = GetGameObject(body);
264  if (go == null) {
265  return -1;
266  }
267 
268  return go.layer;
269  }
270 
277  public bool IsCollisionEnabled(IBody rigidBody1, IBody rigidBody2) {
278  return LayerCollisionMatrix.CollisionEnabled(gameObjectMap[rigidBody1], gameObjectMap[rigidBody2]);
279  }
280 
281  public IWorldClone GetWorldClone() {
282  return new WorldClone();
283  }
284 
285  }
286 
287 }
Manages the collision matrix of physics simulation.
Manages creation of player prefabs and lockstep execution.
Represents few information about a raycast hit.
Definition: TSRaycastHit.cs:9
TSVector Gravity
Property access to simulated gravity.
static void UpdateCoroutines()
Update all coroutines created.
Provides a few utilities to be used on TrueSync exposed classes.
Definition: UnityUtils.cs:10
IWorld GetWorld()
Instance of the current simulated world.
bool IsCollisionEnabled(IBody rigidBody1, IBody rigidBody2)
Check if the collision between two RigidBodies is enabled.
Represents a physical 3D rigid body.
Definition: TSRigidBody.cs:12
A deterministic version of Unity&#39;s Transform component for 3D physics.
Definition: TSTransform.cs:9
static IPhysicsManager instance
Returns a proper implementation of IPhysicsManager.
Manages the 3D physics simulation.
Abstract collider for 3D shapes.
Definition: TSCollider.cs:13
TSVector ScaledCenter
Returns a version of collider&#39;s center scaled by parent&#39;s transform.
Definition: TSCollider.cs:80
TSRigidBodyConstraints constraints
Freeze constraints applied to this body.
Definition: TSRigidBody.cs:149
GameObject GetGameObject(IBody rigidBody)
Get the GameObject related to a specific RigidBody.
static bool CollisionEnabled(int layerA, int layerB)
Returns true if the given layers can collide.
TSVector position
Property access to position.
Definition: TSTransform.cs:23
Represents a ray with origin and direction.
Definition: TSRay.cs:7
void Initialize()
Initializes Shape and RigidBody and sets initial values to position and orientation based on Unity&#39;s ...
Definition: TSCollider.cs:194
Manages physics simulation.
IBody3D Body
Returns the body linked to this collider.
Definition: TSCollider.cs:114
static TSBodyComparer bodyComparer
Instance of a TSBodyComparer.
Definition: UnityUtils.cs:53
Represents information about a contact between two 3D bodies.
Definition: TSCollision.cs:26
bool SpeculativeContacts
Property access to speculative contacts.
Represents a common interface to 2D and 3D bodies.
Definition: IBody.cs:6
void AddBody(ICollider iCollider)
Add a new RigidBody to the world.
void UpdateStep()
Goes one step further on the physics simulation.
Generated by   doxygen 1.8.11