Пример #1
0
        /**
         * Check if agent intersect with shape
         *
         * Agent will automatically detect which shape is used to calculate collision
         **/
        public virtual CollisionResult IntersectWithShape(ConvexShape shape)
        {
            switch (shape.ShapeId)
            {
            case ConvexShapeID.Rectangle:
                ConvexRect rectShape = shape as ConvexRect;
                if (rectShape == null)
                {
                                        #if DEBUG
                    Debug.LogError("Unable to down cast ConvexShape to ConvexRect");
                                        #endif
                }
                return(ContactWithRectangle(rectShape));

            case ConvexShapeID.Circle:
                ConvexCircle circleShape = shape as ConvexCircle;
                if (circleShape == null)
                {
                                        #if DEBUG
                    Debug.LogError("Unable to down cast ConvexShape to ConvexCircle");
                                        #endif
                }
                return(ContactWIthCircle(circleShape));

            case ConvexShapeID.Unknow:
                                #if DEBUG
                Debug.LogError("Unknow convex shape");
                                #endif
                break;
            }

            return(CollisionResult.None);
        }
Пример #2
0
        protected override CollisionResult ContactWithRectangle(ConvexRect otherRect)
        {
            //All corners from rectangle
            Vector2[] corners = otherRect.AllCorners;

            bool collision = true;

            /**
             * Find closest corner to circle center then make a line between that corner and circle center into projection axis
             * Projecting all corner to that axis then find min and max corner
             * Check if circle is overlap with rectangle
             *
             * This solve problem when circle contact each corner vertex
             **/
            //find closest corner and compare distance
            int closestCornerIndex = 0;
            int currentCornerIndex = 1;

            while (currentCornerIndex < corners.Length)
            {
                if ((_center - corners [closestCornerIndex]).sqrMagnitude > (_center - corners [currentCornerIndex]).sqrMagnitude)
                {
                    closestCornerIndex = currentCornerIndex;
                }

                currentCornerIndex++;
            }

            //projection axis from closest corner to circle center
            Vector2 p = _center - corners [closestCornerIndex];

            //base on axis find min and max corner
            float rMin = 0.0f;
            float rMax = 0.0f;

            for (int i = 0; i < corners.Length; i++)
            {
                rMax = Mathf.Max(rMax, Vector2.Dot(p.normalized, corners [i]));
                rMin = Mathf.Min(rMin, Vector2.Dot(p.normalized, corners [i]));
            }

            //find circle center projection
            float cP = Vector2.Dot(p.normalized, _center);

            //check if circle is overlap rectangle
            if (rMax < (cP - _radius) || rMin > (cP + _radius))
            {
                collision = false;
            }
            else
            {
                collision = true;
            }

            /**
             * Find 4 corner's normal and make it as prjection axis
             * Go throught each normal(corner)
             * Find min and max projection of rectangle's corner base on that axis
             * Project circle center on that axis
             * Check if circle overlap rectangle
             *
             * This solve problem while circle contact edge of rectangle
             *
             * We also check if circle inside rectangle
             **/
            //Ignore edge check if circle not contact with 4 corners(vertices)
            if (collision == true)
            {
                bool inside = true;

                Vector2[] normals = otherRect.Normals;
                float     r1Dot1, r1Dot2, r1Dot3, r1Dot4, r1PMin, r1PMax;

                for (int i = 0; i < normals.Length; i++)
                {
                    //4 corners projection
                    r1Dot1 = Vector2.Dot(normals [i], corners [0]);
                    r1Dot2 = Vector2.Dot(normals [i], corners [1]);
                    r1Dot3 = Vector2.Dot(normals [i], corners [2]);
                    r1Dot4 = Vector2.Dot(normals [i], corners [3]);

                    //corner min and max on this normal(projection axis)
                    r1PMin = Mathf.Min(r1Dot1, Mathf.Min(r1Dot2, Mathf.Min(r1Dot3, r1Dot4)));
                    r1PMax = Mathf.Max(r1Dot1, Mathf.Max(r1Dot2, Mathf.Max(r1Dot3, r1Dot4)));

                    //circle center projection on this normal(projection axis)
                    float circleP = Vector2.Dot(normals [i], _center);

                    //check if circle overlap rectangle
                    if ((circleP - _radius) > r1PMax || (circleP + _radius) < r1PMin)
                    {
                        collision = false;
                        break;
                    }

                    //Circle intersect with rectangle then check if circle inside rectangle
                    //If insde we &(AND) value with true other wise false
                    if ((circleP - _radius) > r1PMin && (circleP + _radius) > r1PMin)
                    {
                        inside &= true;
                    }
                    else
                    {
                        inside &= false;
                    }
                }

                //if circle collide rectangle
                if (collision)
                {
                    //If inside rectangle
                    if (inside)
                    {
                        return(CollisionResult.Fit);
                    }
                    else
                    {
                        return(CollisionResult.Overlap);
                    }
                }
            }

            return(CollisionResult.None);
        }
Пример #3
0
        protected override CollisionResult ContactWithRectangle(ConvexRect otherRect)
        {
            bool collision = true;

            //this rectangle's normal of 4 corner and use it as projection axis
            Vector2[] rect1Normals    = this.Normals;
            Vector2[] rect1AllCorners = this.AllCorners;
            Vector2[] rect2AllCorners = otherRect.AllCorners;

            //For each normals in this rectangle
            for (int i = 0; i < rect1Normals.Length; i++)
            {
                //Projecting all corners from rect1 to rect1's normal
                float r1Dot1 = Vector2.Dot(rect1Normals [i], rect1AllCorners [0]);
                float r1Dot2 = Vector2.Dot(rect1Normals [i], rect1AllCorners [1]);
                float r1Dot3 = Vector2.Dot(rect1Normals [i], rect1AllCorners [2]);
                float r1Dot4 = Vector2.Dot(rect1Normals [i], rect1AllCorners [3]);

                //Find rect1 max and min projection
                float r1PMin = Mathf.Min(r1Dot1, Mathf.Min(r1Dot2, Mathf.Min(r1Dot3, r1Dot4)));
                float r1PMax = Mathf.Max(r1Dot1, Mathf.Max(r1Dot2, Mathf.Max(r1Dot3, r1Dot4)));

                //Projecting all corners from rect2 to rect1's normal
                float r2Dot1 = Vector2.Dot(rect1Normals [i], rect2AllCorners [0]);
                float r2Dot2 = Vector2.Dot(rect1Normals [i], rect2AllCorners [1]);
                float r2Dot3 = Vector2.Dot(rect1Normals [i], rect2AllCorners [2]);
                float r2Dot4 = Vector2.Dot(rect1Normals [i], rect2AllCorners [3]);

                //Find rect2 max and min projection
                float r2PMin = Mathf.Min(r2Dot1, Mathf.Min(r2Dot2, Mathf.Min(r2Dot3, r2Dot4)));
                float r2PMax = Mathf.Max(r2Dot1, Mathf.Max(r2Dot2, Mathf.Max(r2Dot3, r2Dot4)));

                //Two rectangles not collide each other if there is a gap
                //and we do not check further
                if (r2PMin > r1PMax || r2PMax < r1PMin)
                {
                    collision = false;

                    break;
                }
            }

            //Check if this rectangle is inside another rectangle
            if (collision == true)
            {
                bool inside = true;

                //4 corners of this rectangle
                foreach (Vector2 corner in AllCorners)
                {
                    //if other rectangle not contain this corner
                    if (!otherRect.ContainPoint2D(corner))
                    {
                        inside = false;
                        break;
                    }
                }

                if (inside == true)
                {
                    return(CollisionResult.Fit);
                }

                return(CollisionResult.Overlap);
            }

            //There is no collision between two rectangles;
            return(CollisionResult.None);
        }
Пример #4
0
        //public abstract ConvexShape GetShape ();

        /**
         * Subclass must override
         **/
        protected abstract CollisionResult ContactWithRectangle(ConvexRect otherRect);
Пример #5
0
 protected override CollisionResult ContactWithRectangle(ConvexRect otherRect)
 {
     return(otherRect.IntersectWithShape(this));
 }
Пример #6
0
        protected override CollisionResult ContactWithRectangle(ConvexRect otherRect)
        {
            bool collision = true;
            bool inside    = true;

            //this rectangle's normal of 4 corner and use it as projection axis
            Vector2[] rect1Normals    = this.Normals;
            Vector2[] rect1AllCorners = this.AllCorners;
            Vector2[] rect2AllCorners = otherRect.AllCorners;

            //For each normals in this rectangle
            IEnumerator ie = rect1Normals.GetEnumerator();

            while (ie.MoveNext())
            {
                //Projecting all corners from rect1 to rect1's normal
                float r1Dot1 = Vector2.Dot((Vector2)ie.Current, rect1AllCorners [0]);
                float r1Dot2 = Vector2.Dot((Vector2)ie.Current, rect1AllCorners [1]);
                float r1Dot3 = Vector2.Dot((Vector2)ie.Current, rect1AllCorners [2]);
                float r1Dot4 = Vector2.Dot((Vector2)ie.Current, rect1AllCorners [3]);

                //Find rect1 max and min projection
                float r1PMin = Mathf.Min(r1Dot1, Mathf.Min(r1Dot2, Mathf.Min(r1Dot3, r1Dot4)));
                float r1PMax = Mathf.Max(r1Dot1, Mathf.Max(r1Dot2, Mathf.Max(r1Dot3, r1Dot4)));

                //Projecting all corners from rect2 to rect1's normal
                float r2Dot1 = Vector2.Dot((Vector2)ie.Current, rect2AllCorners [0]);
                float r2Dot2 = Vector2.Dot((Vector2)ie.Current, rect2AllCorners [1]);
                float r2Dot3 = Vector2.Dot((Vector2)ie.Current, rect2AllCorners [2]);
                float r2Dot4 = Vector2.Dot((Vector2)ie.Current, rect2AllCorners [3]);

                //Find rect2 max and min projection
                float r2PMin = Mathf.Min(r2Dot1, Mathf.Min(r2Dot2, Mathf.Min(r2Dot3, r2Dot4)));
                float r2PMax = Mathf.Max(r2Dot1, Mathf.Max(r2Dot2, Mathf.Max(r2Dot3, r2Dot4)));

                //Two rectangles not collide each other if there is a gap
                //and we do not check further
                if (r2PMin > r1PMax || r2PMax < r1PMin)
                {
                    collision = false;
                    inside    = false;
                    break;
                }

                if (r1PMin < r2PMin || r1PMax > r2PMax)
                {
                    inside = false;
                }
            }

            if (collision == true)
            {
                if (inside == true)
                {
                    return(CollisionResult.Fit);
                }

                return(CollisionResult.Overlap);
            }

            //There is no collision between two rectangles;
            return(CollisionResult.None);
        }