Example #1
0
        /// <summary>
        /// caculates the movement modifying the motion vector to take into account any collisions that will
        /// occur when moving
        /// </summary>
        /// <returns><c>true</c>, if movement was calculated, <c>false</c> otherwise.</returns>
        /// <param name="motion">Motion.</param>
        /// <param name="collisionResult">Collision result.</param>
        public bool CalculateMovement(ref System.Numerics.Vector2 motion, out CollisionResult collisionResult)
        {
            collisionResult = new CollisionResult();

            // no collider? just move and forget about it
            if (Entity.GetComponent <Collider>() == null || _triggerHelper == null)
            {
                return(false);
            }

            // 1. move all non-trigger Colliders and get closest collision
            var colliders = Entity.GetComponents <Collider>();

            for (var i = 0; i < colliders.Count; i++)
            {
                var collider = colliders[i];

                // skip triggers for now. we will revisit them after we move.
                if (collider.IsTrigger)
                {
                    continue;
                }

                // fetch anything that we might collide with at our new position
                var bounds = collider.Bounds;
                bounds.X += motion.X;
                bounds.Y += motion.Y;
                var neighbors =
                    Physics.BoxcastBroadphaseExcludingSelf(collider, ref bounds, collider.CollidesWithLayers);

                foreach (var neighbor in neighbors)
                {
                    // skip triggers for now. we will revisit them after we move.
                    if (neighbor.IsTrigger)
                    {
                        continue;
                    }

                    if (collider.CollidesWith(neighbor, motion, out CollisionResult _InternalcollisionResult))
                    {
                        // hit. back off our motion
                        motion -= _InternalcollisionResult.MinimumTranslationVector;

                        // If we hit multiple objects, only take on the first for simplicity sake.
                        if (_InternalcollisionResult.Collider != null)
                        {
                            collisionResult = _InternalcollisionResult;
                        }
                    }
                }
            }

            ListPool <Collider> .Free(colliders);

            return(collisionResult.Collider != null);
        }
Example #2
0
        /// <summary>
        /// Calculates the movement modifying the motion vector to take into account any collisions that will
        /// occur when moving. This version is modified to output through a given collection to show every
        /// collision that occured.
        /// </summary>
        /// <returns>The amount of collisions that occured.</returns>
        /// <param name="motion">Motion.</param>
        /// <param name="collisionResult">Collision result.</param>
        public int AdvancedCalculateMovement(ref System.Numerics.Vector2 motion, ICollection <CollisionResult> collisionResults)
        {
            int Collisions = 0;

            // no collider? just move and forget about it
            if (Entity.GetComponent <Collider>() == null || _triggerHelper == null)
            {
                return(Collisions);
            }

            // 1. move all non-trigger Colliders and get closest collision
            var colliders = Entity.GetComponents <Collider>();

            for (var i = 0; i < colliders.Count; i++)
            {
                var collider = colliders[i];

                // skip triggers for now. we will revisit them after we move.
                if (collider.IsTrigger)
                {
                    continue;
                }

                // fetch anything that we might collide with at our new position
                var bounds = collider.Bounds;
                bounds.X += motion.X;
                bounds.Y += motion.Y;
                var neighbors =
                    Physics.BoxcastBroadphaseExcludingSelf(collider, ref bounds, collider.CollidesWithLayers);

                foreach (var neighbor in neighbors)
                {
                    // skip triggers for now. we will revisit them after we move.
                    if (neighbor.IsTrigger)
                    {
                        continue;
                    }

                    if (collider.CollidesWith(neighbor, motion, out CollisionResult _InternalcollisionResult))
                    {
                        // hit. back off our motion
                        motion -= _InternalcollisionResult.MinimumTranslationVector;
                        collisionResults.Add(_InternalcollisionResult);

                        Collisions++;
                    }
                }
            }

            ListPool <Collider> .Free(colliders);

            return(Collisions);
        }
Example #3
0
        void IUpdatable.Update()
        {
            if (IsImmovable || _collider == null)
            {
                Velocity = Vector2.Zero;
                return;
            }

            if (ShouldUseGravity)
            {
                Velocity += Physics.Gravity * Time.DeltaTime;
            }

            Entity.Transform.Position += Velocity * Time.DeltaTime;

            CollisionResult collisionResult;

            // fetch anything that we might collide with at our new position
            var neighbors = Physics.BoxcastBroadphaseExcludingSelf(_collider, _collider.CollidesWithLayers);

            foreach (var neighbor in neighbors)
            {
                // if the neighbor collider is of the same entity, ignore it
                if (neighbor.Entity == Entity)
                {
                    continue;
                }

                if (_collider.CollidesWith(neighbor, out collisionResult))
                {
                    // if the neighbor has an ArcadeRigidbody we handle full collision response. If not, we calculate things based on the
                    // neighbor being immovable.
                    var neighborRigidbody = neighbor.Entity.GetComponent <ArcadeRigidbody>();
                    if (neighborRigidbody != null)
                    {
                        ProcessOverlap(neighborRigidbody, ref collisionResult.MinimumTranslationVector);
                        ProcessCollision(neighborRigidbody, ref collisionResult.MinimumTranslationVector);
                    }
                    else
                    {
                        // neighbor has no ArcadeRigidbody so we assume its immovable and only move ourself
                        Entity.Transform.Position -= collisionResult.MinimumTranslationVector;
                        var relativeVelocity = Velocity;
                        CalculateResponseVelocity(ref relativeVelocity, ref collisionResult.MinimumTranslationVector,
                                                  out relativeVelocity);
                        Velocity += relativeVelocity;
                    }
                }
            }
        }
Example #4
0
        public void Update()
        {
            if (_collider == null)
            {
                return;
            }
            //fetch anything that we might collide with us
            var neighbors = Physics.BoxcastBroadphaseExcludingSelf(_collider, _collider.CollidesWithLayers);

            foreach (var neighbor in neighbors)
            {
                if (_collider.Overlaps(neighbor))
                {
                    NotifyListeners(_collider, neighbor);
                }
            }
        }
Example #5
0
        /// <summary>
        /// checks to see if this Collider with motion applied (delta movement vector) collides with any collider. If it does, true will be
        /// returned and result will be populated with collision data. Motion will be set to the maximum distance the Collider can travel
        /// before colliding.
        /// </summary>
        /// <returns><c>true</c>, if with was collidesed, <c>false</c> otherwise.</returns>
        /// <param name="motion">Motion.</param>
        /// <param name="result">Result.</param>
        public bool CollidesWithAny(ref Vector2 motion, out CollisionResult result)
        {
            result = new CollisionResult();

            // fetch anything that we might collide with at our new position
            var colliderBounds = Bounds;

            colliderBounds.X += motion.X;
            colliderBounds.Y += motion.Y;
            var neighbors = Physics.BoxcastBroadphaseExcludingSelf(this, ref colliderBounds, CollidesWithLayers);

            // alter the shapes position so that it is in the place it would be after movement so we can check for overlaps
            var oldPosition = Shape.position;

            Shape.position += motion;

            var didCollide = false;

            foreach (var neighbor in neighbors)
            {
                // skip triggers
                if (neighbor.IsTrigger)
                {
                    continue;
                }

                if (CollidesWith(neighbor, out result))
                {
                    // hit. back off our motion and our Shape.position
                    motion         -= result.MinimumTranslationVector;
                    Shape.position -= result.MinimumTranslationVector;
                    didCollide      = true;
                }
            }

            // return the shapes position to where it was before the check
            Shape.position = oldPosition;

            return(didCollide);
        }
Example #6
0
        /// <summary>
        /// checks to see if this Collider collides with any other Colliders in the Scene. The first Collider it intersects will have its collision
        /// data returned in the CollisionResult.
        /// </summary>
        /// <returns><c>true</c>, if with was collidesed, <c>false</c> otherwise.</returns>
        /// <param name="result">Result.</param>
        public bool CollidesWithAny(out CollisionResult result)
        {
            result = new CollisionResult();

            // fetch anything that we might collide with at our new position
            var neighbors = Physics.BoxcastBroadphaseExcludingSelf(this, CollidesWithLayers);

            foreach (var neighbor in neighbors)
            {
                // skip triggers
                if (neighbor.IsTrigger)
                {
                    continue;
                }

                if (CollidesWith(neighbor, out result))
                {
                    return(true);
                }
            }

            return(false);
        }