//------------------------------------------------------------------------------------------
    //                                      BallSegmentCollisionDetection()
    //------------------------------------------------------------------------------------------
    private void BallSegmentCollisionDetection(ref GameObject current, ref Vec2 currentNormal)
    {
        for (int i = 0; i < myGame.GetNumberOfLines(); i++)
        {
            LineSegment line = myGame.GetLine(i);
            if (Input.GetKey(Key.S) && line.parent is Stairs)
            {
                continue;
            }
            Vec2  differenceVector = _oldPosition - line.start;
            float ballDistance     = differenceVector.Dot((line.end - line.start).Normal());

            Vec2  normal     = (line.end - line.start).Normal();
            Vec2  dist       = position + (-ballDistance + radius) * normal;
            float difference = (dist - position).Magnitude();
            float b          = -velocity.Dot(normal);
            float a          = ballDistance - radius;

            if (b > 0)
            {
                float t = 3f;
                if (a >= 0)
                {
                    t = a / b;
                }
                else if (a >= -radius)
                {
                    t = 0;
                }
                else
                {
                    continue;
                }
                if (t <= 1f)
                {
                    Vec2  POI = _oldPosition + t * velocity;
                    float d   = (POI - line.start).Dot((line.end - line.start).Normalized());
                    if (0 <= d && d <= (line.end - line.start).Magnitude())
                    {
                        if (t < smallestToi)
                        {
                            smallestToi   = t;
                            current       = line;
                            currentNormal = normal;
                            currentline   = (Platform)line;
                        }
                    }
                }
            }
        }
    }
Exemplo n.º 2
0
    CollisionInfo FindEarliestCollision()
    {
        GameObject current       = null;
        Vec2       currentNormal = new Vec2();

        smallestToi = 2f;
        MyGame myGame = (MyGame)game;

        // Check other movers:
        for (int i = 0; i < myGame.GetNumberOfMovers(); i++)
        {
            Ball mover = myGame.GetMover(i);
            if (mover != this)
            {
                Vec2 relativePosition = position - mover.position;
                //if (relativePosition.Magnitude() < radius + mover.radius)
                //{
                // TODO: compute correct normal and time of impact, and
                // return *earliest* collision instead of *first detected collision*:
                Vec2  u     = _oldPosition - mover.position;
                float a     = velocity.Magnitude() * velocity.Magnitude();
                float b     = 2 * u.Dot(velocity);
                float c     = u.Magnitude() * u.Magnitude() - (radius + mover.radius) * (radius + mover.radius);
                float delta = b * b - 4 * a * c;
                float t;
                t = (-b - Mathf.Sqrt(delta)) / (2 * a);

                if (c < 0)
                {
                    if (b < 0)
                    {
                        t = 0;
                        //Vec2 normal = (_oldPosition - mover.position).Normalized();
                        //return new CollisionInfo(normal, mover, t);
                    }
                    else
                    {
                        continue;
                    }
                }

                if (a != 0)
                //{
                //    return null;
                //}
                //else
                {
                    if (delta >= 0)
                    //{
                    //    return null;
                    //}
                    //else
                    {
                        Vec2 pointOfImpact = _oldPosition + velocity * t;
                        Vec2 normal        = (pointOfImpact - mover.position).Normalized();
                        if (0 <= t && t < 1)
                        {
                            if (t < smallestToi)
                            {
                                smallestToi   = t;
                                current       = mover;
                                currentNormal = normal;
                            }
                        }
                        //else return null;
                    }
                }
                //Vec2 normal = relativePosition.Normalized();
                //float overlap = radius + mover.radius - relativePosition.Magnitude();
                //return new CollisionInfo(normal, mover, overlap);


                //}
            }
        }

        for (int i = 0; i < myGame.GetNumberOfLines(); i++)
        {
            NLineSegment line = myGame.GetLine(i);

            Vec2  differenceVector = _oldPosition - line.start;
            float ballDistance     = differenceVector.Dot((line.end - line.start).Normal());
            //if (ballDistance < radius)
            //{
            Vec2  normal     = (line.end - line.start).Normal();
            Vec2  dist       = position + (-ballDistance + radius) * normal;
            float difference = (dist - position).Magnitude();
            float b          = -velocity.Dot(normal);
            //float a = b - difference;
            float a = ballDistance - radius;

            if (b > 0)
            //{

            //    return null;
            //}
            //else
            {
                float t = 3f;
                if (a >= 0)
                //{
                //    return null;
                //}
                //else
                {
                    t = a / b;
                }
                else if (a >= -radius)
                {
                    t = 0;
                }
                else
                {
                    continue;
                }
                if (t <= 1f)
                {
                    Vec2  POI = _oldPosition + t * velocity;
                    float d   = (POI - line.start).Dot((line.end - line.start).Normalized());
                    if (0 <= d && d <= (line.end - line.start).Magnitude())
                    {
                        if (t < smallestToi)
                        {
                            smallestToi   = t;
                            current       = line;
                            currentNormal = normal;
                        }
                    }
                    // else return null;
                }
            }
            //}
        }


        if (current != null)
        {
            return(new CollisionInfo(currentNormal, current, smallestToi));
        }
        else
        {
            return(null);
        }
        // TODO: Check Line segments using myGame.GetLine();
        // return null;
    }