Example #1
0
        private void checkBox(Aabb box)
        {
            IEnumerable <LineSeg> segs = Gen <LineSeg>(delegate() { return(LineSeg.FromEndpoints(PointInside(box), PointOutside(box))); });

            foreach (LineSeg ls in Take(100, segs))
            {
                Assert.IsTrue(box.Intersects(ls));

                LineSeg outline = new LineSeg(ls.End, ls.Dir);
                Assert.IsFalse(box.Intersects(outline));

                LineSeg swapped = LineSeg.FromEndpoints(ls.End, ls.Start);
                Assert.IsTrue(box.Intersects(swapped));

                // neither endpoint is inside but the line def. crosses
                LineSeg crossing = new LineSeg(ls.Start - ls.Dir, ls.Dir * 2.0);
                Assert.IsTrue(box.Intersects(crossing));

                // Shift it outside of the box by moving it sideways a min amt...
                double shift_length = Math.Sqrt(box.W * box.W + box.H * box.H);
                Vector shift        = shift_length * crossing.Dir.Normalize().Perp;

                LineSeg out1 = new LineSeg(crossing.Start + shift,
                                           crossing.Dir);
                Assert.IsFalse(box.Intersects(out1));
            }
        }
Example #2
0
    public bool Query(Aabb bounds, QueryCallbcak callback = null)
    {
        m_stack.Clear();
        m_stack.Push(m_root);

        bool touchedAnyBounds = false;

        while (m_stack.Count > 0)
        {
            int index = m_stack.Pop();
            if (index == Null)
            {
                continue;
            }

            Aabb tightBounds = m_nodes[index].Bounds;
            tightBounds.Expand(-FatBoundsRadius);
            if (!Aabb.Intersects(bounds, tightBounds))
            {
                continue;
            }

            if (m_nodes[index].IsLeaf)
            {
                touchedAnyBounds = true;

                bool proceed =
                    callback != null
            ? callback(m_nodes[index].UserData)
            : true;

                if (!proceed)
                {
                    return(true);
                }
            }
            else
            {
                m_stack.Push(m_nodes[index].ChildA);
                m_stack.Push(m_nodes[index].ChildB);
            }
        }

        return(touchedAnyBounds);
    }
Example #3
0
    public bool RayCast(Vector3 from, Vector3 to, RayCastCallback callback = null)
    {
        Vector3 r = to - from;

        r.Normalize();

        float maxFraction = 1.0f;

        // v is perpendicular to the segment.
        Vector3 v    = VectorUtil.FindOrthogonal(r).normalized;
        Vector3 absV = VectorUtil.Abs(v);

        // build a bounding box for the segment.
        Aabb rayBounds = Aabb.Empty;

        rayBounds.Include(from);
        rayBounds.Include(to);

        m_stack.Clear();
        m_stack.Push(m_root);

        bool hitAnyBounds = false;

        while (m_stack.Count > 0)
        {
            int index = m_stack.Pop();
            if (index == Null)
            {
                continue;
            }

            if (!Aabb.Intersects(m_nodes[index].Bounds, rayBounds))
            {
                continue;
            }

            // Separating axis for segment (Gino, p80).
            // |dot(v, a - c)| > dot(|v|, h)
            Vector3 c          = m_nodes[index].Bounds.Center;
            Vector3 h          = m_nodes[index].Bounds.HalfExtents;
            float   separation = Mathf.Abs(Vector3.Dot(v, from - c)) - Vector3.Dot(absV, h);
            if (separation > 0.0f)
            {
                continue;
            }

            if (m_nodes[index].IsLeaf)
            {
                Aabb tightBounds = m_nodes[index].Bounds;
                tightBounds.Expand(-FatBoundsRadius);
                float t = tightBounds.RayCast(from, to, maxFraction);
                if (t < 0.0f)
                {
                    continue;
                }

                hitAnyBounds = true;

                float newMaxFraction =
                    callback != null
            ? callback(from, to, m_nodes[index].UserData)
            : maxFraction;

                if (newMaxFraction >= 0.0f)
                {
                    // Update segment bounding box.
                    maxFraction = newMaxFraction;
                    Vector3 newTo = from + maxFraction * (to - from);
                    rayBounds.Min = VectorUtil.Min(from, newTo);
                    rayBounds.Max = VectorUtil.Max(from, newTo);
                }
            }
            else
            {
                m_stack.Push(m_nodes[index].ChildA);
                m_stack.Push(m_nodes[index].ChildB);
            }
        }

        return(hitAnyBounds);
    }
Example #4
0
 public bool Intersects(LineSeg l)
 {
     return(m_bound.Intersects(l));
 }