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
        /// <summary>
        /// update should be called AFTER Entity is moved. It will take care of any ITriggerListeners that the Collider overlaps.
        /// </summary>
        public void Update()
        {
            // 3. do an overlap check of all entity.colliders that are triggers with all broadphase colliders, triggers or not.
            //    Any overlaps result in trigger events.
            var colliders = _entity.GetComponents <Collider>();

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

                // fetch anything that we might collide with us at our new position
                var neighbors = Physics.BoxcastBroadphase(collider.Bounds, collider.CollidesWithLayers);
                foreach (var neighbor in neighbors)
                {
                    // we need at least one of the colliders to be a trigger
                    if (!collider.IsTrigger && !neighbor.IsTrigger)
                    {
                        continue;
                    }

                    if (collider.Overlaps(neighbor))
                    {
                        var pair = new Pair <Collider>(collider, neighbor);

                        // if we already have this pair in one of our sets (the previous or current trigger intersections) dont call the enter event
                        var shouldReportTriggerEvent = !_activeTriggerIntersections.Contains(pair) &&
                                                       !_previousTriggerIntersections.Contains(pair);
                        if (shouldReportTriggerEvent)
                        {
                            NotifyTriggerListeners(pair, true);
                            _previousColliders.Add(pair);
                        }

                        _activeTriggerIntersections.Add(pair);
                        CheckForStayColliders();
                    }             // overlaps
                }                 // end foreach
            }



            ListPool <Collider> .Free(colliders);



            CheckForExitedColliders();
        }