예제 #1
0
 /**
    * Cast a ray against this shape.
    *
    * @param output the ray-cast results.
    * @param input the ray-cast input parameters.
    * @param output
    * @param input
    */
 public bool raycast(RayCastOutput output, RayCastInput input, int childIndex)
 {
     return m_shape.raycast(output, input, m_body.m_xf, childIndex);
 }
예제 #2
0
파일: AABB.cs 프로젝트: Nomad1/sharpbox2d
        /**
           * 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;
        }
예제 #3
0
파일: World.cs 프로젝트: Nomad1/sharpbox2d
        public float raycastCallback(RayCastInput input, int nodeId)
        {
            Object userData = broadPhase.getUserData(nodeId);
            FixtureProxy proxy = (FixtureProxy) userData;
            Fixture fixture = proxy.fixture;
            int index = proxy.childIndex;
            bool hit = fixture.raycast(output, input, index);

            if (hit)
            {
                float fraction = output.fraction;
                // Vec2 point = (1.0f - fraction) * input.p1 + fraction * input.p2;
                temp.set(input.p2);
                temp.mulLocal(fraction);
                point.set(input.p1);
                point.mulLocal(1 - fraction);
                point.addLocal(temp);
                return callback.reportFixture(fixture, point, output.normal, fraction);
            }

            return input.maxFraction;
        }
예제 #4
0
파일: AABB.cs 프로젝트: Nomad1/sharpbox2d
 /**
    * @deprecated please use {@link #raycast(RayCastOutput, RayCastInput, IWorldPool)} for better
    *             performance
    * @param output
    * @param input
    * @return
    */
 public bool raycast(RayCastOutput output, RayCastInput input)
 {
     return raycast(output, input, new DefaultWorldPool(4, 4));
 }
예제 #5
0
 public void set(RayCastInput rci)
 {
     p1.set(rci.p1);
     p2.set(rci.p2);
     maxFraction = rci.maxFraction;
 }
예제 #6
0
        public float raycastCallback(RayCastInput input,
            int proxyId)
        {
            Actor actor = (Actor) m_tree.getUserData(proxyId);

            RayCastOutput output = new RayCastOutput();
            bool hit = actor.aabb.raycast(output, input, getWorld().getPool());

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

            return input.maxFraction;
        }
예제 #7
0
        public void RayCast()
        {
            m_rayActor = null;

            RayCastInput input = new RayCastInput();
            input.set(m_rayCastInput);

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

            // Brute force ray cast.
            Actor bruteActor = null;
            RayCastOutput bruteOutput = new RayCastOutput();
            for (int i = 0; i < _e_actorCount; ++i)
            {
                if (m_actors[i].proxyId == -1)
                {
                    continue;
                }

                RayCastOutput output = new RayCastOutput();
                bool hit = m_actors[i].aabb.raycast(output, input,
                    getWorld().getPool());
                if (hit)
                {
                    bruteActor = m_actors[i];
                    bruteOutput = output;
                    input.maxFraction = output.fraction;
                }
            }

            if (bruteActor != null)
            {
                if (MathUtils.abs(bruteOutput.fraction
                                  - m_rayCastOutput.fraction) > Settings.EPSILON)
                {
                    Debug.WriteLine("wrong!");
                    Debug.Assert(MathUtils.abs(bruteOutput.fraction
                                               - m_rayCastOutput.fraction) <= 20*Settings.EPSILON);
                }

            }
        }
예제 #8
0
        public override void initTest(bool argDeserialized)
        {
            worldExtent = 15.0f;
            m_proxyExtent = 0.5f;

            m_tree = new DynamicTree();

            for (int i = 0; i < _e_actorCount; ++i)
            {
                Actor actor = m_actors[i] = new Actor();
                GetRandomAABB(actor.aabb);
                actor.proxyId = m_tree.createProxy(actor.aabb, actor);
            }

            m_stepCount = 0;

            float h = worldExtent;
            m_queryAABB = new AABB();
            m_queryAABB.lowerBound.set(-3.0f, -4.0f + h);
            m_queryAABB.upperBound.set(5.0f, 6.0f + h);

            m_rayCastInput = new RayCastInput();
            m_rayCastInput.p1.set(-5.0f, 5.0f + h);
            m_rayCastInput.p2.set(7.0f, -4.0f + h);
            // m_rayCastInput.p1.set(0.0f, 2.0f + h);
            // m_rayCastInput.p2.set(0.0f, -2.0f + h);
            m_rayCastInput.maxFraction = 1.0f;

            m_rayCastOutput = new RayCastOutput();

            m_automated = false;
        }