Exemple #1
0
        // 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(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]);
            }
        }