예제 #1
0
        public bool RayCast(out b2RayCastOutput castOutput, b2RayCastInput input, Transform transform, int childIndex)
        {
            Vector2D position = transform.Position + b2Mat22.Mul(transform.Rotation, m_p);
            Vector2D s        = input.p1 - position;
            float    b        = Vector2D.Dot(s, s) - Radius * Radius;

            castOutput.fraction = 0.0f;
            castOutput.Normal   = null;

            // Solve quadratic equation
            Vector2D r     = input.p2 - input.p1;
            float    c     = Vector2D.Dot(s, r);
            float    rr    = Vector2D.Dot(r, r);
            float    sigma = c * c - rr * b;

            if (sigma < 0.0f || rr < float.Epsilon)
            {
                return(false);
            }

            float a = -(float)(c + System.Math.Sqrt(sigma));

            if (0.0f <= a && a <= input.maxFraction * rr)
            {
                a /= rr;
                castOutput.fraction = a;
                castOutput.Normal   = s + r * a;
                castOutput.Normal   = castOutput.Normal.Normal();
                return(true);
            }

            return(false);
        }
예제 #2
0
        private void RayCast()
        {
            m_rayActor = null;

            b2RayCastInput input = m_rayCastInput;

            // Ray cast against the dynamic tree.
            m_tree.RayCast(this, input);

            // Brute force ray cast.
            Actor           bruteActor  = null;
            b2RayCastOutput bruteOutput = new b2RayCastOutput();

            for (int i = 0; i < e_actorCount; ++i)
            {
                if (m_actors[i].proxyId == b2_nullNode)
                {
                    continue;
                }

                b2RayCastOutput output;
                bool            hit = m_actors[i].aabb.RayCast(out output, input);
                if (hit)
                {
                    bruteActor        = m_actors[i];
                    bruteOutput       = output;
                    input.maxFraction = output.fraction;
                }
            }

            if (bruteActor != null)
            {
                Debug.Assert(bruteOutput.fraction == m_rayCastOutput.fraction);
            }
        }
예제 #3
0
    /// Implement b2Shape.

    // Collision Detection in Interactive 3D Environments by Gino van den Bergen
    // From Section 3.1.2
    // x = s + a * r
    // norm(x) = radius
    public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform transform, int childIndex)
    {
        b2Vec2 position = transform.p + Utils.b2Mul(transform.q, m_p);
        b2Vec2 s        = input.p1 - position;
        float  b        = Utils.b2Dot(s, s) - m_radius * m_radius;

        // Solve quadratic equation.
        b2Vec2 r     = input.p2 - input.p1;
        float  c     = Utils.b2Dot(s, r);
        float  rr    = Utils.b2Dot(r, r);
        float  sigma = c * c - rr * b;

        // Check for negative discriminant and short segment.
        if (sigma < 0.0f || rr < float.Epsilon)
        {
            return(false);
        }

        // Find the point of intersection of the line with the circle.
        float a = -(c + (float)Math.Sqrt(sigma));

        // Is the intersection point on the segment?
        if (0.0f <= a && a <= input.maxFraction * rr)
        {
            a /= rr;
            output.fraction = a;
            output.normal   = s + a * r;
            output.normal.Normalize();
            return(true);
        }

        return(false);
    }
예제 #4
0
        public bool RayCast(b2RayCastOutput output, b2RayCastInput input, int childIndex)
        {
            bool ret = Box2DPINVOKE.b2Fixture_RayCast(swigCPtr, b2RayCastOutput.getCPtr(output), b2RayCastInput.getCPtr(input), childIndex);

            if (Box2DPINVOKE.SWIGPendingException.Pending)
            {
                throw Box2DPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
예제 #5
0
        public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform transform, int childIndex)
        {
            bool ret = Box2DPINVOKE.b2CircleShape_RayCast(swigCPtr, b2RayCastOutput.getCPtr(output), b2RayCastInput.getCPtr(input), b2Transform.getCPtr(transform), childIndex);

            if (Box2DPINVOKE.SWIGPendingException.Pending)
            {
                throw Box2DPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
예제 #6
0
        public bool RayCast(b2RayCastOutput output, b2RayCastInput input)
        {
            bool ret = Box2dPINVOKE.b2AABB_RayCast(swigCPtr, b2RayCastOutput.getCPtr(output), b2RayCastInput.getCPtr(input));

            if (Box2dPINVOKE.SWIGPendingException.Pending)
            {
                throw Box2dPINVOKE.SWIGPendingException.Retrieve();
            }
            return(ret);
        }
예제 #7
0
        /**
         * @inheritDoc
         */
        public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform transform)
        {
            //b2Vec2 position = transform.position + b2Mul(transform.R, m_p);
            b2Mat22 tMat      = transform.R;
            float   positionX = transform.position.x + (tMat.col1.x * m_p.x + tMat.col2.x * m_p.y);
            float   positionY = transform.position.y + (tMat.col1.y * m_p.x + tMat.col2.y * m_p.y);

            //b2Vec2 s = input.p1 - position;
            float sX = input.p1.x - positionX;
            float sY = input.p1.y - positionY;
            //float32 b = b2Dot(s, s) - m_radius * m_radius;
            float b = (sX * sX + sY * sY) - m_radius * m_radius;

            /*// Does the segment start inside the circle?
             * if (b < 0.0)
             * {
             *      output.fraction = 0;
             *      output.hit = e_startsInsideCollide;
             *      return;
             * }*/

            // Solve quadratic equation.
            //b2Vec2 r = input.p2 - input.p1;
            float rX = input.p2.x - input.p1.x;
            float rY = input.p2.y - input.p1.y;
            //float32 c =  b2Dot(s, r);
            float c = (sX * rX + sY * rY);
            //float32 rr = b2Dot(r, r);
            float rr    = (rX * rX + rY * rY);
            float sigma = c * c - rr * b;

            // Check for negative discriminant and short segment.
            if (sigma < 0.0 || rr < float.MinValue)
            {
                return(false);
            }

            // Find the point of intersection of the line with the circle.
            float a = -(c + Mathf.Sqrt(sigma));

            // Is the intersection point on the segment?
            if (0.0f <= a && a <= input.maxFraction * rr)
            {
                a /= rr;
                output.fraction = a;
                // manual inline of: output.normal = s + a * r;
                output.normal.x = sX + a * rX;
                output.normal.y = sY + a * rY;
                output.normal.Normalize();
                return(true);
            }

            return(false);
        }
예제 #8
0
        // Collision Detection in Interactive 3D Environments by Gino van den Bergen
        // From Section 3.1.2
        // x = s + a * r
        // norm(x) = radius
        public override bool RayCast(out b2RayCastOutput output, b2RayCastInput input,
                                     b2Transform transform, int childIndex)
        {
            output = b2RayCastOutput.Zero;

            b2Vec2 tx = b2Math.b2Mul(transform.q, m_p);
//            b2Vec2 position = transform.p + tx;
            b2Vec2 position;

            position.x = transform.p.x + tx.x;
            position.y = transform.p.y + tx.y;
//            b2Vec2 s = input.p1 - position;
            b2Vec2 s;

            s.x = input.p1.x - position.x;
            s.y = input.p1.y - position.y;
            float b = s.LengthSquared - m_radius * m_radius;

            // Solve quadratic equation.
            b2Vec2 r;

            r.x = input.p2.x - input.p1.x;
            r.y = input.p2.y - input.p1.y;
//            b2Vec2 r = input.p2 - input.p1;
            float c     = s.x * r.x + s.y * r.y; // b2Math.b2Dot(ref s, ref r);
            float rr    = r.LengthSquared;       //  b2Math.b2Dot(r, r);
            float sigma = c * c - rr * b;

            // Check for negative discriminant and short segment.
            if (sigma < 0.0f || rr < b2Settings.b2_epsilon)
            {
                return(false);
            }

            // Find the point of intersection of the line with the circle.
            float a = -(c + b2Math.b2Sqrt(sigma));

            // Is the intersection point on the segment?
            if (0.0f <= a && a <= input.maxFraction * rr)
            {
                a /= rr;
                output.fraction = a;
                output.normal.x = s.x + a * r.x;
                output.normal.y = s.y + a * r.y;
//                output.normal = s + a * r;
                output.normal.Normalize();
                return(true);
            }

            return(false);
        }
예제 #9
0
        // Collision Detection in Interactive 3D Environments by Gino van den Bergen
        // From Section 3.1.2
        // x = s + a * r
        // norm(x) = radius
        public override bool RayCast(out b2RayCastOutput output, b2RayCastInput input,
                                    b2Transform transform, int childIndex)
        {
            output = b2RayCastOutput.Zero;

            b2Vec2 tx = b2Math.b2Mul(transform.q, m_p);
//            b2Vec2 position = transform.p + tx;
            b2Vec2 position;
            position.x = transform.p.x + tx.x;
            position.y = transform.p.y + tx.y;
//            b2Vec2 s = input.p1 - position;
            b2Vec2 s;
            s.x = input.p1.x - position.x;
            s.y = input.p1.y - position.y;
            float b = s.LengthSquared - m_radius * m_radius;

            // Solve quadratic equation.
            b2Vec2 r;
            r.x = input.p2.x - input.p1.x;
            r.y = input.p2.y - input.p1.y;
//            b2Vec2 r = input.p2 - input.p1;
            float c = s.x * r.x + s.y * r.y; // b2Math.b2Dot(ref s, ref r);
            float rr = r.LengthSquared; //  b2Math.b2Dot(r, r);
            float sigma = c * c - rr * b;

            // Check for negative discriminant and short segment.
            if (sigma < 0.0f || rr < b2Settings.b2_epsilon)
            {
                return false;
            }

            // Find the point of intersection of the line with the circle.
            float a = -(c + b2Math.b2Sqrt(sigma));

            // Is the intersection point on the segment?
            if (0.0f <= a && a <= input.maxFraction * rr)
            {
                a /= rr;
                output.fraction = a;
                output.normal.x = s.x + a * r.x;
                output.normal.y = s.y + a * r.y;
//                output.normal = s + a * r;
                output.normal.Normalize();
                return true;
            }

            return false;
        }
예제 #10
0
        public float RayCastCallback(ref b2RayCastInput input, int proxyId)
        {
            Actor actor = (Actor)m_tree.GetUserData(proxyId);

            b2RayCastOutput output = new b2RayCastOutput();
            bool            hit    = actor.aabb.RayCast(out output, input);

            if (hit)
            {
                m_rayCastOutput     = output;
                m_rayActor          = actor;
                m_rayActor.fraction = output.fraction;
                return(output.fraction);
            }

            return(input.maxFraction);
        }
예제 #11
0
        /**
         * @inheritDoc
         */
        public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform transform)
        {
            b2Mat22 tMat;
            float   rX = input.p2.x - input.p1.x;
            float   rY = input.p2.y - input.p1.y;

            //b2Vec2 v1 = b2Mul(transform, m_v1);
            tMat = transform.R;
            float v1X = transform.position.x + (tMat.col1.x * m_v1.x + tMat.col2.x * m_v1.y);
            float v1Y = transform.position.y + (tMat.col1.y * m_v1.x + tMat.col2.y * m_v1.y);

            //b2Vec2 n = b2Cross(d, 1.0);
            float nX = transform.position.y + (tMat.col1.y * m_v2.x + tMat.col2.y * m_v2.y) - v1Y;
            float nY = -(transform.position.x + (tMat.col1.x * m_v2.x + tMat.col2.x * m_v2.y) - v1X);

            float k_slop = 100.0f * float.MinValue;
            float denom  = -(rX * nX + rY * nY);

            // Cull back facing collision and ignore parallel segments.
            if (denom > k_slop)
            {
                // Does the segment intersect the infinite line associated with this segment?
                float bX = input.p1.x - v1X;
                float bY = input.p1.y - v1Y;
                float a  = (bX * nX + bY * nY);

                if (0.0f <= a && a <= input.maxFraction * denom)
                {
                    float mu2 = -rX * bY + rY * bX;

                    // Does the segment intersect this segment?
                    if (-k_slop * denom <= mu2 && mu2 <= denom * (1.0f + k_slop))
                    {
                        a /= denom;
                        output.fraction = a;
                        float nLen = Mathf.Sqrt(nX * nX + nY * nY);
                        output.normal.x = nX / nLen;
                        output.normal.y = nY / nLen;
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #12
0
    /// Implement b2Shape.
    public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform xf, int childIndex)
    {
        Debug.Assert(childIndex < m_count);

        b2EdgeShape edgeShape = new b2EdgeShape();

        int i1 = childIndex;
        int i2 = childIndex + 1;

        if (i2 == m_count)
        {
            i2 = 0;
        }

        edgeShape.m_vertex1 = m_vertices[i1];
        edgeShape.m_vertex2 = m_vertices[i2];

        return(edgeShape.RayCast(output, input, xf, 0));
    }
예제 #13
0
        public override bool RayCast(out b2RayCastOutput output, b2RayCastInput input, ref b2Transform xf, int childIndex)
        {
            b2EdgeShape edgeShape = new b2EdgeShape();

            output = b2RayCastOutput.Zero;

            int i1 = childIndex;
            int i2 = childIndex + 1;

            if (i2 == Count)
            {
                i2 = 0;
            }

            edgeShape.Vertex1 = Vertices[i1];
            edgeShape.Vertex2 = Vertices[i2];

            b2RayCastOutput co = b2RayCastOutput.Zero;
            bool            b  = edgeShape.RayCast(out co, input, ref xf, 0);

            output = co;
            return(b);
        }
예제 #14
0
        // Collision Detection in Interactive 3D Environments by Gino van den Bergen
        // From Section 3.1.2
        // x = s + a * r
        // norm(x) = radius
        public virtual bool RayCast(out b2RayCastOutput output, b2RayCastInput input,
                                    b2Transform transform, int childIndex)
        {
            output = b2RayCastOutput.Zero;

            b2Vec2 position = transform.p + b2Math.b2Mul(transform.q, m_p);
            b2Vec2 s = input.p1 - position;
            float b = b2Math.b2Dot(s, s) - m_radius * m_radius;

            // Solve quadratic equation.
            b2Vec2 r = input.p2 - input.p1;
            float c = b2Math.b2Dot(s, r);
            float rr = b2Math.b2Dot(r, r);
            float sigma = c * c - rr * b;

            // Check for negative discriminant and short segment.
            if (sigma < 0.0f || rr < b2Settings.b2_epsilon)
            {
                return false;
            }

            // Find the point of intersection of the line with the circle.
            float a = -(c + b2Math.b2Sqrt(sigma));

            // Is the intersection point on the segment?
            if (0.0f <= a && a <= input.maxFraction * rr)
            {
                a /= rr;
                output.fraction = a;
                output.normal = s + a * r;
                output.normal.Normalize();
                return true;
            }

            return false;
        }
예제 #15
0
        /**
         * @inheritDoc
         */
        public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform transform)
        {
            float lower = 0.0f;
            float upper = input.maxFraction;

            float   tX;
            float   tY;
            b2Mat22 tMat;
            b2Vec2  tVec;

            // Put the ray into the polygon's frame of reference. (AS3 Port Manual inlining follows)
            //b2Vec2 p1 = b2MulT(transform.R, segment.p1 - transform.position);
            tX   = input.p1.x - transform.position.x;
            tY   = input.p1.y - transform.position.y;
            tMat = transform.R;
            float p1X = (tX * tMat.col1.x + tY * tMat.col1.y);
            float p1Y = (tX * tMat.col2.x + tY * tMat.col2.y);

            //b2Vec2 p2 = b2MulT(transform.R, segment.p2 - transform.position);
            tX   = input.p2.x - transform.position.x;
            tY   = input.p2.y - transform.position.y;
            tMat = transform.R;
            float p2X = (tX * tMat.col1.x + tY * tMat.col1.y);
            float p2Y = (tX * tMat.col2.x + tY * tMat.col2.y);
            //b2Vec2 d = p2 - p1;
            float dX    = p2X - p1X;
            float dY    = p2Y - p1Y;
            int   index = -1;

            for (int i = 0; i < m_vertexCount; ++i)
            {
                // p = p1 + a * d
                // dot(normal, p - v) = 0
                // dot(normal, p1 - v) + a * dot(normal, d) = 0

                //float32 numerator = b2Dot(m_normals[i], m_vertices[i] - p1);
                tVec = m_vertices[i];
                tX   = tVec.x - p1X;
                tY   = tVec.y - p1Y;
                tVec = m_normals[i];
                float numerator = (tVec.x * tX + tVec.y * tY);
                //float32 denominator = b2Dot(m_normals[i], d);
                float denominator = (tVec.x * dX + tVec.y * dY);

                if (denominator == 0.0f)
                {
                    if (numerator < 0.0f)
                    {
                        return(false);
                    }
                }
                else
                {
                    // Note: we want this predicate without division:
                    // lower < numerator / denominator, where denominator < 0
                    // Since denominator < 0, we have to flip the inequality:
                    // lower < numerator / denominator <==> denominator * lower > numerator.
                    if (denominator < 0.0f && numerator < lower * denominator)
                    {
                        // Increase lower.
                        // The segment enters this half-space.
                        lower = numerator / denominator;
                        index = i;
                    }
                    else if (denominator > 0.0f && numerator < upper * denominator)
                    {
                        // Decrease upper.
                        // The segment exits this half-space.
                        upper = numerator / denominator;
                    }
                }

                /*if (upper < lower - float.MinValue)
                 * {
                 *      return false;
                 * }*/
                //改
                if (upper < lower)
                {
                    return(false);
                }
            }

            //b2Settings.b2Assert(0.0 <= lower && lower <= input.maxLambda);

            if (index >= 0)
            {
                output.fraction = lower;
                //output.normal = b2Mul(transform.R, m_normals[index]);
                tMat            = transform.R;
                tVec            = m_normals[index];
                output.normal.x = (tMat.col1.x * tVec.x + tMat.col2.x * tVec.y);
                output.normal.y = (tMat.col1.y * tVec.x + tMat.col2.y * tVec.y);
                return(true);
            }

            return(false);
        }
예제 #16
0
        // p = p1 + t * d
        // v = v1 + s * e
        // p1 + t * d = v1 + s * e
        // s * e - t * d = p1 - v1
        public override bool RayCast(out b2RayCastOutput output, b2RayCastInput input,
                                     b2Transform xf, int childIndex)
        {
            output = b2RayCastOutput.Zero;

            // Put the ray into the edge's frame of reference.
            b2Vec2 p1 = b2Math.b2MulT(xf.q, input.p1 - xf.p);
            b2Vec2 p2 = b2Math.b2MulT(xf.q, input.p2 - xf.p);
            b2Vec2 d  = p2 - p1;

            b2Vec2 v1     = m_vertex1;
            b2Vec2 v2     = m_vertex2;
            b2Vec2 e      = v2 - v1;
            b2Vec2 normal = b2Vec2.Zero; // new b2Vec2(e.y, -e.x);

            normal.m_x = e.m_y;
            normal.m_y = -e.m_x;
            normal.Normalize();

            // q = p1 + t * d
            // dot(normal, q - v1) = 0
            // dot(normal, p1 - v1) + t * dot(normal, d) = 0
            b2Vec2 diff        = v1 - p1;
            float  numerator   = b2Math.b2Dot(ref normal, ref diff);
            float  denominator = b2Math.b2Dot(ref normal, ref d);

            if (denominator == 0.0f)
            {
                return(false);
            }

            float t = numerator / denominator;

            if (t < 0.0f || input.maxFraction < t)
            {
                return(false);
            }

            b2Vec2 q = p1 + t * d;

            // q = v1 + s * r
            // s = dot(q - v1, r) / dot(r, r)
            b2Vec2 r  = v2 - v1;
            float  rr = r.LengthSquared; // b2Math.b2Dot(r, r);

            if (rr == 0.0f)
            {
                return(false);
            }

            diff = q - v1;
            float s = b2Math.b2Dot(ref diff, ref r) / rr;

            if (s < 0.0f || 1.0f < s)
            {
                return(false);
            }

            output.fraction = t;
            if (numerator > 0.0f)
            {
                output.normal = -normal;
            }
            else
            {
                output.normal = normal;
            }
            return(true);
        }
예제 #17
0
        public override bool RayCast(out b2RayCastOutput output, b2RayCastInput input, ref b2Transform xf, int childIndex)
        {
            output = b2RayCastOutput.Zero;
            // Put the ray into the polygon's frame of reference.
            b2Vec2 p1 = b2Math.b2MulT(xf.q, input.p1 - xf.p);
            b2Vec2 p2 = b2Math.b2MulT(xf.q, input.p2 - xf.p);
            b2Vec2 d = p2 - p1;

            float lower = 0.0f, upper = input.maxFraction;

            int index = -1;

            for (int i = 0; i < m_vertexCount; ++i)
            {
                // p = p1 + a * d
                // dot(normal, p - v) = 0
                // dot(normal, p1 - v) + a * dot(normal, d) = 0
                float numerator = b2Math.b2Dot(Normals[i], Vertices[i] - p1);
                float denominator = b2Math.b2Dot(Normals[i], d);

                if (denominator == 0.0f)
                {
                    if (numerator < 0.0f)
                    {
                        return false;
                    }
                }
                else
                {
                    // Note: we want this predicate without division:
                    // lower < numerator / denominator, where denominator < 0
                    // Since denominator < 0, we have to flip the inequality:
                    // lower < numerator / denominator <==> denominator * lower > numerator.
                    if (denominator < 0.0f && numerator < lower * denominator)
                    {
                        // Increase lower.
                        // The segment enters this half-space.
                        lower = numerator / denominator;
                        index = i;
                    }
                    else if (denominator > 0.0f && numerator < upper * denominator)
                    {
                        // Decrease upper.
                        // The segment exits this half-space.
                        upper = numerator / denominator;
                    }
                }

                // The use of epsilon here causes the assert on lower to trip
                // in some cases. Apparently the use of epsilon was to make edge
                // shapes work, but now those are handled separately.
                //if (upper < lower - b2_epsilon)
                if (upper < lower)
                {
                    return false;
                }
            }

            //    Debug.Assert(0.0f <= lower && lower <= input.maxFraction);

            if (index >= 0)
            {
                output.fraction = lower;
                output.normal = b2Math.b2Mul(xf.q, Normals[index]);
                return true;
            }

            return false;
        }
예제 #18
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(b2RayCastOutput obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
예제 #19
0
 public virtual bool RayCast(out b2RayCastOutput output, b2RayCastInput input, int childIndex)
 {
     return(m_shape.RayCast(out output, input, m_body.Transform, childIndex));
 }
예제 #20
0
        public override bool RayCast(out b2RayCastOutput output, b2RayCastInput input,
                                    b2Transform xf, int childIndex)
        {
            b2EdgeShape edgeShape = new b2EdgeShape();
            output = b2RayCastOutput.Zero;

            int i1 = childIndex;
            int i2 = childIndex + 1;
            if (i2 == m_count)
            {
                i2 = 0;
            }

            edgeShape.Vertex1 = m_vertices[i1];
            edgeShape.Vertex2 = m_vertices[i2];

            b2RayCastOutput co = b2RayCastOutput.Zero;
            bool b = edgeShape.RayCast(out co, input, xf, 0);
            output = co;
            return (b);
        }
예제 #21
0
 /// Cast a ray against a child shape.
 /// @param output the ray-cast results.
 /// @param input the ray-cast input parameters.
 /// @param transform the transform to be applied to the shape.
 /// @param childIndex the child shape index
 public abstract bool RayCast(out b2RayCastOutput output, b2RayCastInput input,
                     b2Transform transform, int childIndex);
예제 #22
0
 /// Cast a ray against a child shape.
 /// @param output the ray-cast results.
 /// @param input the ray-cast input parameters.
 /// @param transform the transform to be applied to the shape.
 /// @param childIndex the child shape index
 public abstract bool RayCast(out b2RayCastOutput output, b2RayCastInput input, ref b2Transform transform, int childIndex);
예제 #23
0
 /**
  * Perform a ray cast against this shape.
  * @param output the ray-cast results.
  * @param input the ray-cast input parameters.
  */
 public bool RayCast(b2RayCastOutput output, b2RayCastInput input)
 {
     return(m_shape.RayCast(output, input, m_body.GetTransform()));
 }
예제 #24
0
        // p = p1 + t * d
        // v = v1 + s * e
        // p1 + t * d = v1 + s * e
        // s * e - t * d = p1 - v1
        public override bool RayCast(out b2RayCastOutput output, b2RayCastInput input,
                                    b2Transform xf, int childIndex)
        {
            output = b2RayCastOutput.Zero;

            // Put the ray into the edge's frame of reference.
            b2Vec2 p1 = b2Math.b2MulT(xf.q, input.p1 - xf.p);
            b2Vec2 p2 = b2Math.b2MulT(xf.q, input.p2 - xf.p);
            b2Vec2 d = p2 - p1;

            b2Vec2 v1 = m_vertex1;
            b2Vec2 v2 = m_vertex2;
            b2Vec2 e = v2 - v1;
            b2Vec2 normal = new b2Vec2(e.y, -e.x);
            normal.Normalize();

            // q = p1 + t * d
            // dot(normal, q - v1) = 0
            // dot(normal, p1 - v1) + t * dot(normal, d) = 0
            float numerator = b2Math.b2Dot(normal, v1 - p1);
            float denominator = b2Math.b2Dot(normal, d);

            if (denominator == 0.0f)
            {
                return false;
            }

            float t = numerator / denominator;
            if (t < 0.0f || input.maxFraction < t)
            {
                return false;
            }

            b2Vec2 q = p1 + t * d;

            // q = v1 + s * r
            // s = dot(q - v1, r) / dot(r, r)
            b2Vec2 r = v2 - v1;
            float rr = b2Math.b2Dot(r, r);
            if (rr == 0.0f)
            {
                return false;
            }

            float s = b2Math.b2Dot(q - v1, r) / rr;
            if (s < 0.0f || 1.0f < s)
            {
                return false;
            }

            output.fraction = t;
            if (numerator > 0.0f)
            {
                output.normal = -normal;
            }
            else
            {
                output.normal = normal;
            }
            return true;
        }
예제 #25
0
 /// Cast a ray against this shape.
 /// @param output the ray-cast results.
 /// @param input the ray-cast input parameters.
 public bool RayCast(b2RayCastOutput output, b2RayCastInput input, int childIndex)
 {
     return(m_shape.RayCast(output, input, m_body.GetTransform(), childIndex));
 }
예제 #26
0
	/**
	 * Cast a ray against this shape.
	 * @param output the ray-cast results.
	 * @param input the ray-cast input parameters.
	 * @param transform the transform to be applied to the shape.
	 */
	virtual public bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform transform)
	{
		return false;
	}
예제 #27
0
    // From Real-time Collision Detection, p179.
    public bool RayCast(b2RayCastOutput output, b2RayCastInput input)
    {
        float tmin = -float.MaxValue;
        float tmax = float.MaxValue;

        b2Vec2 p    = new b2Vec2(input.p1);
        b2Vec2 d    = input.p2 - input.p1;
        b2Vec2 absD = Utils.b2Abs(d);

        b2Vec2 normal = new b2Vec2();

        for (int i = 0; i < 2; ++i)
        {
            if (absD[i] < float.Epsilon)
            {
                // Parallel.
                if (p[i] < lowerBound[i] || upperBound[i] < p[i])
                {
                    return(false);
                }
            }
            else
            {
                float inv_d = 1.0f / d[i];
                float t1    = (lowerBound[i] - p[i]) * inv_d;
                float t2    = (upperBound[i] - p[i]) * inv_d;

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

                if (t1 > t2)
                {
                    Utils.b2Swap(ref t1, ref t2);
                    s = 1.0f;
                }

                // Push the min up
                if (t1 > tmin)
                {
                    normal.SetZero();
                    normal[i] = s;
                    tmin      = t1;
                }

                // Pull the max down
                tmax = Utils.b2Min(tmax, t2);

                if (tmin > tmax)
                {
                    return(false);
                }
            }
        }

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

        // Intersection.
        output.fraction = tmin;


        output.normal = normal;
        return(true);
    }
예제 #28
0
        public override bool RayCast(out b2RayCastOutput output, b2RayCastInput input, ref b2Transform xf, int childIndex)
        {
            output = b2RayCastOutput.Zero;
            // Put the ray into the polygon's frame of reference.
            b2Vec2 p1 = b2Math.b2MulT(xf.q, input.p1 - xf.p);
            b2Vec2 p2 = b2Math.b2MulT(xf.q, input.p2 - xf.p);
            b2Vec2 d  = p2 - p1;

            float lower = 0.0f, upper = input.maxFraction;

            int index = -1;

            for (int i = 0; i < m_vertexCount; ++i)
            {
                // p = p1 + a * d
                // dot(normal, p - v) = 0
                // dot(normal, p1 - v) + a * dot(normal, d) = 0
                float numerator   = b2Math.b2Dot(Normals[i], Vertices[i] - p1);
                float denominator = b2Math.b2Dot(Normals[i], d);

                if (denominator == 0.0f)
                {
                    if (numerator < 0.0f)
                    {
                        return(false);
                    }
                }
                else
                {
                    // Note: we want this predicate without division:
                    // lower < numerator / denominator, where denominator < 0
                    // Since denominator < 0, we have to flip the inequality:
                    // lower < numerator / denominator <==> denominator * lower > numerator.
                    if (denominator < 0.0f && numerator < lower * denominator)
                    {
                        // Increase lower.
                        // The segment enters this half-space.
                        lower = numerator / denominator;
                        index = i;
                    }
                    else if (denominator > 0.0f && numerator < upper * denominator)
                    {
                        // Decrease upper.
                        // The segment exits this half-space.
                        upper = numerator / denominator;
                    }
                }

                // The use of epsilon here causes the assert on lower to trip
                // in some cases. Apparently the use of epsilon was to make edge
                // shapes work, but now those are handled separately.
                //if (upper < lower - b2_epsilon)
                if (upper < lower)
                {
                    return(false);
                }
            }

            //    Debug.Assert(0.0f <= lower && lower <= input.maxFraction);

            if (index >= 0)
            {
                output.fraction = lower;
                output.normal   = b2Math.b2Mul(xf.q, Normals[index]);
                return(true);
            }

            return(false);
        }
예제 #29
0
    /// Implement b2Shape.

    // p = p1 + t * d
    // v = v1 + s * e
    // p1 + t * d = v1 + s * e
    // s * e - t * d = p1 - v1
    public override bool RayCast(b2RayCastOutput output, b2RayCastInput input, b2Transform xf, int childIndex)
    {
        // Put the ray into the edge's frame of reference.
        b2Vec2 p1 = Utils.b2MulT(xf.q, input.p1 - xf.p);
        b2Vec2 p2 = Utils.b2MulT(xf.q, input.p2 - xf.p);
        b2Vec2 d  = p2 - p1;

        b2Vec2 v1     = new b2Vec2(m_vertex1);
        b2Vec2 v2     = new b2Vec2(m_vertex2);
        b2Vec2 e      = v2 - v1;
        b2Vec2 normal = new b2Vec2(e.y, -e.x);

        normal.Normalize();

        // q = p1 + t * d
        // dot(normal, q - v1) = 0
        // dot(normal, p1 - v1) + t * dot(normal, d) = 0
        float numerator   = Utils.b2Dot(normal, v1 - p1);
        float denominator = Utils.b2Dot(normal, d);

        if (denominator == 0.0f)
        {
            return(false);
        }

        float t = numerator / denominator;

        if (t < 0.0f || input.maxFraction < t)
        {
            return(false);
        }

        b2Vec2 q = p1 + t * d;

        // q = v1 + s * r
        // s = dot(q - v1, r) / dot(r, r)
        b2Vec2 r  = v2 - v1;
        float  rr = Utils.b2Dot(r, r);

        if (rr == 0.0f)
        {
            return(false);
        }

        float s = Utils.b2Dot(q - v1, r) / rr;

        if (s < 0.0f || 1.0f < s)
        {
            return(false);
        }

        output.fraction = t;
        if (numerator > 0.0f)
        {
            output.normal = -Utils.b2Mul(xf.q, normal);
        }
        else
        {
            output.normal = Utils.b2Mul(xf.q, normal);
        }
        return(true);
    }