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); } } }
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); }
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); } }