Ejemplo n.º 1
0
        public bool RayCast(out b2RayCastOutput output, b2RayCastInput input)
        {
            float tmin = -float.MaxValue;
            float tmax = float.MaxValue;

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

            b2Vec2 normal = new b2Vec2(0,0);

            for (int i = 0; i < 2; ++i)
            {
                float p_i, lb, ub, d_i, absd_i;
                p_i = (i == 0 ? p.x : p.y);
                lb = (i == 0 ? m_lowerBound.x : m_lowerBound.y);
                ub = (i == 0 ? m_upperBound.x : m_upperBound.y);
                absd_i = (i == 0 ? absD.x : absD.y);
                d_i = (i == 0 ? d.x : d.y);

                if (absd_i < b2Settings.b2_epsilon)
                {
                    // Parallel.
                    if (p_i < lb || ub < p_i)
                    {
                        output.fraction = 0f;
                        output.normal = new b2Vec2(0, 0);
                        return false;
                    }
                }
                else
                {
                    float inv_d = 1.0f / d_i;
                    float t1 = (lb - p_i) * inv_d;
                    float t2 = (ub - p_i) * inv_d;

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

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

                    // Push the min up
                    if (t1 > tmin)
                    {
                        normal.SetZero();
                        if (i == 0)
                        {
                            normal.x = s;
                        }
                        else
                        {
                            normal.y = s;
                        }
                        tmin = t1;
                    }

                    // Pull the max down
                    tmax = Math.Min(tmax, t2);

                    if (tmin > tmax)
                    {
                        output.fraction = 0f;
                        output.normal = new b2Vec2(0, 0);
                        return false;
                    }
                }
            }

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

            // Intersection.
            output.fraction = tmin;
            output.normal = normal;
            return true;
        }
Ejemplo n.º 2
0
 public virtual bool RayCast(out b2RayCastOutput output, b2RayCastInput input, int childIndex)
 {
     return m_shape.RayCast(out output, input, m_body.Transform, childIndex);
 }
Ejemplo n.º 3
0
        public bool RayCast(out b2RayCastOutput output, b2RayCastInput input)
        {
            float tmin = -float.MaxValue;
            float tmax = float.MaxValue;

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

            b2Vec2 normal = new b2Vec2(0, 0);

            for (int i = 0; i < 2; ++i)
            {
                float p_i, lb, ub, d_i, absd_i;
                p_i    = (i == 0 ? p.x : p.y);
                lb     = (i == 0 ? m_lowerBound.x : m_lowerBound.y);
                ub     = (i == 0 ? m_upperBound.x : m_upperBound.y);
                absd_i = (i == 0 ? absD.x : absD.y);
                d_i    = (i == 0 ? d.x : d.y);

                if (absd_i < b2Settings.b2_epsilon)
                {
                    // Parallel.
                    if (p_i < lb || ub < p_i)
                    {
                        output.fraction = 0f;
                        output.normal   = new b2Vec2(0, 0);
                        return(false);
                    }
                }
                else
                {
                    float inv_d = 1.0f / d_i;
                    float t1    = (lb - p_i) * inv_d;
                    float t2    = (ub - p_i) * inv_d;

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

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

                    // Push the min up
                    if (t1 > tmin)
                    {
                        normal.SetZero();
                        if (i == 0)
                        {
                            normal.x = s;
                        }
                        else
                        {
                            normal.y = s;
                        }
                        tmin = t1;
                    }

                    // Pull the max down
                    tmax = Math.Min(tmax, t2);

                    if (tmin > tmax)
                    {
                        output.fraction = 0f;
                        output.normal   = new b2Vec2(0, 0);
                        return(false);
                    }
                }
            }

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

            // Intersection.
            output.fraction = tmin;
            output.normal   = normal;
            return(true);
        }
Ejemplo n.º 4
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);
            }
        }
Ejemplo n.º 5
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;
        }
Ejemplo n.º 6
0
        // From Real-time Collision Detection, p179.

        /**
         * Perform a precise raycast against the AABB.
         */
        public bool RayCast(b2RayCastOutput output, b2RayCastInput input)
        {
            float tmin = -float.MaxValue;
            //float tmax = float.MaxValue;

            float pX    = input.p1.x;
            float pY    = input.p1.y;
            float dX    = input.p2.x - input.p1.x;
            float dY    = input.p2.y - input.p1.y;
            float absDX = Mathf.Abs(dX);
            float absDY = Mathf.Abs(dY);

            b2Vec2 normal = output.normal;

            float inv_d;
            float t1;
            float t2;
            float t3;
            float s;

            //x
            if (absDX < float.MinValue)
            {
                // Parallel.
                if (pX < lowerBound.x || upperBound.x < pX)
                {
                    return(false);
                }
            }
            else
            {
                inv_d = 1.0f / dX;
                t1    = (lowerBound.x - pX) * inv_d;
                t2    = (upperBound.x - pX) * inv_d;

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

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

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

                // Pull the max down
                float tmax = Mathf.Min(float.MaxValue, t2);

                if (tmin > tmax)
                {
                    return(false);
                }
            }
            //y
            if (absDY < float.MinValue)
            {
                // Parallel.
                if (pY < lowerBound.y || upperBound.y < pY)
                {
                    return(false);
                }
            }
            else
            {
                inv_d = 1.0f / dY;
                t1    = (lowerBound.y - pY) * inv_d;
                t2    = (upperBound.y - pY) * inv_d;

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

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

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

                // Pull the max down
                float tmax = Mathf.Min(float.MaxValue, t2);

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

            output.fraction = tmin;
            return(true);
        }