Beispiel #1
0
        /// <summary>
        /// Performs a ray cast on the polygon given an optional tmax value
        /// Only process the information in the rayHit structure if Intersection = true,
        /// which is specified in the gxtRayHit instance and the return value.  If the ray origin is 
        /// inside the Polygon it is not considered an intersection
        /// </summary>
        /// <param name="ray">Ray</param>
        /// <param name="polygon">Polygon</param>
        /// <param name="rayHit">Ray Hit Info</param>
        /// <param name="tmax">Max T Value</param>
        /// <returns>If Intersecting</returns>
        public virtual bool RayCast(gxtRay ray, ref gxtPolygon polygon, out gxtRayHit rayHit, float tmax = float.MaxValue)
        {
            rayHit = new gxtRayHit();
            rayHit.Distance = tmax;

            // if a crossing is within tmax
            bool intersection = false;
            // temp holder for segment distance
            float distance;
            // number of crossings, regardless of tmax
            int crossings = 0;

            // log a message when we run a raycast on a very detailed polygon
            // to indicate that the results may not be perfect
            int testIterations = polygon.NumVertices;
            if (MaxIterations < polygon.NumVertices)
            {
                gxtLog.WriteLineV(gxtVerbosityLevel.WARNING, "Polygon vertices exceeds max collider iterations.  Not all segments will be tested!");
                testIterations = MaxIterations;
            }

            for (int j = polygon.NumVertices - 1, i = 0; i < testIterations; j = i, i++)
            {
                if (RayIntersectsSegment(ray, polygon.v[j], polygon.v[i], out distance))
                {
                    crossings++;
                    if (distance <= rayHit.Distance)
                    {
                        intersection = true;

                        rayHit.Distance = distance;
                        rayHit.Point = ray.GetPoint(distance);

                        // right perp assumes CCW polygon winding
                        Vector2 edge = polygon.v[j] - polygon.v[i];
                        rayHit.Normal = Vector2.Normalize(gxtMath.RightPerp(edge));
                    }
                }
            }
            // raycast algorithm
            rayHit.Intersection = intersection && crossings > 0 && crossings % 2 == 0;
            return rayHit.Intersection;
        }
Beispiel #2
0
        public static bool RayCast(gxtRay ray, gxtPolygon polygon, float tmax, out float t, out Vector2 pt, out Vector2 normal)
        {
            t = float.MaxValue;
            pt = ray.Origin;
            normal = ray.Direction;

            bool intersection = false;
            // temp holder for segment distance
            float distance;
            int crossings = 0;

            for (int j = polygon.NumVertices - 1, i = 0; i < polygon.NumVertices; j = i, i++)
            {
                if (RayIntersectsSegment(ray, polygon.v[j], polygon.v[i], float.MaxValue, out distance))
                {
                    crossings++;
                    if (distance < t && distance <= tmax)
                    {
                        intersection = true;

                        t = distance;
                        pt = ray.GetPoint(t);

                        Vector2 edge = polygon.v[i] - polygon.v[j];
                        normal = Vector2.Normalize(gxtMath.RightPerp(edge));
                        //normal = gxtMath.GetReflection(ray.Direction, edgeNormal);
                    }
                }
            }
            return intersection && crossings > 0 && crossings % 2 == 0;
        }