Esempio n. 1
0
        public Hit hit = new Hit();         // Result of ray casting. Contains last ray state if not.

        // Casts a ray, returns true if a collision occurred.
        // Options of the raycaster are used.
        // Important : you must normalize the ray direction,
        // otherwise the crossed distance will not be accurate.
        public Hit Cast(Vector2f origin, Vector2f direction, HitPredicate hitFunc, float maxDistance)
        {
            float infinite = 9999999;

            // Equation : p + v*t
            // p : ray start position (ray.pos)
            // v : ray orientation vector (ray.dir)
            // t : parametric variable = a distance if v is normalized

            // This raycasting technique is described here :
            // http://www.cse.yorku.ca/~amana/research/grid.pdf

            // Note : the grid is assumed to have 1-unit square cells.

            //
            // Initialisation
            //

            hit.isHit = false;

            // Cell position
            hit.pos.X   = (int)Mathf.Floor(origin.X);
            hit.pos.Y   = (int)Mathf.Floor(origin.Y);
            hit.prevPos = hit.pos;

            // Voxel step (will not change)
            int xi_step = direction.X > 0 ? 1 : direction.X < 0 ? -1 : 0;
            int yi_step = direction.Y > 0 ? 1 : direction.Y < 0 ? -1 : 0;

            // Parametric voxel step (will not change)
            float tdelta_x = xi_step != 0 ? 1f / Mathf.Abs(direction.X) : infinite;
            float tdelta_y = yi_step != 0 ? 1f / Mathf.Abs(direction.Y) : infinite;

            // Parametric grid-cross
            float tcross_x;             // At which value of T we will cross a vertical line?
            float tcross_y;             // At which value of T we will cross a horizontal line?

            // X initialization
            if (xi_step != 0)
            {
                if (xi_step == 1)
                {
                    tcross_x = (Mathf.Ceil(origin.X) - origin.X) * tdelta_x;
                }
                else
                {
                    tcross_x = (origin.X - Mathf.Floor(origin.X)) * tdelta_x;
                }
            }
            else
            {
                tcross_x = infinite;                 // Will never cross on X
            }
            // Y initialization
            if (yi_step != 0)
            {
                if (yi_step == 1)
                {
                    tcross_y = (Mathf.Ceil(origin.Y) - origin.Y) * tdelta_y;
                }
                else
                {
                    tcross_y = (origin.Y - Mathf.Floor(origin.Y)) * tdelta_y;
                }
            }
            else
            {
                tcross_y = infinite;                 // Will never cross on X
            }
            //
            // Iteration
            //

            do
            {
                hit.prevPos = hit.pos;
                if (tcross_x < tcross_y)
                {
                    // X collision
                    //hit.prevPos.x = hit.pos.x;
                    hit.pos.X += xi_step;
                    if (tcross_x > maxDistance)
                    {
                        return(hit);
                    }
                    tcross_x += tdelta_x;
                }
                else
                {
                    // Y collision
                    //hit.prevPos.y = hit.pos.y;
                    hit.pos.Y += yi_step;
                    if (tcross_y > maxDistance)
                    {
                        return(hit);
                    }
                    tcross_y += tdelta_y;
                }
            } while (!hitFunc(hit.pos.X, hit.pos.Y));

            return(hit);
        }
Esempio n. 2
0
 public void Draw(Vector2f position, IntRect subRect)
 {
     Draw(position, subRect, Color.White);
 }
Esempio n. 3
0
 public void DrawCentered(Vector2f position, IntRect subRect, Color color, Vector2f scale, float rotation)
 {
     Draw(position, subRect, color, scale, new Vector2f((float)subRect.Width / 2f, (float)subRect.Height / 2f), rotation);
 }
Esempio n. 4
0
        public void Draw(Vector2f position, IntRect subRect, Color color, Vector2f scale, Vector2f origin, float rotation)
        {
            if (_primitiveCount * 4 >= _vertices.Length)
            {
                Array.Resize <Vertex>(ref _vertices, _vertices.Length * 2);
            }

            float sin = __sin.GetRepeat(rotation);
            float cos = __cos.GetRepeat(rotation);

            origin.X *= scale.X;
            origin.Y *= scale.Y;
            scale.X  *= subRect.Width;
            scale.Y  *= subRect.Height;

            Vertex v = new Vertex();

            v.Color = color;

            float pX, pY;
            uint  vi = _primitiveCount * 4;

            pX            = -origin.X;
            pY            = -origin.Y;
            v.Position.X  = pX * cos - pY * sin + position.X;
            v.Position.Y  = pX * sin + pY * cos + position.Y;
            v.TexCoords.X = subRect.Left + E;
            v.TexCoords.Y = subRect.Top + E;
            _vertices[vi] = v;

            pX               += scale.X;
            v.Position.X      = pX * cos - pY * sin + position.X;
            v.Position.Y      = pX * sin + pY * cos + position.Y;
            v.TexCoords.X    += subRect.Width - 2f * E;
            _vertices[vi + 1] = v;

            pY               += scale.Y;
            v.Position.X      = pX * cos - pY * sin + position.X;
            v.Position.Y      = pX * sin + pY * cos + position.Y;
            v.TexCoords.Y    += subRect.Height - 2f * E;
            _vertices[vi + 2] = v;

            pX               -= scale.X;
            v.Position.X      = pX * cos - pY * sin + position.X;
            v.Position.Y      = pX * sin + pY * cos + position.Y;
            v.TexCoords.X    -= subRect.Width - 2f * E;
            _vertices[vi + 3] = v;

            ++_primitiveCount;
        }