Beispiel #1
0
        public static CollisionInformations CheckCollisionPadBall(Pad pad, Ball ball)
        {
            Vector3 size = Vector3.Multiply(Vector3.Add(pad.Size, ball.Size), 0.5f);

            Vector3[] v1 = { -Vector3.UnitX * size.X,
                             Vector3.UnitX *size.X,
                             -Vector3.UnitY * size.Y,
                             Vector3.UnitY *size.Y };

            Vector3[] v2 = { Vector3.UnitY *size.Y,
                             -Vector3.UnitY *size.Y,
                      Vector3.UnitX *size.X,
                             -Vector3.UnitX *size.X };

            Vector3[] v3 = { -Vector3.UnitZ * size.Z,
                             Vector3.UnitZ *size.Z,
                             -Vector3.UnitZ * size.Z,
                             Vector3.UnitZ *size.Z };

            CollisionInformations total_res = CollisionInformations.NOT_COLLIDING;

            for (int i = v1.Length - 1; i >= 0; i--)    // reverse... we check the right and left faces first
            {
                CollisionInformations res = CalculateCollision(v1[i], v2[i], v3[i], ball, pad, yPhysics.Instance.DT, false);

                if (res.Colliding && res.CollisionT < total_res.CollisionT)
                {
                    total_res = res;
                }
            }

            return(total_res);
        }
Beispiel #2
0
        public static CollisionInformations CheckCollisionWalls(Level lvl, Box obj, bool ghost_wall)
        {
            // intern face of each lvl.Box*
            Box[] targets = { lvl.BoxDown, lvl.BoxRight, lvl.BoxUp, lvl.BoxLeft, lvl.BoxLimit, lvl.BoxLimit };

            Vector3[] v1 = { -Vector3.UnitX * (lvl.BoxDown.Size.X + obj.Size.X) / 2,
                             -Vector3.UnitY * (lvl.BoxRight.Size.Y + obj.Size.Y) / 2,
                             Vector3.UnitX *(lvl.BoxUp.Size.X + obj.Size.X) / 2,
                             Vector3.UnitY *(lvl.BoxLeft.Size.Y + obj.Size.Y) / 2,
                             Vector3.UnitY *(lvl.BoxLimit.Size.Y + obj.Size.Y) / 2,
                             Vector3.UnitY *(lvl.BoxLimit.Size.Y + obj.Size.Y) / 2 };

            Vector3[] v2 = { Vector3.UnitY *(lvl.BoxDown.Size.Y + obj.Size.Y) / 2,
                             Vector3.UnitX *(lvl.BoxRight.Size.X + obj.Size.X) / 2,
                             -Vector3.UnitY * (lvl.BoxUp.Size.Y + obj.Size.Y) / 2,
                             -Vector3.UnitX * (lvl.BoxLeft.Size.X + obj.Size.X) / 2,
                             Vector3.UnitX *(lvl.BoxLimit.Size.X + obj.Size.X) / 2,
                             -Vector3.UnitX * (lvl.BoxLimit.Size.X + obj.Size.X) / 2 };

            Vector3[] v3 = { -Vector3.UnitZ * (lvl.BoxDown.Size.Z + obj.Size.Z) / 2,
                             -Vector3.UnitZ * (lvl.BoxRight.Size.Z + obj.Size.Z) / 2,
                             Vector3.UnitZ *(lvl.BoxUp.Size.Z + obj.Size.Z) / 2,
                             Vector3.UnitZ *(lvl.BoxLeft.Size.Z + obj.Size.Z) / 2,
                             Vector3.UnitZ *(lvl.BoxLimit.Size.Z + obj.Size.Z) / 2,
                             Vector3.UnitZ *(lvl.BoxLimit.Size.Z + obj.Size.Z) / 2 };

            CollisionInformations total_res = CollisionInformations.NOT_COLLIDING;


            for (int i = 0; i < targets.Length - (ghost_wall?0:2); i++)
            {
                CollisionInformations res = CalculateCollision(v1[i], v2[i], v3[i], obj, targets[i], yPhysics.Instance.DT, false);

                if (res.Colliding && res.CollisionT < total_res.CollisionT)
                {
                    total_res = res;
                }
            }

            return(total_res);
        }
Beispiel #3
0
        // global method
        public static CollisionInformations[] CheckCollisions(Level lvl, Pad[] pads, Ball[] balls)
        {
            LinkedList <CollisionInformations> collisions_done = new LinkedList <CollisionInformations>();

            const int  max_iteration           = 200;
            const bool collision_between_balls = false;

            int iteration = 0;

            while (true)
            {
                if (++iteration > max_iteration)
                {
                    break;
                }

                CollisionInformations[] collisions = new CollisionInformations[pads.Length + balls.Length + pads.Length * balls.Length + pads.Length * (pads.Length - 1) / 2 + (collision_between_balls?balls.Length * (balls.Length - 1) / 2:0)];
                int collisionn = 0;

                for (int i = 0; i < pads.Length + balls.Length; i++)        // a tricky loop, to do all the balls and all the pads at once
                {
                    CollisionInformations res;

                    if (i < pads.Length)
                    {
                        res = CheckCollisionWalls(lvl, (Box)pads[i], true);
                    }
                    else
                    {
                        res = CheckCollisionWalls(lvl, (Box)balls[i - pads.Length], false);
                    }


                    if (res.Colliding)                                      // whenever a collision is found, the collisioninformations object is queued in the collision array
                    {
                        collisions[collisionn++] = res;
                    }

                    if (i < pads.Length)
                    {
                        for (int b = 0; b < balls.Length; b++)              // check pad<->ball
                        {
                            res = CheckCollisionPadBall(pads[i], balls[b]);

                            if (res.Colliding)
                            {
                                collisions[collisionn++] = res;
                            }
                        }

                        for (int j = i + 1; j < pads.Length; j++)           // check pad<->pad
                        {
                            res = CheckCollisionsBetweenPads(pads[i], pads[j]);

                            if (res.Colliding)
                            {
                                collisions[collisionn++] = res;
                            }
                        }
                    }
                }

                if (collision_between_balls)
                {
                    for (int b = 0; b < balls.Length; b++)
                    {
                        for (int j = b + 1; j < balls.Length; j++)
                        {
                            CollisionInformations res = CheckCollisionBetweenBalls(balls[b], balls[j]);

                            if (res.Colliding)
                            {
                                collisions[collisionn++] = res;
                            }
                        }
                    }
                }


                if (collisionn == 0)
                {
                    break;
                }


                int best_i = 0;
                for (int i = 1; i < collisionn; i++)
                {
                    if (collisions[i].CollisionT < collisions[best_i].CollisionT)
                    {
                        if (collisions_done.Count > 0)
                        {
                            if (!collisions_done.Last.Value.hasSameObjects(collisions[i]))
                            {
                                best_i = i;
                            }
                        }
                        else
                        {
                            best_i = i;
                        }
                    }
                }

                // check if (best_i=0) the only valid collision is the same as the last one Apply()ed
                if (collisions_done.Count > 0)
                {
                    if (collisions_done.Last.Value.hasSameObjects(collisions[best_i]))
                    {
                        break;
                    }
                }

                collisions[best_i].Apply();
                collisions_done.AddLast(collisions[best_i]);
            }

            return(collisions_done.ToArray <CollisionInformations>());
        }
Beispiel #4
0
 public bool hasSameObjects(CollisionInformations c)
 {
     return(hasSameObjects(c.CollidingObj, c.TargetObj));
 }