// Runs collision behavior and updates cache private void ProcessCollisions(IEnumerable <ICollidableComponent> bodies) { _collisionCache.Clear(); var combinations = new HashSet <(EntityUid, EntityUid)>(); foreach (var aCollidable in bodies) { if (!aCollidable.Awake) { continue; } foreach (var b in _physicsManager.GetCollidingEntities(aCollidable, Vector2.Zero)) { var aUid = aCollidable.Entity.Uid; var bUid = b.Uid; if (bUid.CompareTo(aUid) > 0) { var tmpUid = bUid; bUid = aUid; aUid = tmpUid; } if (!combinations.Add((aUid, bUid))) { continue; } var bCollidable = b.GetComponent <ICollidableComponent>(); _collisionCache.Add(new Manifold(aCollidable, bCollidable, aCollidable.Hard && bCollidable.Hard)); } } var counter = 0; while (GetNextCollision(_collisionCache, counter, out var collision)) { collision.A.WakeBody(); collision.B.WakeBody(); counter++; var impulse = _physicsManager.SolveCollisionImpulse(collision); if (collision.A.CanMove()) { collision.A.Momentum -= impulse; } if (collision.B.CanMove()) { collision.B.Momentum += impulse; } } var collisionsWith = new Dictionary <ICollideBehavior, int>(); foreach (var collision in _collisionCache) { // Apply onCollide behavior var aBehaviors = collision.A.Entity.GetAllComponents <ICollideBehavior>(); foreach (var behavior in aBehaviors) { var entity = collision.B.Entity; if (entity.Deleted) { continue; } behavior.CollideWith(entity); if (collisionsWith.ContainsKey(behavior)) { collisionsWith[behavior] += 1; } else { collisionsWith[behavior] = 1; } } var bBehaviors = collision.B.Entity.GetAllComponents <ICollideBehavior>(); foreach (var behavior in bBehaviors) { var entity = collision.A.Entity; if (entity.Deleted) { continue; } behavior.CollideWith(entity); if (collisionsWith.ContainsKey(behavior)) { collisionsWith[behavior] += 1; } else { collisionsWith[behavior] = 1; } } } foreach (var behavior in collisionsWith.Keys) { behavior.PostCollide(collisionsWith[behavior]); } }
// Runs collision behavior and updates cache private void ProcessCollisions() { _collisionCache.Clear(); var collisionsWith = new Dictionary <ICollideBehavior, int>(); var physicsComponents = new Dictionary <ICollidableComponent, PhysicsComponent>(); foreach (var collision in FindCollisions(RelevantEntities, physicsComponents)) { _collisionCache.Add(collision); } var counter = 0; while (GetNextCollision(_collisionCache, counter, out var collision)) { counter++; var impulse = _physicsManager.SolveCollisionImpulse(collision); if (physicsComponents.ContainsKey(collision.A)) { physicsComponents[collision.A].Momentum -= impulse; } if (physicsComponents.ContainsKey(collision.B)) { physicsComponents[collision.B].Momentum += impulse; } } foreach (var collision in _collisionCache) { // Apply onCollide behavior var aBehaviors = (collision.A as CollidableComponent).Owner.GetAllComponents <ICollideBehavior>(); foreach (var behavior in aBehaviors) { var entity = (collision.B as CollidableComponent).Owner; if (entity.Deleted) { continue; } behavior.CollideWith(entity); if (collisionsWith.ContainsKey(behavior)) { collisionsWith[behavior] += 1; } else { collisionsWith[behavior] = 1; } } var bBehaviors = (collision.B as CollidableComponent).Owner.GetAllComponents <ICollideBehavior>(); foreach (var behavior in bBehaviors) { var entity = (collision.A as CollidableComponent).Owner; if (entity.Deleted) { continue; } behavior.CollideWith(entity); if (collisionsWith.ContainsKey(behavior)) { collisionsWith[behavior] += 1; } else { collisionsWith[behavior] = 1; } } } foreach (var behavior in collisionsWith.Keys) { behavior.PostCollide(collisionsWith[behavior]); } }
// Runs collision behavior and updates cache private void ProcessCollisions(IEnumerable <ICollidableComponent> bodies) { var collisionsWith = new Dictionary <ICollideBehavior, int>(); FindCollisions(bodies); var counter = 0; while (GetNextCollision(_collisionCache, counter, out var collision)) { counter++; var impulse = _physicsManager.SolveCollisionImpulse(collision); if (collision.A.CanMove()) { collision.A.Momentum -= impulse; } if (collision.B.CanMove()) { collision.B.Momentum += impulse; } } foreach (var collision in _collisionCache) { // Apply onCollide behavior var aBehaviors = collision.A.Entity.GetAllComponents <ICollideBehavior>(); foreach (var behavior in aBehaviors) { var entity = collision.B.Entity; if (entity.Deleted) { continue; } behavior.CollideWith(entity); if (collisionsWith.ContainsKey(behavior)) { collisionsWith[behavior] += 1; } else { collisionsWith[behavior] = 1; } } var bBehaviors = collision.B.Entity.GetAllComponents <ICollideBehavior>(); foreach (var behavior in bBehaviors) { var entity = collision.A.Entity; if (entity.Deleted) { continue; } behavior.CollideWith(entity); if (collisionsWith.ContainsKey(behavior)) { collisionsWith[behavior] += 1; } else { collisionsWith[behavior] = 1; } } } foreach (var behavior in collisionsWith.Keys) { behavior.PostCollide(collisionsWith[behavior]); } }
// Runs collision behavior and updates cache private void ProcessCollisions(IEnumerable <IPhysicsComponent> awakeBodies) { _collisionCache.Clear(); var combinations = new HashSet <(EntityUid, EntityUid)>(); foreach (var aPhysics in awakeBodies) { foreach (var b in _physicsManager.GetCollidingEntities(aPhysics, Vector2.Zero, false)) { var aUid = aPhysics.Entity.Uid; var bUid = b.Uid; if (bUid.CompareTo(aUid) > 0) { var tmpUid = bUid; bUid = aUid; aUid = tmpUid; } if (!combinations.Add((aUid, bUid))) { continue; } var bPhysics = b.GetComponent <IPhysicsComponent>(); _collisionCache.Add(new Manifold(aPhysics, bPhysics, aPhysics.Hard && bPhysics.Hard)); } } var counter = 0; while (GetNextCollision(_collisionCache, counter, out var collision)) { collision.A.WakeBody(); collision.B.WakeBody(); counter++; var impulse = _physicsManager.SolveCollisionImpulse(collision); if (collision.A.CanMove()) { collision.A.ApplyImpulse(-impulse); } if (collision.B.CanMove()) { collision.B.ApplyImpulse(impulse); } } var collisionsWith = new Dictionary <ICollideBehavior, int>(); foreach (var collision in _collisionCache) { // Apply onCollide behavior foreach (var behavior in collision.A.Entity.GetAllComponents <ICollideBehavior>().ToArray()) { var entity = collision.B.Entity; if (entity.Deleted) { break; } behavior.CollideWith(entity); if (collisionsWith.ContainsKey(behavior)) { collisionsWith[behavior] += 1; } else { collisionsWith[behavior] = 1; } } foreach (var behavior in collision.B.Entity.GetAllComponents <ICollideBehavior>().ToArray()) { var entity = collision.A.Entity; if (entity.Deleted) { break; } behavior.CollideWith(entity); if (collisionsWith.ContainsKey(behavior)) { collisionsWith[behavior] += 1; } else { collisionsWith[behavior] = 1; } } } foreach (var behavior in collisionsWith.Keys) { behavior.PostCollide(collisionsWith[behavior]); } }