Esempio n. 1
0
        public void UpdateWorldMatrixBall()
        {
            List <Vector3> verticesSoup = game.maze.VertList;
            Vector3        tableCenter  = game.table.Position;

            Vector2 velocity = physics.CurrentVelocity(delta, externalAcceleration);

            externalAcceleration = Vector2.Zero;

            Vector3 prevPosition = position;

            COLLISION collision = COLLISION.NoHit;

            Vector2 distance = physics.Collision(new BoundingSphere(position, Globals.config.ballRadius), verticesSoup, velocity, ref collision);

            switch (collision)
            {
            case COLLISION.HitXY:
                physics.PreVelocityX = -reflectionIndex * velocity.X;
                physics.PreVelocityY = -reflectionIndex * velocity.Y;

                position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;

                break;

            case COLLISION.HitX:

                if (Math.Abs(physics.PreVelocityX) > 1)
                {
                    physics.PreVelocityX = -reflectionIndex * velocity.X;
                    physics.PreVelocityY = velocity.Y;

                    position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                    position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    physics.PreVelocityY = velocity.Y;
                    physics.PreVelocityX = 0;
                    position.Z          -= velocity.Y * Globals.config.gFrameTime;
                }

                break;

            case COLLISION.HitY:
                if (Math.Abs(physics.PreVelocityY) > 1)
                {
                    physics.PreVelocityX = velocity.X;
                    physics.PreVelocityY = -reflectionIndex * velocity.Y;

                    position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                    position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    physics.PreVelocityX = velocity.X;
                    physics.PreVelocityY = 0;
                    position.X          -= velocity.X * Globals.config.gFrameTime;
                }
                break;

            case COLLISION.HitEdgeX:
                if (Math.Abs(physics.PreVelocityX) > 10)
                {
                    physics.PreVelocityX = -reflectionIndex * velocity.X;
                    physics.PreVelocityY = velocity.Y;

                    position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                    position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    physics.PreVelocityY = velocity.Y;
                    physics.PreVelocityX = 0;
                    position.Z          -= velocity.Y * Globals.config.gFrameTime;
                }

                break;

            case COLLISION.HitEdgeY:
                if (Math.Abs(physics.PreVelocityY) > 10)
                {
                    physics.PreVelocityX = velocity.X;
                    physics.PreVelocityY = -reflectionIndex * velocity.Y;

                    position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                    position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    physics.PreVelocityX = velocity.X;
                    physics.PreVelocityY = 0;
                    position.X          -= velocity.X * Globals.config.gFrameTime;
                }

                break;

            case COLLISION.NoMove:
                physics.PreVelocity = Vector2.Zero;

                break;



            default:
                position.X -= velocity.X * Globals.config.gFrameTime;
                position.Z -= velocity.Y * Globals.config.gFrameTime;

                physics.PreVelocityX = velocity.X;
                physics.PreVelocityY = velocity.Y;
                break;
            }



            world  = Matrix.Identity;
            world *= Matrix.CreateTranslation(0f, -tableCenter.Y, 0f);
            world *= Matrix.CreateFromAxisAngle(Vector3.Normalize(new Vector3(0f, 0, 1f)), delta.X);
            world *= Matrix.CreateFromAxisAngle(Vector3.Normalize(new Vector3(1f, 0f, 0f)), delta.Y);
            world *= Matrix.CreateTranslation(0f, tableCenter.Y, 0f);

            Vector4 deltaPos = Vector4.Transform(position, world);

            world = Matrix.CreateTranslation(deltaPos.X, deltaPos.Y, deltaPos.Z);
        }
Esempio n. 2
0
        public void UpdateWorldMatrixBall()
        {
            List <Vector3> verticesSoup = game.maze.VertList;
            Vector3        tableCenter  = game.table.Position;

            Vector2 velocity = physics.CurrentVelocity(delta, externalAcceleration);

            externalAcceleration = Vector2.Zero;

            Vector3 prevPosition = position;

            COLLISION collision = COLLISION.NoHit;

            Vector2 distance = physics.Collision(new BoundingSphere(position, Globals.config.ballRadius), verticesSoup, velocity, ref collision);

            switch (collision)
            {
            case COLLISION.HitXY:
                if (Math.Abs(physics.PreVelocityX) > 1 || Math.Abs(physics.PreVelocityY) > 1)
                {
                    float vol = (float)((Math.Max(Math.Abs(velocity.X), Math.Abs(velocity.Y)))) / 200;
                    sound2Instance.Volume = vol > 1 ? 1 : vol;
                    sound2Instance.Play();

                    physics.PreVelocityX = -reflectionIndex * velocity.X;
                    position.X          -= physics.PreVelocityX * Globals.config.gFrameTime;

                    physics.PreVelocityY = -reflectionIndex * velocity.Y;
                    position.Z          -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    sound1Instance.Stop();
                    physics.PreVelocityX = 0;
                    physics.PreVelocityY = 0;
                }

                break;

            case COLLISION.HitX:

                if (Math.Abs(physics.PreVelocityX) > 1)
                {
                    float vol = (float)(Math.Abs(velocity.X)) / 200;
                    sound2Instance.Volume = vol > 1 ? 1 : vol;
                    sound2Instance.Play();

                    physics.PreVelocityX = -reflectionIndex * velocity.X;
                    physics.PreVelocityY = velocity.Y;

                    position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                    position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    if (physics.PreVelocity != Vector2.Zero)
                    {
                        float velocityMagnitude = (float)(Math.Sqrt(Math.Pow(velocity.X, 2) + Math.Pow(velocity.Y, 2))) / 200 - 1;
                        sound1Instance.Pitch = velocityMagnitude > 1 ? 1 : velocityMagnitude;
                        sound1Instance.Play();
                    }
                    else
                    {
                        sound1Instance.Stop();
                    }

                    physics.PreVelocityY = velocity.Y;
                    physics.PreVelocityX = 0;
                    position.Z          -= velocity.Y * Globals.config.gFrameTime;
                }

                break;

            case COLLISION.HitY:
                if (Math.Abs(physics.PreVelocityY) > 1)
                {
                    float vol = (float)(Math.Abs(velocity.Y)) / 200;
                    sound2Instance.Volume = vol > 1 ? 1 : vol;
                    sound2Instance.Play();

                    physics.PreVelocityX = velocity.X;
                    physics.PreVelocityY = -reflectionIndex * velocity.Y;

                    position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                    position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    if (physics.PreVelocity != Vector2.Zero)
                    {
                        float velocityMagnitude = (float)(Math.Sqrt(Math.Pow(velocity.X, 2) + Math.Pow(velocity.Y, 2))) / 200 - 1;
                        sound1Instance.Pitch = velocityMagnitude > 1 ? 1 : velocityMagnitude;
                        sound1Instance.Play();
                    }
                    else
                    {
                        sound1Instance.Stop();
                    }

                    physics.PreVelocityX = velocity.X;
                    physics.PreVelocityY = 0;
                    position.X          -= velocity.X * Globals.config.gFrameTime;
                }
                break;

            case COLLISION.HitEdgeX:
                if (Math.Abs(physics.PreVelocityX) > 1)
                {
                    float vol = (float)(Math.Abs(velocity.X)) / 200;
                    sound2Instance.Volume = vol > 1 ? 1 : vol;
                    sound2Instance.Play();

                    physics.PreVelocityX = -reflectionIndex * velocity.X;
                    physics.PreVelocityY = velocity.Y;

                    position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                    position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    if (physics.PreVelocity != Vector2.Zero)
                    {
                        float velocityMagnitude = (float)(Math.Sqrt(Math.Pow(velocity.X, 2) + Math.Pow(velocity.Y, 2))) / 200 - 1;
                        sound1Instance.Pitch = velocityMagnitude > 1 ? 1 : velocityMagnitude;
                        sound1Instance.Play();
                    }
                    else
                    {
                        sound1Instance.Stop();
                    }

                    physics.PreVelocityY = velocity.Y;
                    physics.PreVelocityX = 0;
                    position.Z          -= velocity.Y * Globals.config.gFrameTime;
                }

                break;

            case COLLISION.HitEdgeY:
                if (Math.Abs(physics.PreVelocityY) > 1)
                {
                    float vol = (float)(Math.Abs(velocity.Y)) / 200;
                    sound2Instance.Volume = vol > 1 ? 1 : vol;
                    sound2Instance.Play();

                    physics.PreVelocityX = velocity.X;
                    physics.PreVelocityY = -reflectionIndex * velocity.Y;

                    position.X -= physics.PreVelocityX * Globals.config.gFrameTime;
                    position.Z -= physics.PreVelocityY * Globals.config.gFrameTime;
                }
                else
                {
                    if (physics.PreVelocity != Vector2.Zero)
                    {
                        float velocityMagnitude = (float)(Math.Sqrt(Math.Pow(velocity.X, 2) + Math.Pow(velocity.Y, 2))) / 200 - 1;
                        sound1Instance.Pitch = velocityMagnitude > 1 ? 1 : velocityMagnitude;
                        sound1Instance.Play();
                    }
                    else
                    {
                        sound1Instance.Stop();
                    }

                    physics.PreVelocityX = velocity.X;
                    physics.PreVelocityY = 0;
                    position.X          -= velocity.X * Globals.config.gFrameTime;
                }

                break;

            case COLLISION.NoMove:
                if (physics.PreVelocity != Vector2.Zero)
                {
                    float vol = (float)(Math.Sqrt(Math.Pow(velocity.X, 2) + Math.Pow(velocity.Y, 2))) / 200;
                    sound2Instance.Volume = vol > 1 ? 1 : vol;
                    sound2Instance.Play();
                }
                sound1Instance.Stop();
                physics.PreVelocity = Vector2.Zero;

                break;



            default:
                if (physics.PreVelocity != Vector2.Zero)
                {
                    float velocityMagnitude = (float)(Math.Sqrt(Math.Pow(velocity.X, 2) + Math.Pow(velocity.Y, 2))) / 200 - 1;
                    sound1Instance.Pitch = velocityMagnitude > 1 ? 1 : velocityMagnitude;
                    sound1Instance.Play();
                }
                else
                {
                    sound1Instance.Stop();
                }

                position.X -= velocity.X * Globals.config.gFrameTime;
                position.Z -= velocity.Y * Globals.config.gFrameTime;

                physics.PreVelocityX = velocity.X;
                physics.PreVelocityY = velocity.Y;
                break;
            }



            world  = Matrix.Identity;
            world *= Matrix.CreateTranslation(0f, -tableCenter.Y, 0f);
            world *= Matrix.CreateFromAxisAngle(Vector3.Normalize(new Vector3(0f, 0, 1f)), delta.X);
            world *= Matrix.CreateFromAxisAngle(Vector3.Normalize(new Vector3(1f, 0f, 0f)), delta.Y);
            world *= Matrix.CreateTranslation(0f, tableCenter.Y, 0f);

            Vector4 deltaPos = Vector4.Transform(position, world);

            world = Matrix.CreateTranslation(deltaPos.X, deltaPos.Y, deltaPos.Z);
        }
Esempio n. 3
0
        public Vector2 Collision(BoundingSphere sphere, List <Vector3> vertices, Vector2 velocity, ref COLLISION collision)
        {
            Ray[] ray = new Ray[3];

            ray[0].Position  = sphere.Center;
            ray[0].Direction = Vector3.Normalize(new Vector3(-velocity.X, 0, 0));

            ray[1].Position  = sphere.Center;
            ray[1].Direction = Vector3.Normalize(new Vector3(0, 0, -velocity.Y));

            Vector2 distance     = Vector2.One * float.MaxValue;
            Vector3 Edge         = Vector3.Zero;
            float?  distanceEdge = float.MaxValue;

            for (int i = 0; i < vertices.Count; i += 3)
            {
                Vector2 tmpDistance;
                tmpDistance.X = RayTriangleIntersects(ray[0], vertices[i], vertices[i + 1], vertices[i + 2]);
                tmpDistance.Y = RayTriangleIntersects(ray[1], vertices[i], vertices[i + 1], vertices[i + 2]);
                if (tmpDistance.X < distance.X)
                {
                    distance.X = tmpDistance.X;
                }
                if (tmpDistance.Y < distance.Y)
                {
                    distance.Y = tmpDistance.Y;
                }
                if (vertices[i].Y != vertices[i + 1].Y && vertices[i].X == vertices[i + 1].X && vertices[i + 1].Z == vertices[i + 1].Z)
                {
                    ray[2].Position  = new Vector3(vertices[i].X, (vertices[i].Y + vertices[i + 1].Y) / 2, vertices[i].Z);
                    ray[2].Direction = Vector3.Normalize(new Vector3(velocity.X, 0, velocity.Y));
                    float?tmp = sphere.Intersects(ray[2]);
                    if (tmp == null)
                    {
                        tmp = float.MaxValue;
                    }
                    if (tmp < distanceEdge)
                    {
                        Edge         = ray[2].Position;
                        distanceEdge = tmp;
                    }
                }
            }

            if (!(distance.X != float.MaxValue && distance.X > 0 && (distance.X <= Globals.config.ballRadius || distance.X <= Math.Abs(velocity.X * Globals.config.gFrameTime) + Globals.config.ballRadius))) //|| distance <= Math.Abs(velocity.Y * Globals.config.gFrameTime) + Globals.config.ballRadius))
            {
                distance.X = float.MaxValue;
            }
            if (!(distance.Y != float.MaxValue && distance.Y > 0 && (distance.Y <= Globals.config.ballRadius || distance.Y <= Math.Abs(velocity.Y * Globals.config.gFrameTime) + Globals.config.ballRadius))) //|| distance <= Math.Abs(velocity.Y * Globals.config.gFrameTime) + Globals.config.ballRadius))
            {
                distance.Y = float.MaxValue;
            }
            if (!(distanceEdge != float.MaxValue && distanceEdge > 0 && (distanceEdge <= Math.Sqrt(Math.Pow(velocity.X, 2) + Math.Pow(velocity.Y, 2)) * Globals.config.gFrameTime)))
            {
                distanceEdge = float.MaxValue;
            }

            if (distance.X != float.MaxValue && distance.Y != float.MaxValue && distance.X - Globals.config.ballRadius < distanceEdge / 2 && distance.Y - Globals.config.ballRadius < distanceEdge / 2)
            {
                collision = COLLISION.HitXY;
            }
            else if (distance.X != float.MaxValue && distance.X - Globals.config.ballRadius < distanceEdge / 2)
            {
                collision = COLLISION.HitX;
            }
            else if (distance.Y != float.MaxValue && distance.Y - Globals.config.ballRadius < distanceEdge / 2)
            {
                collision = COLLISION.HitY;
            }
            else if (distanceEdge != float.MaxValue)
            {
                float angleBefore = (float)(Math.Atan2(sphere.Center.Z - Edge.Z, sphere.Center.X - Edge.X));
                if (angleBefore != -MathHelper.PiOver2)
                {
                    collision = COLLISION.NoHit;
                }

                if (angleBefore > 0 && angleBefore < MathHelper.PiOver2)
                {
                    if (velocity.X <= 0 && velocity.Y >= 0)
                    {
                        collision = COLLISION.HitEdgeY;
                    }
                    else if (velocity.X >= 0 && velocity.Y <= 0)
                    {
                        collision = COLLISION.HitEdgeX;
                    }
                    else
                    {
                        collision = COLLISION.NoMove;
                    }
                }

                else if (angleBefore > MathHelper.PiOver2 && angleBefore < MathHelper.Pi)
                {
                    if (velocity.X >= 0 && velocity.Y >= 0)
                    {
                        collision = COLLISION.HitEdgeY;
                    }
                    else if (velocity.X <= 0 && velocity.Y <= 0)
                    {
                        collision = COLLISION.HitEdgeX;
                    }
                    else
                    {
                        collision = COLLISION.NoMove;
                    }
                }

                else if (angleBefore < -MathHelper.PiOver2 && angleBefore > -MathHelper.Pi)
                {
                    if (velocity.X >= 0 && velocity.Y <= 0)
                    {
                        collision = COLLISION.HitEdgeY;
                    }
                    else if (velocity.X <= 0 && velocity.Y >= 0)
                    {
                        collision = COLLISION.HitEdgeX;
                    }
                    else
                    {
                        collision = COLLISION.NoMove;
                    }
                }

                else if (angleBefore < 0 && angleBefore > -MathHelper.PiOver2)
                {
                    if (velocity.X <= 0 && velocity.Y <= 0)
                    {
                        collision = COLLISION.HitEdgeY;
                    }
                    else if (velocity.X >= 0 && velocity.Y >= 0)
                    {
                        collision = COLLISION.HitEdgeX;
                    }
                    else
                    {
                        collision = COLLISION.NoMove;
                    }
                }

                else if (angleBefore == 0 || angleBefore == -MathHelper.Pi || angleBefore == MathHelper.Pi)
                {
                    collision = COLLISION.HitEdgeX;
                }
                else if (angleBefore == MathHelper.PiOver2 || angleBefore == -MathHelper.PiOver2)
                {
                    collision = COLLISION.HitEdgeY;
                }
            }

            return(distance);
        }