/// <summary> /// Add a quad that you now occupy to your list (called by quad tree) /// </summary> /// <param name="q"></param> public override void AddMap(Map q) { myMaps.Add(q); }
/// <summary> /// Remove a quad that you no longer occupy from your list (called by quad tree) /// </summary> /// <param name="q"></param> public override void DelMap(Map q) { myMaps.Remove(q); }
/// <summary> /// Static constr - build tree /// </summary> static Map() { // Recursively create the entire tree root = new Map(null,new Rectangle(0,0,MapWidth,MapHeight),0); Debug.WriteLine(String.Format("{0} quads in quadtree",numQuads)); }
// Helper for GetObjectsWithinRange() // Run through each object in the given quad, keeping only those that are within the radius // and are of the right type(s). Optionally also filter those not in direct line of sight. private static void GetObjectsFromQuad(Map map, List<IDetectable> result, Vector3 loc, float radius, bool includeOrganisms, bool includeTerrain, bool lineOfSightOnly, Organism ignoreMe) { // Organisms... if (includeOrganisms==true) { foreach (Renderable obj in map.OrganismList) { if (obj != ignoreMe) // don't include the owner of the sensor! { float radii = obj.AbsSphere.Radius + radius; if (Vector3.LengthSq(loc - obj.AbsSphere.Centre) <= (radii * radii)) // include it if spheres intersect { if (lineOfSightOnly == true) // and optionally if unobstructed by terrain etc. { if ((Terrain.InLineOfSight(loc, obj.AbsSphere.Centre)) && (!result.Contains((IDetectable)obj))) // Object may be in several quads, so only add if unique result.Add((IDetectable)obj); } else { if (!result.Contains((IDetectable)obj)) // Object may be in several quads, so only add if unique result.Add((IDetectable)obj); } } } } } // Tiles... if (includeTerrain==true) { foreach (Renderable obj in map.TerrainList) { float radii = obj.AbsSphere.Radius + radius; if (Vector3.LengthSq(loc - obj.AbsSphere.Centre) <= (radii * radii)) // include it if obj sphere intersects tile SPHERE { if (lineOfSightOnly==true) { if (Terrain.InLineOfSight(loc, obj.AbsSphere.Centre)) result.Add((IDetectable)obj); } else { if (!result.Contains((IDetectable)obj)) // Object may be in several quads, so only add if unique result.Add((IDetectable)obj); } } } } }
/// <summary> /// Instance constr - called recursively by static constr /// </summary> /// <param name="parent">map above me</param> /// <param name="bounds">rectangle of world that I represent</param> /// <param name="level">current level into tree</param> public Map(Map parent, RectangleF bounds, int level) { // record level & parent this.level = level; this.parent = parent; numQuads++; // track number of quads during development // set up my bounding box and bounding circle this.bounds = bounds; centre = new Vector3(bounds.X + (bounds.Width / 2.0f), // use Vector3 for easy comparison with 0, // object x,y,z, but y is always 0 bounds.Y + (bounds.Height / 2.0f)); double diagx = centre.X - bounds.X; // xy offset from centre to a corner double diagy = centre.Z - bounds.Y; radius = (float)Math.Sqrt((diagx*diagx)+(diagy*diagy)); // distance from centre to corners // recursively create my children, if any if (++level < NumLevels) { float w = bounds.Width / 2.0f; // size of sub-quads float h = bounds.Height / 2.0f; child[0] = new Map(this, // NE new RectangleF(centre.X,centre.Z,w,h), level); child[1] = new Map(this, // SE new RectangleF(centre.X,bounds.Y,w,h), level); child[2] = new Map(this, // SW new RectangleF(bounds.X,bounds.Y,w,h), level); child[3] = new Map(this, // NW new RectangleF(bounds.X,centre.Z,w,h), level); } }
/// <summary> /// Add a quad that you now occupy to your list, IF YOU HAVE ONE (called by quad tree) /// Base method does nothing - only mobile objects need implement a list of /// their own, so that they can check whether they've crossed a quad boundary /// </summary> /// <param name="q"></param> public virtual void AddMap(Map q) { }
/// <summary> /// Remove a quad that you no longer occupy from your list (called by quad tree) /// </summary> /// <param name="q"></param> public virtual void DelMap(Map q) { }