Пример #1
0
        public TwinCollisionChild(Collider self, Collider other, DotToLineCollisionResult source)
        {
            this.self               = self;
            this.other              = other;
            this.contactPoint       = source.collisionPoint;
            this.selfDepenetration  = source.dotDepenetration;
            this.otherDepenetration = source.lineDepenetration;
            this.selfOtherNormal    = source.lineNormal;
            this.t                    = source.t;
            this.selfMovement         = source.dotMovement;
            this.otherMovement        = source.lineMovement;
            this.selfRequirement      = source.dotRequirement;
            this.otherRequirement     = source.lineRequirement;
            this.thinSelf             = source.thinDot;
            this.thinOther            = source.thinLine;
            this.similarDepenetration = source.similarDepenetration;

            this.selfOriginalMovement  = source.dotOriginalMovement;
            this.otherOriginalMovement = source.lineOriginalMovement;

            selfDepenetration0    = selfDepenetration;
            otherDepenetration0   = otherDepenetration;
            similarDepenetration0 = similarDepenetration;
            selfMovement0         = selfMovement;
            otherMovement0        = otherMovement;
            selfRequirement0      = selfRequirement;
            otherRequirement0     = otherRequirement;
        }
Пример #2
0
        public bool CheckGraze(PolygonCollider other, out TwinCollisionChild result)
        {
            bool ret0 = false;

            result = null;

            Vector2 mov  = movement;
            Vector2 oMov = other.movement;

            Vector2[] myPoints         = worldPoints;
            Vector2[] otherPoints      = other.worldPoints;
            int       mpl              = myPoints.Length;
            int       mpl1             = mpl - 1;
            int       opl              = otherPoints.Length;
            int       opl1             = opl - 1;
            Vector2   prevContactPoint = Vector2.zero;

            DotToLineCollisionResult r = new DotToLineCollisionResult();

            for (int i = 0; i < mpl; ++i)
            {
                Vector2 p = myPoints [i];

                for (int j = 0; j < opl; ++j)
                {
                    int     j1 = Util.RotaryClamp(j - 1, 0, opl1);
                    Vector2 p1 = otherPoints [j1];
                    Vector2 p2 = otherPoints [j];
                    DotToLineCollisionResult rIJ;
                    if (Physics.MovingDotToMovingLineGraze(
                            p,
                            movement,
                            p1,
                            p2,
                            other.movement,
                            out rIJ) &&
                        (!ret0 || prevContactPoint != rIJ.collisionPoint))
                    {
                        if (!ret0 || rIJ.t < r.t ||
                            (
                                rIJ.t == r.t &&
                                rIJ.dotMovement.sqrMagnitude < r.dotMovement.sqrMagnitude

                                /*&& (
                                 * !r.CheckDotRequirement2(mov+rIJ.dotDepenetration - rIJ.thinDot)
                                 || !r.CheckLineRequirement2(oMov+rIJ.lineDepenetration - rIJ.thinLine)
                                 ||)*/
                            )
                            )
                        {
                            bool collidedIJ = false;
                            if (rIJ.r == 0)
                            {
                                if (Vector2.Dot(
                                        Util.Normal(myPoints[Util.RotaryClamp(i - 1, 0, mpl1)], p),
                                        rIJ.lineNormal
                                        ) == -1)
                                {
                                    collidedIJ = true;
                                }
                            }
                            else if (rIJ.r == 1)
                            {
                                if (Vector2.Dot(
                                        Util.Normal(p, myPoints[Util.RotaryClamp(i + 1, 0, mpl1)]),
                                        rIJ.lineNormal
                                        ) == -1)
                                {
                                    collidedIJ = true;
                                }
                            }
                            else
                            {
                                collidedIJ = true;
                            }
                            if (collidedIJ)
                            {
                                ret0 = true;
                                r    = rIJ;
                                //result = new TwinCollisionChild (this, other, rIJ);
                            }
                        }
                    }
                }
            }
            if (ret0)
            {
                result = new TwinCollisionChild(this, other, r);
            }
            if (ret0 && gameObject.name == "GreenBox" && (result.selfDepenetration.x == 0.3125f || result.selfDepenetration.x == 0.3124999f))
            {
                bool x = true;
            }
            if (ret0 && result.other.gameObject.name == "GreenBox" && (result.otherDepenetration.x == 0.3125f || result.otherDepenetration.x == 0.3124999f))
            {
                bool x = true;
            }
            return(ret0);
        }
Пример #3
0
        public static bool MovingDotToMovingLineCollision(
            Vector2 dot, Vector2 dotMovement,
            Vector2 lineP1, Vector2 lineP2, Vector2 lineMovement,
            out DotToLineCollisionResult result)
        {
            result = new DotToLineCollisionResult();
            result.dotOriginalMovement  = dotMovement;
            result.lineOriginalMovement = lineMovement;
            Vector2 lineNormal = Util.Normal(lineP1, lineP2);

            result.lineNormal = lineNormal;
            result.t          = 1;
            //Vector2 d = lineP2 - lineP1;
            if (dotMovement == Vector2.zero && lineMovement == Vector2.zero)
            {
                UnityEngine.Debug.Log("ZERO MOVEMENT");
                return(false);
            }
            Vector2 diff0  = (dotMovement - lineMovement);
            float   movDot = Vector2.Dot(lineNormal, diff0.normalized);

            if (movDot > 0)
            {
                /*if (dotMovement.x != 0 && lineNormal.x != 0) {
                 *      bool signDot = dotMovement.x > 0;
                 *      bool signLine = lineMovement.x > 0;
                 *      if (signDot == signLine) {
                 *              UnityEngine.Debug.Log ("DOT ESCAPE");
                 *      }
                 * }*/
                return(false);
            }

            if (movDot == 0)
            {
                Vector2 u    = lineP2 - lineP1;
                Vector2 v    = dot - lineP1;
                Vector2 w    = v + diff0;
                Vector2 proj = Util.Project(w, u);
                if (Vector2.Dot(v, u) < 0)
                {
                    return(false);
                }
                else
                {
                    float   r   = proj.magnitude / u.magnitude;
                    Vector2 rej = w - proj;
                    if (r > 1)
                    {
                        return(false);
                    }
                    else if (rej.sqrMagnitude > 3 * Util.sqrThin)
                    {
                        return(false);
                    }
                    else
                    {
                        result.r = r;
                        result.t = 1;
                        result.dotDepenetration     = Vector2.zero;
                        result.collisionPoint       = dot + dotMovement;
                        result.lineDepenetration    = Vector2.zero;
                        result.dotMovement          = dotMovement;
                        result.dotRequirement       = dotMovement;
                        result.dotOriginalMovement  = dotMovement;
                        result.lineNormal           = Util.Normal(u);
                        result.similarDepenetration = Vector2.zero;
                        result.thinDot              = Vector2.zero;
                        result.thinLine             = Vector2.zero;
                        result.lineOriginalMovement = lineMovement;
                        result.lineRequirement      = lineMovement;
                        result.lineMovement         = lineMovement;

                        return(true);
                    }
                }
            }
            DotToLineIntersectionResult _r;

            if (!MovingDotToMovingLineIntersection(dot, dotMovement, lineP1, lineP2, lineMovement, out _r))
            {
                return(MovingDotToMovingLineGraze(dot, dotMovement, lineP1, lineP2, lineMovement, out result));

                return(false);
            }
            bool needThinning = true;

            if (false)
            {
                float   t          = _r.t;
                Vector2 u          = lineP2 - lineP1;
                Vector2 endPoint   = _r.intersectionPoint;
                Vector2 postLineP1 = lineP1 + lineMovement + result.lineDepenetration;
                Vector2 diff       = endPoint - postLineP1;
                float   crossPost  = Util.Cross(diff, u);
                if (crossPost != 0)
                {
                    //UnityEngine.Debug.Log ("CROSS IS NOT ZERO");
                    float crossPre = Util.Cross(dot - lineP1, u);
                    bool  signPost = crossPost > 0;
                    bool  signPre  = crossPre > 0;
                    needThinning = true;
                    if (signPre != signPost)
                    {
                        UnityEngine.Debug.Log("SIGN IS DIFFERENT");
                        if (t <= 0)
                        {
                            UnityEngine.Debug.Log("T NEGATIVE");
                            needThinning = true;
                            t            = 0;
                        }
                        else
                        {
                            int i = 0;
                            do
                            {
                                if (t >= _r.t)
                                {
                                    t *= (1 - Util.thin);
                                }
                                if (t >= _r.t)
                                {
                                    t -= Util.sqrThin;
                                }
                                if (t >= _r.t)
                                {
                                    t -= Util.halfThin;
                                }
                                if (t >= _r.t)
                                {
                                    t -= Util.thin;
                                }
                                if (t < 0)
                                {
                                    UnityEngine.Debug.Log("T NEGATIVE");
                                    needThinning = true;
                                    t            = 0;
                                    break;
                                }
                                _r.t = t;
                                float t1 = t - 1;
                                _r.dotDepenetration  = dotMovement * t1;
                                _r.lineDepenetration = lineMovement * t1;
                                _r.intersectionPoint = dot + dotMovement + _r.dotDepenetration;

                                endPoint   = _r.intersectionPoint;
                                postLineP1 = lineP1 + lineMovement + _r.lineDepenetration;
                                diff       = endPoint - postLineP1;
                                crossPost  = Util.Cross(diff, u);
                                crossPre   = Util.Cross(dot - lineP1, u);
                                signPost   = crossPost > 0;
                                signPre    = crossPre > 0;
                                if (signPost == signPre)
                                {
                                    needThinning = false;
                                    break;
                                }
                                else
                                {
                                    UnityEngine.Debug.Log("FAILED");
                                }
                                ++i;
                            } while(needThinning && i < 5 && t > 0);
                        }
                    }
                }
            }
            //needThinning = false;

            Vector2 _dotMovement  = dotMovement + _r.dotDepenetration;
            Vector2 _lineMovement = lineMovement + _r.lineDepenetration;

            Vector2 _dotRequirement  = _dotMovement;
            Vector2 _lineRequirement = _lineMovement;

            _r.dotDepenetration  = Util.Project(_r.dotDepenetration, lineNormal);
            _r.lineDepenetration = Util.Project(_r.lineDepenetration, lineNormal);

            if (dotMovement == Vector2.zero && lineMovement == Vector2.zero && _r.dotDepenetration == Vector2.zero && _r.lineDepenetration == Vector2.zero)
            {
                UnityEngine.Debug.Log("ZERO MOVEMENT AND DEPENETRATION");
                return(false);
            }



            //Vector2 similarDepenetration = Vector2.zero;
            Vector2 similarDepenetration = SimilarDepenetration(_r.dotDepenetration, _r.lineDepenetration, lineNormal);

            if (similarDepenetration != Vector2.zero)
            {
                _r.dotDepenetration  -= similarDepenetration;
                _r.lineDepenetration -= similarDepenetration;
                _dotMovement         -= similarDepenetration;
                _lineMovement        -= similarDepenetration;
            }

            Vector2 thinDot = Vector2.zero, thinLine = Vector2.zero;

            if (needThinning)
            {
                Thin(_dotMovement, _r.dotDepenetration, _lineMovement, _r.lineDepenetration, lineNormal, out thinDot, out thinLine);
                _r.dotDepenetration  += thinDot;
                _r.lineDepenetration += thinLine;
                _dotMovement         += thinDot;
                _lineMovement        += thinLine;
            }

            result.similarDepenetration = similarDepenetration;
            result.lineNormal           = lineNormal;
            result.t = _r.t;
            result.r = _r.r;
            result.dotDepenetration  = _r.dotDepenetration;
            result.lineDepenetration = _r.lineDepenetration;
            result.collisionPoint    = _r.intersectionPoint;
            result.dotMovement       = _dotMovement;
            result.lineMovement      = _lineMovement;
            result.dotRequirement    = _dotRequirement;         // - _r.dotDepenetration;
            result.lineRequirement   = _lineRequirement;        // - _r.lineDepenetration;
            result.thinDot           = thinDot;
            result.thinLine          = thinLine;

            return(true);
        }
Пример #4
0
        public static bool MovingDotToMovingLineGraze(
            Vector2 dot, Vector2 dotMovement,
            Vector2 lineP1, Vector2 lineP2, Vector2 lineMovement,
            out DotToLineCollisionResult result)
        {
            result = new DotToLineCollisionResult();
            result.dotOriginalMovement  = dotMovement;
            result.lineOriginalMovement = lineMovement;
            Vector2 lineNormal = Util.Normal(lineP1, lineP2);

            result.lineNormal = lineNormal;
            result.t          = 1;
            Vector2 diff0  = (dotMovement - lineMovement);
            float   movDot = Vector2.Dot(lineNormal, diff0.normalized);

            if (movDot < 0)
            {
                return(false);
            }
            Vector2 u    = lineP2 - lineP1;
            Vector2 v    = dot - lineP1;
            Vector2 w    = v + diff0;
            Vector2 proj = Util.Project(v, u);
            Vector2 rej  = w - proj;

            if (rej.sqrMagnitude < 3 * Util.sqrThin)
            {
                if (Vector2.Dot(v, u) < 0)
                {
                    return(false);
                }
                else
                {
                    float r0 = proj.sqrMagnitude / u.sqrMagnitude;
                    float r  = Util.Project(w, u).magnitude / u.magnitude;
                    if (r0 > 1)
                    {
                        return(false);
                    }
                    else
                    {
                        if (r > 1)
                        {
                            r = 1;
                        }

                        result.r = r;
                        result.t = 1;
                        result.dotDepenetration     = Vector2.zero;
                        result.collisionPoint       = dot + dotMovement;
                        result.lineDepenetration    = Vector2.zero;
                        result.dotMovement          = dotMovement;
                        result.dotRequirement       = dotMovement;
                        result.dotOriginalMovement  = dotMovement;
                        result.lineNormal           = Util.Normal(u);
                        result.similarDepenetration = Vector2.zero;
                        result.thinDot              = Vector2.zero;
                        result.thinLine             = Vector2.zero;
                        result.lineOriginalMovement = lineMovement;
                        result.lineRequirement      = lineMovement;
                        result.lineMovement         = lineMovement;

                        return(true);
                    }
                }
            }
            return(false);
        }