Beispiel #1
0
        /**
         * From Real-time Collision Detection, p179.
         *
         * @param output
         * @param input
         */

        public bool raycast(RayCastOutput output, RayCastInput input,
                            IWorldPool argPool)
        {
            double tmin = -double.MaxValue;
            double tmax = double.MaxValue;

            Vec2 p      = argPool.popVec2();
            Vec2 d      = argPool.popVec2();
            Vec2 absD   = argPool.popVec2();
            Vec2 normal = argPool.popVec2();

            p.set(input.p1);
            d.set(input.p2).subLocal(input.p1);
            Vec2.absToOut(d, absD);

            // x then y
            if (absD.x < Settings.EPSILON)
            {
                // Parallel.
                if (p.x < lowerBound.x || upperBound.x < p.x)
                {
                    argPool.pushVec2(4);
                    return(false);
                }
            }
            else
            {
                double inv_d = 1.0d / d.x;
                double t1    = (lowerBound.x - p.x) * inv_d;
                double t2    = (upperBound.x - p.x) * inv_d;

                // Sign of the normal vector.
                double s = -1.0d;

                if (t1 > t2)
                {
                    double temp = t1;
                    t1 = t2;
                    t2 = temp;
                    s  = 1.0d;
                }

                // Push the min up
                if (t1 > tmin)
                {
                    normal.setZero();
                    normal.x = s;
                    tmin     = t1;
                }

                // Pull the max down
                tmax = MathUtils.min(tmax, t2);

                if (tmin > tmax)
                {
                    argPool.pushVec2(4);
                    return(false);
                }
            }

            if (absD.y < Settings.EPSILON)
            {
                // Parallel.
                if (p.y < lowerBound.y || upperBound.y < p.y)
                {
                    argPool.pushVec2(4);
                    return(false);
                }
            }
            else
            {
                double inv_d = 1.0d / d.y;
                double t1    = (lowerBound.y - p.y) * inv_d;
                double t2    = (upperBound.y - p.y) * inv_d;

                // Sign of the normal vector.
                double s = -1.0d;

                if (t1 > t2)
                {
                    double temp = t1;
                    t1 = t2;
                    t2 = temp;
                    s  = 1.0d;
                }

                // Push the min up
                if (t1 > tmin)
                {
                    normal.setZero();
                    normal.y = s;
                    tmin     = t1;
                }

                // Pull the max down
                tmax = MathUtils.min(tmax, t2);

                if (tmin > tmax)
                {
                    argPool.pushVec2(4);
                    return(false);
                }
            }

            // Does the ray start inside the box?
            // Does the ray intersect beyond the max fraction?
            if (tmin < 0.0d || input.maxFraction < tmin)
            {
                argPool.pushVec2(4);
                return(false);
            }

            // Intersection.
            output.fraction = tmin;
            output.normal.x = normal.x;
            output.normal.y = normal.y;
            argPool.pushVec2(4);
            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// From Real-time Collision Detection, p179.
        /// </summary>
        /// <param name="output"></param>
        /// <param name="input"></param>
        public bool raycast(RayCastOutput output, RayCastInput input, IWorldPool argPool)
        {
            //UPGRADE_TODO: The equivalent in .NET for field 'java.lang.Float.MIN_VALUE' may return a different value. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1043'"
            float tmin = Single.Epsilon;
            float tmax = Single.MaxValue;

            Vec2 p = argPool.popVec2();
            Vec2 d = argPool.popVec2();
            Vec2 absD = argPool.popVec2();
            Vec2 normal = argPool.popVec2();

            p.set_Renamed(input.p1);
            d.set_Renamed(input.p2).subLocal(input.p1);
            Vec2.absToOut(d, absD);

            // x then y
            if (absD.x < Settings.EPSILON)
            {
                // Parallel.
                if (p.x < lowerBound.x || upperBound.x < p.x)
                {
                    argPool.pushVec2(4);
                    return false;
                }
            }
            else
            {
                float inv_d = 1.0f / d.x;
                float t1 = (lowerBound.x - p.x) * inv_d;
                float t2 = (upperBound.x - p.x) * inv_d;

                // Sign of the normal vector.
                float s = -1.0f;

                if (t1 > t2)
                {
                    float temp = t1;
                    t1 = t2;
                    t2 = temp;
                    s = 1.0f;
                }

                // Push the min up
                if (t1 > tmin)
                {
                    normal.setZero();
                    normal.x = s;
                    tmin = t1;
                }

                // Pull the max down
                tmax = MathUtils.min(tmax, t2);

                if (tmin > tmax)
                {
                    argPool.pushVec2(4);
                    return false;
                }
            }

            if (absD.y < Settings.EPSILON)
            {
                // Parallel.
                if (p.y < lowerBound.y || upperBound.y < p.y)
                {
                    argPool.pushVec2(4);
                    return false;
                }
            }
            else
            {
                float inv_d = 1.0f / d.y;
                float t1 = (lowerBound.y - p.y) * inv_d;
                float t2 = (upperBound.y - p.y) * inv_d;

                // Sign of the normal vector.
                float s = -1.0f;

                if (t1 > t2)
                {
                    float temp = t1;
                    t1 = t2;
                    t2 = temp;
                    s = 1.0f;
                }

                // Push the min up
                if (t1 > tmin)
                {
                    normal.setZero();
                    normal.y = s;
                    tmin = t1;
                }

                // Pull the max down
                tmax = MathUtils.min(tmax, t2);

                if (tmin > tmax)
                {
                    argPool.pushVec2(4);
                    return false;
                }
            }

            // Does the ray start inside the box?
            // Does the ray intersect beyond the max fraction?
            if (tmin < 0.0f || input.maxFraction < tmin)
            {
                argPool.pushVec2(4);
                return false;
            }

            // Intersection.
            output.fraction = tmin;
            output.normal.x = normal.x;
            output.normal.y = normal.y;
            argPool.pushVec2(4);
            return true;
        }
Beispiel #3
0
        /**
           * From Real-time Collision Detection, p179.
           *
           * @param output
           * @param input
           */
        public bool raycast(RayCastOutput output, RayCastInput input,
            IWorldPool argPool)
        {
            float tmin = float.MinValue;
            float tmax = float.MaxValue;

            Vec2 p = argPool.popVec2();
            Vec2 d = argPool.popVec2();
            Vec2 absD = argPool.popVec2();
            Vec2 normal = argPool.popVec2();

            p.set(input.p1);
            d.set(input.p2);
            d.subLocal(input.p1);
            Vec2.absToOut(d, ref absD);

            // x then y
            if (absD.x < Settings.EPSILON)
            {
                // Parallel.
                if (p.x < lowerBound.x || upperBound.x < p.x)
                {
                    argPool.pushVec2(4);
                    return false;
                }
            }
            else
            {
                float inv_d = 1.0f/d.x;
                float t1 = (lowerBound.x - p.x)*inv_d;
                float t2 = (upperBound.x - p.x)*inv_d;

                // Sign of the normal vector.
                float s = -1.0f;

                if (t1 > t2)
                {
                    float temp = t1;
                    t1 = t2;
                    t2 = temp;
                    s = 1.0f;
                }

                // Push the min up
                if (t1 > tmin)
                {
                    normal.setZero();
                    normal.x = s;
                    tmin = t1;
                }

                // Pull the max down
                tmax = MathUtils.min(tmax, t2);

                if (tmin > tmax)
                {
                    argPool.pushVec2(4);
                    return false;
                }
            }

            if (absD.y < Settings.EPSILON)
            {
                // Parallel.
                if (p.y < lowerBound.y || upperBound.y < p.y)
                {
                    argPool.pushVec2(4);
                    return false;
                }
            }
            else
            {
                float inv_d = 1.0f/d.y;
                float t1 = (lowerBound.y - p.y)*inv_d;
                float t2 = (upperBound.y - p.y)*inv_d;

                // Sign of the normal vector.
                float s = -1.0f;

                if (t1 > t2)
                {
                    float temp = t1;
                    t1 = t2;
                    t2 = temp;
                    s = 1.0f;
                }

                // Push the min up
                if (t1 > tmin)
                {
                    normal.setZero();
                    normal.y = s;
                    tmin = t1;
                }

                // Pull the max down
                tmax = MathUtils.min(tmax, t2);

                if (tmin > tmax)
                {
                    argPool.pushVec2(4);
                    return false;
                }
            }

            // Does the ray start inside the box?
            // Does the ray intersect beyond the max fraction?
            if (tmin < 0.0f || input.maxFraction < tmin)
            {
                argPool.pushVec2(4);
                return false;
            }

            // Intersection.
            output.fraction = tmin;
            output.normal.x = normal.x;
            output.normal.y = normal.y;
            argPool.pushVec2(4);
            return true;
        }