public void CullLocalObjects(List <T> outlist, object cull)
 {
     foreach (KeyValuePair <T, object> b in objct_to_boundings)
     {
         if (Intersection.Intersect(b.Value, cull))
         {
             outlist.Add(b.Key);
         }
     }
 }
Esempio n. 2
0
        public override List <T> Cull(object bounding)
        {
            List <T> l = new List <T>();

            foreach (var v in entities)
            {
                if (Intersection.Intersect(v.Value, bounding))
                {
                    l.Add(v.Key);
                }
            }
            return(l);
        }
        public static RSpatialRelation Relation(BoundingBox a, Ray b)
        {
            object o;

            if (Intersection.Intersect(a, b, out o))
            {
                return(RSpatialRelation.Intersect);
            }
            else
            {
                return(RSpatialRelation.Outside);
            }
        }
        public override bool Intersect(SlimDX.Ray ray, float maxDistance, out float dist, out T obj)
        {
            T     minObj = default(T);
            float minD   = maxDistance + float.Epsilon;     // we are only using less-than-checks
            bool  hit    = false;

            if (OptimizeGroundIntersection && ray.Direction.X == 0 && ray.Direction.Y == 0)
            {
                // set minD by doing ground intersection here
                float height = GroundHeight(Common.Math.ToVector2(ray.Position));
                float d      = ray.Position.Z - height;
                if (ray.Direction.Z < 0 && d < minD)
                {
                    minD = d;
                    hit  = true;
                }
                // Todo: obj?
            }
            if (root != null)
            {
                hit |= root.Intersect(ray, ref minD, ref minObj);
            }

            foreach (var nb in nonfittableObjects.Keys)
            {
                RayIntersection rOut;
                var             bounding = nonfittableObjects[nb];
                if (bounding.Intersectable)
                {
                    if (Intersection.Intersect <RayIntersection>(bounding.Bounding, ray, out rOut) && rOut.Distance < minD)
                    {
                        minD   = rOut.Distance;
                        minObj = (T)rOut.Userdata;
                        hit    = true;
                    }
                }
            }

            dist = minD;
            obj  = minObj;

            return(hit);
        }
        public override List <T> Cull(object bounding)
        {
            List <T> l = new List <T>();

            if (root != null)
            {
                root.Cull(l, bounding);
            }
            foreach (var nb in nonfittableObjects.Keys)
            {
                if (nonfittableObjects[nb].NeverCulled)
                {
                    l.Add(nb);
                }
                else
                if (Intersection.Intersect(bounding, nonfittableObjects[nb].Bounding))
                {
                    l.Add(nb);
                }
            }
            return(l);
        }
Esempio n. 6
0
 public void Cull(List <T> culled, BoundingSphere bounding)
 {
     if (objects != null)
     {
         foreach (var p in objects)
         {
             if (Intersection.Intersect(p.Second, bounding))
             {
                 culled.Add(p.First);
             }
         }
     }
     else
     {
         if (Value(bounding.Center, axis) - bounding.Radius < splitter)
         {
             left.Cull(culled, bounding);
         }
         if (Value(bounding.Center, axis) + bounding.Radius > splitter)
         {
             right.Cull(culled, bounding);
         }
     }
 }
            public bool Intersect(Ray r, ref float minD, ref T minObj)
            {
                float d;
                // run intersection with local objects
                RayIntersection rOut;
                bool            methodHit = false;

                foreach (KeyValuePair <T, object> b in objct_to_boundings)
                {
                    var gp = b.Value as Common.Bounding.GroundPiece;

                    if (gp != null)
                    {
                        if (!quadtree.OptimizeGroundIntersection || r.Direction.X != 0 || r.Direction.Y != 0)
                        {
                            bool hit = Intersection.Intersect(gp.Bounding, r, minD, out rOut);

                            if (hit && rOut.Distance < minD)
                            {
                                minD      = rOut.Distance;
                                minObj    = b.Key;
                                methodHit = true;
                            }
                        }
                    }
                    else if (Intersection.Intersect(b.Value, r, minD, out rOut) && rOut.Distance < minD)
                    {
                        minD      = rOut.Distance;
                        minObj    = b.Key;
                        methodHit = true;
                    }
                }

                if (depth > 0)
                {
                    // look at nodes that are close to the ray first
                    //SortedList<float, Node> proximityList = new SortedList<float, Quadtree<T>.Node>(4);
                    List <Common.Tuple <float, Node> > proximityList = new List <Tuple <float, Quadtree <T> .Node> >(4);
                    for (int i = 0; i < 4; i++)
                    {
                        if (BoundingBox.Intersects(children[i].bounding, r, out d) && d < minD)
                        {
                            proximityList.Add(new Common.Tuple <float, Node>(d, children[i]));
                        }
                    }
                    float oldMinD = minD;
                    proximityList.Sort((a, b) => { return(a.First.CompareTo(b.First)); });
                    foreach (var kvp in proximityList)
                    {
                        bool hit  = kvp.Second.Intersect(r, ref minD, ref minObj);
                        bool test = hit && minD < oldMinD;
                        //if (!hit && minD <= oldMinD)
                        //    System.Diagnostics.Debugger.Break();
                        if (test)     // means a hit was found and we know that everything behind this will be farther away
                        {
                            methodHit = true;
                            break;
                        }
                    }
                }

                return(methodHit);
            }
        public static RSpatialRelation Relation(BoundingBox a, Bounding.Cylinder b)
        {
            // NOTE: Not tested thoroughly!

            /*
             * This all is based on finding the intersections between the axises of the box
             * */

            float m, n;

            float boxMinZ = a.Minimum.Z; float boxMaxZ = a.Maximum.Z;
            float cylMinZ = b.Position.Z; float cylMaxZ = cylMinZ + b.Height;

            RSpatialRelation verticalRelation = Relation1DLines(boxMinZ, boxMaxZ, cylMinZ, cylMaxZ);

            if (verticalRelation == RSpatialRelation.Outside)
            {
                return(RSpatialRelation.Outside);
            }

            // from this point on we know that the cylinder at least intersects the box on the vertical axis

            //X Axis, first find intersections
            CylP x1 = CylP.NotIntersecting;

            if (Math.CircleXAxisIntersection(b.Position, b.Radius, a.Minimum.Y, out m, out n))
            {
                if (m > a.Maximum.X || n < a.Minimum.X)
                {
                    x1 = CylP.Outside;
                }
                else if (m < a.Minimum.X && n > a.Maximum.X)
                {
                    x1 = CylP.AInsideB;
                }
                else
                {
                    return(RSpatialRelation.Intersect);
                }
            }

            CylP x2 = CylP.NotIntersecting;

            if (Math.CircleXAxisIntersection(b.Position, b.Radius, a.Maximum.Y, out m, out n))
            {
                if (m > a.Maximum.X || n < a.Minimum.X)
                {
                    x2 = CylP.Outside;
                }
                else if (m < a.Minimum.X && n > a.Maximum.X)
                {
                    x2 = CylP.AInsideB;
                }
                else
                {
                    return(RSpatialRelation.Intersect);
                }
            }

            //Y Axis, first find intersections
            CylP y1 = CylP.NotIntersecting;

            if (Math.CircleYAxisIntersection(b.Position, b.Radius, a.Minimum.X, out m, out n))
            {
                if (m > a.Maximum.Y || n < a.Minimum.Y)
                {
                    y1 = CylP.Outside;
                }
                else if (m < a.Minimum.Y && n > a.Maximum.Y)
                {
                    y1 = CylP.AInsideB;
                }
                else
                {
                    return(RSpatialRelation.Intersect);
                }
            }

            CylP y2 = CylP.NotIntersecting;

            if (Math.CircleYAxisIntersection(b.Position, b.Radius, a.Maximum.X, out m, out n))
            {
                if (m > a.Maximum.Y || n < a.Minimum.Y)
                {
                    y2 = CylP.Outside;
                }
                else if (m < a.Minimum.Y && n > a.Maximum.Y)
                {
                    y2 = CylP.AInsideB;
                }
                else
                {
                    return(RSpatialRelation.Intersect);
                }
            }

            if (x1 == CylP.AInsideB && x2 == CylP.AInsideB && y1 == CylP.AInsideB && y2 == CylP.AInsideB)
            {
                if (verticalRelation == RSpatialRelation.AInsideB)
                {
                    return(RSpatialRelation.AInsideB);
                }
                return(RSpatialRelation.Intersect);
            }

            //var horizontalRelation = RectCircleRelation(new RectangleF(new PointF(a.Minimum.X, a.Minimum.Y), new SizeF(a.Maximum.X - a.Minimum.X, a.Maximum.Y - a.Minimum.Y)), b);

            //if (horizontalRelation == RSpatialRelation.Outside)
            //    return RSpatialRelation.Outside;
            //else if (horizontalRelation == verticalRelation)
            //    return horizontalRelation;
            //else
            //    return RSpatialRelation.Intersect;

            if (x1 == CylP.NotIntersecting && x2 == CylP.NotIntersecting &&
                y1 == CylP.NotIntersecting && y2 == CylP.NotIntersecting &&
                Intersection.Intersect(a, Math.ToVector2(b.Position)))
            {
                if (verticalRelation == RSpatialRelation.BInsideA)
                {
                    return(RSpatialRelation.BInsideA);
                }
                return(RSpatialRelation.Intersect);
            }

            else
            {
                return(RSpatialRelation.Outside);
            }
#if false
            //We start by checking if the circle is so large it covers the whole rectangle
            bool intersects = false, ainsideb = true;

            if (p.CullPoint(position.X, position.Y) == ECull.Intersect)
            {
                intersects = true;
            }
            else
            {
                ainsideb = false;
            }

            if (p.CullPoint(position.X + size.X, position.Y) == ECull.Intersect)
            {
                intersects = true;
            }
            else
            {
                ainsideb = false;
            }

            if (p.CullPoint(position.X, position.Y + size.Y) == ECull.Intersect)
            {
                intersects = true;
            }
            else
            {
                ainsideb = false;
            }

            if (p.CullPoint(position.X + size.X, position.Y + size.Y) == ECull.Intersect)
            {
                intersects = true;
            }
            else
            {
                ainsideb = false;
            }

            if (ainsideb)
            {
                return(RSpatialRelation.AInsideB);
            }
            if (intersects)
            {
                return(RSpatialRelation.Intersect);
            }

            //The find the point on the circle which is closest to the center of the rectangle
            Vector3 k = center - p.Position;
            if (k.LengthSquared() == 0)
            {
                k.X = 1;
            }
            Vector3 d = Vector3.Normalize(k) * p.Radius;

            Vector3 a = p.Position + d;

            //And check if it is outside the rectangle
            if (CullPoint(a.X, a.Y) == ECull.Outside)
            {
                return(RSpatialRelation.Outside);
            }

            //The we take the point furthest away from the center
            Vector3 b = p.Position - d;
            if (CullPoint(b.X, b.Y) == ECull.Outside)
            {
                return(RSpatialRelation.Intersect);
            }

            return(RSpatialRelation.BInsideA);
#endif
        }
        private static RSpatialRelation RectCircleRelation(RectangleF a, Bounding.Cylinder b)
        {
            float m, n;

            //X Axis, first find intersections
            CylP x1 = CylP.NotIntersecting;

            if (Math.CircleXAxisIntersection(b.Position, b.Radius, a.Y, out m, out n))
            {
                if (m > a.X + a.Width || n < a.X)
                {
                    x1 = CylP.Outside;
                }
                else if (m < a.X && n > a.X + a.Width)
                {
                    x1 = CylP.AInsideB;
                }
                else
                {
                    return(RSpatialRelation.Intersect);
                }
            }

            CylP x2 = CylP.NotIntersecting;

            if (Math.CircleXAxisIntersection(b.Position, b.Radius, a.Y + a.Height, out m, out n))
            {
                if (m > a.X + a.Height || n < a.X)
                {
                    x2 = CylP.Outside;
                }
                else if (m < a.X && n > a.X + a.Height)
                {
                    x2 = CylP.AInsideB;
                }
                else
                {
                    return(RSpatialRelation.Intersect);
                }
            }

            //Y Axis, first find intersections
            CylP y1 = CylP.NotIntersecting;

            if (Math.CircleYAxisIntersection(b.Position, b.Radius, a.X, out m, out n))
            {
                if (m > a.Y + a.Height || n < a.Y)
                {
                    y1 = CylP.Outside;
                }
                else if (m < a.Y && n > a.Y + a.Height)
                {
                    y1 = CylP.AInsideB;
                }
                else
                {
                    return(RSpatialRelation.Intersect);
                }
            }

            CylP y2 = CylP.NotIntersecting;

            if (Math.CircleYAxisIntersection(b.Position, b.Radius, a.X + a.Width, out m, out n))
            {
                if (m > a.Y + a.Height || n < a.Y)
                {
                    y2 = CylP.Outside;
                }
                else if (m < a.Y && n > a.Y + a.Height)
                {
                    y2 = CylP.AInsideB;
                }
                else
                {
                    return(RSpatialRelation.Intersect);
                }
            }

            if (x1 == CylP.AInsideB && x2 == CylP.AInsideB && y1 == CylP.AInsideB && y2 == CylP.AInsideB)
            {
                return(RSpatialRelation.AInsideB);
            }

            if (x1 == CylP.NotIntersecting && x2 == CylP.NotIntersecting &&
                y1 == CylP.NotIntersecting && y2 == CylP.NotIntersecting &&
                Intersection.Intersect(a, Math.ToVector2(b.Position)))
            {
                return(RSpatialRelation.BInsideA);
            }

            else
            {
                return(RSpatialRelation.Outside);
            }
        }