/// <summary> /// Creates a shallow copy of the volume. /// </summary> /// <param name="input">The volume to copy.</param> public void MemberwiseClone(Volume input) { // Copy references to members. this.Size = input.Size; this.Position = input.Position; this.color = input.color; // Calculate derivative variables. this.Half = Size / 2; this.Half = new Vector3((int)this.Half.X, (int)this.Half.Y, (int)this.Half.Z); this.Middle.X = this.Half.X + this.Position.X; this.Middle.Y = this.Half.Y + this.Position.Y; this.Middle.Z = this.Half.Z + this.Position.Z; this.Middle = new Vector3((int)this.Middle.X, (int)this.Middle.Y, (int)this.Middle.Z); }
/// <summary> /// Handles the removal of a node from an Octree. /// </summary> /// <param name="node">The Octree node to start the search from.</param> /// <param name="position">The location of the volume to remove.</param> public static void RemoveHandler(ref Octree<Volume>.OctreeNode node, Volume child) { if (node == null) return; Volume parent = node.data; //Console.WriteLine("Adding volume: " + child.ToString() + " inside of " + parent.ToString()); parent.Middle.X = (int)(parent.Half.X + parent.Position.X); parent.Middle.Y = (int)(parent.Half.Y + parent.Position.Y); parent.Middle.Z = (int)(parent.Half.Z + parent.Position.Z); #region // Stop condition if (parent.Size.X < 2 && parent.Size.Y < 2 && parent.Size.Z < 2 && parent.color == child.color) { //parent.Remove(); parent.Visible = false; return; } #endregion #region // Overflow calculation. Vector3 Local = Vector3.Zero; Vector3 Overflow = Vector3.Zero; Vector3 Underflow = Vector3.Zero; // Determine the relative position from the parent. Needed for underflow/overflow calculations. Local.X = child.Position.X - parent.Position.X; Local.Y = child.Position.Y - parent.Position.Y; Local.Z = child.Position.Z - parent.Position.Z; // Calculate overflow and underflow along the x-axis. if ((child.Size.X + Local.X) - parent.Half.X > 0) { Underflow.X = (parent.Half.X - Local.X); Overflow.X = child.Size.X - Underflow.X; } // Calculate overflow and underflow along the y-axis. if ((child.Size.Y + Local.Y) - parent.Half.Y > 0) { Underflow.Y = (parent.Half.Y - Local.Y); Overflow.Y = child.Size.Y - Underflow.Y; } // Calculate overflow and underflow along the z-axis. if ((child.Size.Z + Local.Z) - parent.Half.Z > 0) { Underflow.Z = (parent.Half.Z - Local.Z); Overflow.Z = child.Size.Z - Underflow.Z; } #endregion #region Recursive overflow logic if (Local.X >= parent.Half.X) { if (Local.Y >= parent.Half.Y) { if (Local.Z >= parent.Half.Z) { // Octant #8 has no possible overflow. if (node.TopRightFront != null) { RemoveHandler(ref node.TopRightFront, new Volume(child.Position, child.Size, ref child.color)); node.TopRightFront = null; } } else { // Test for overflow into the z direction. if (Overflow.Z > 0) { if (node.TopRightBack != null) { RemoveHandler(ref node.TopRightBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); node.TopRightBack = null; } if (node.TopRightFront != null) { RemoveHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); node.TopRightFront = null; } } else { if (node.TopRightBack != null) { RemoveHandler(ref node.TopRightBack, new Volume(child.Position, child.Size, ref child.color)); node.TopRightBack = null; } } } } else { if (Local.Z >= parent.Half.Z) { // Test for overflow in the Y direction. if (Overflow.Y > 0) { if (node.BottomRightFront != null) { RemoveHandler(ref node.BottomRightFront, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); node.BottomRightFront = null; } if (node.TopRightFront != null) { RemoveHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); node.TopRightFront = null; } } else { if (node.BottomRightFront != null) { RemoveHandler(ref node.BottomRightFront, new Volume(child.Position, child.Size, ref child.color)); node.BottomRightFront = null; } } } else { // Test for both cases. if (Overflow.Y > 0 && Overflow.Z > 0) { if (node.BottomRightBack != null) { RemoveHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, Underflow.Z), ref child.color)); node.BottomRightBack = null; } if (node.TopRightBack != null) { RemoveHandler(ref node.TopRightBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, Underflow.Z), ref child.color)); node.TopRightBack = null; } if (node.BottomRightFront != null) { RemoveHandler(ref node.BottomRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, Underflow.Y, Overflow.Z), ref child.color)); node.BottomRightFront = null; } if (node.TopRightFront != null) { RemoveHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(child.Size.X, Overflow.Y, Overflow.Z), ref child.color)); node.TopRightFront = null; } } else if (Overflow.Y > 0) { if (node.BottomRightBack != null) { RemoveHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); node.BottomRightBack = null; } if (node.TopRightBack != null) { RemoveHandler(ref node.TopRightBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); node.TopRightBack = null; } } else if (Overflow.Z > 0) { if (node.BottomRightBack != null) { RemoveHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); node.BottomRightBack = null; } if (node.BottomRightFront != null) { RemoveHandler(ref node.BottomRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); node.BottomRightFront = null; } } else { if (node.BottomRightBack != null) { RemoveHandler(ref node.BottomRightBack, new Volume(child.Position, child.Size, ref child.color)); node.BottomRightBack = null; } } } } } else { if (Local.Y >= parent.Half.Y) { if (Local.Z >= parent.Half.Z) { // Test for overflow into the X direction. if (Overflow.X > 0) { if (node.TopLeftFront == null) { RemoveHandler(ref node.TopLeftFront, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.TopLeftFront = null; } if (node.TopRightFront == null) { RemoveHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.TopRightFront = null; } } else { if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftFront, new Volume(child.Position, child.Size, ref child.color)); node.TopLeftBack = null; } } } else { // Test for three cases. if (Overflow.X > 0 && Overflow.Z > 0) { if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, Underflow.Z), ref child.color)); node.TopLeftBack = null; } if (node.TopRightBack != null) { RemoveHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, Underflow.Z), ref child.color)); node.TopRightBack = null; } if (node.TopLeftFront != null) { RemoveHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, child.Size.Y, Overflow.Z), ref child.color)); node.TopLeftFront = null; } if (node.TopRightFront != null) { RemoveHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, child.Size.Y, Overflow.Z), ref child.color)); node.TopRightFront = null; } } else if (Overflow.X > 0) { if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.TopLeftBack = null; } if (node.TopRightBack != null) { RemoveHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.TopRightBack = null; } } else if (Overflow.Z > 0) { if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); node.TopLeftBack = null; } if (node.TopLeftFront != null) { RemoveHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); node.TopLeftFront = null; } } else { if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftBack, new Volume(child.Position, child.Size, ref child.color)); node.TopLeftBack = null; } } } } else { if (Local.Z >= parent.Half.Z) { // Test two cases. if (Overflow.X > 0 && Overflow.Y > 0) { if (node.BottomLeftFront != null) { RemoveHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(Underflow.X, Underflow.Y, child.Size.Z), ref child.color)); node.BottomLeftFront = null; } if (node.TopLeftFront != null) { RemoveHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(Underflow.X, Overflow.Y, child.Size.Z), ref child.color)); node.TopLeftFront = null; } if (node.BottomRightFront != null) { RemoveHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, Underflow.Y, child.Size.Z), ref child.color)); node.BottomRightFront = null; } if (node.TopRightFront != null) { RemoveHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, child.Position.Z), new Vector3(Overflow.X, Overflow.Y, child.Size.Z), ref child.color)); node.TopRightFront = null; } } else if (Overflow.X > 0) { if (node.BottomLeftFront != null) { RemoveHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.BottomLeftFront = null; } if (node.BottomRightFront != null) { RemoveHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.BottomRightFront = null; } } else if (Overflow.Y > 0) { if (node.BottomLeftFront != null) { RemoveHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); node.BottomLeftFront = null; } if (node.TopLeftFront != null) { RemoveHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); node.TopLeftFront = null; } } else { if (node.BottomLeftFront != null) { RemoveHandler(ref node.BottomLeftFront, new Volume(child.Position, child.Size, ref child.color)); node.BottomLeftFront = null; } } } else { // Test for both cases. if (Overflow.X > 0 && Overflow.Y > 0 && Overflow.Z > 0) { if (node.BottomLeftBack != null) { RemoveHandler(ref node.BottomLeftBack, new Volume(child.Position, Underflow, ref child.color)); node.BottomLeftBack = null; } // Primaries if (node.BottomRightBack != null) { RemoveHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, Underflow.Y, Underflow.Z), ref child.color)); node.BottomRightBack = null; } if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(Underflow.X, Overflow.Y, Underflow.Z), ref child.color)); node.TopLeftBack = null; } if (node.BottomLeftFront != null) { RemoveHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, Underflow.Y, Overflow.Z), ref child.color)); node.BottomLeftFront = null; } // Secondaries if (node.TopLeftFront != null) { RemoveHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(Underflow.X, Overflow.Y, Overflow.Z), ref child.color)); node.TopLeftFront = null; } if (node.TopRightBack != null) { RemoveHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, child.Position.Z), new Vector3(Overflow.X, Overflow.Y, Underflow.Z), ref child.color)); node.TopRightBack = null; } if (node.BottomRightFront != null) { RemoveHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, Underflow.Y, Overflow.Z), ref child.color)); node.BottomRightFront = null; } // Tertiary if (node.TopRightFront != null) { RemoveHandler(ref node.TopRightFront, new Volume(parent.Middle, Overflow, ref child.color)); node.TopRightFront = null; } } else if (Overflow.X > 0 && Overflow.Y > 0) { if (node.BottomLeftBack != null) { RemoveHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(Underflow.X, Underflow.Y, child.Size.Z), ref child.color)); node.BottomLeftBack = null; } // Primaries if (node.BottomRightBack != null) { RemoveHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.BottomRightBack = null; } if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(Underflow.X, Overflow.Y, child.Size.Z), ref child.color)); node.TopLeftBack = null; } // Secondaries if (node.TopRightBack != null) { RemoveHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, child.Position.Z), new Vector3(Overflow.X, Overflow.Y, child.Size.Z), ref child.color)); node.TopRightBack = null; } } else if (Overflow.Y > 0 && Overflow.Z > 0) { if (node.BottomLeftBack != null) { RemoveHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, Underflow.Z), ref child.color)); node.BottomLeftBack = null; } // Primaries if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, Underflow.Z), ref child.color)); node.TopLeftBack = null; } if (node.BottomLeftFront != null) { RemoveHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, Underflow.Y, Overflow.Z), ref child.color)); node.BottomLeftFront = null; } // Secondaries if (node.TopLeftFront != null) { RemoveHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(child.Size.X, Overflow.Y, Overflow.Z), ref child.color)); node.TopLeftFront = null; } } else if (Overflow.X > 0 && Overflow.Z > 0) { if (node.BottomLeftBack != null) { RemoveHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, Underflow.Z), ref child.color)); node.BottomLeftBack = null; } // Primaries if (node.BottomLeftFront != null) { RemoveHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, child.Size.Y, Overflow.Z), ref child.color)); node.BottomLeftFront = null; } if (node.BottomRightBack != null) { RemoveHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, Underflow.Z), ref child.color)); node.BottomRightBack = null; } // Secondaries if (node.BottomRightFront != null) { RemoveHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, child.Size.Y, Overflow.Z), ref child.color)); node.BottomRightFront = null; } } else if (Overflow.X > 0) { if (node.BottomLeftBack != null) { RemoveHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.BottomLeftBack = null; } if (node.BottomRightBack != null) { RemoveHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); node.BottomRightBack = null; } } else if (Overflow.Y > 0) { if (node.BottomLeftBack != null) { RemoveHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); node.BottomLeftBack = null; } if (node.TopLeftBack != null) { RemoveHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); node.TopLeftBack = null; } } else if (Overflow.Z > 0) { if (node.BottomLeftBack != null) { RemoveHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); node.BottomLeftBack = null; } if (node.BottomLeftFront != null) { RemoveHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); node.BottomLeftFront = null; } } else { if (node.BottomLeftBack != null) { RemoveHandler(ref node.BottomLeftBack, new Volume(child.Position, child.Size, ref child.color)); node.BottomLeftBack = null; } } } } } #endregion //TryCollapse(ref node); }
/// <summary> /// Handles the instantiation of the root node of an Octree. /// </summary> /// <param name="root">The root node to instantiate.</param> /// <param name="size">The maximum size of the Octree, which the root node will hold.</param> public static void SetRootHandler(ref Octree<Volume>.OctreeNode root, Volume volume) { Console.WriteLine("Volume: " + volume.Size); // Set root node! root = new Octree<Volume>.OctreeNode(new Volume(Vector3.Zero, volume.Size, ref volume.color)); }
public bool Equals(Volume a) { return this == a; }
/// <summary> /// Octree search based on volume. To be used with an instance of Octree. /// </summary> /// <param name="node">The OctreeNode to search from.</param> /// <param name="position">The location of the Volume being searched for.</param> /// <returns>A Volume at location provided.</returns> public static Volume SearchHandler(ref Octree<Volume>.OctreeNode node, Volume volume) { if (node.data.Size == volume.Size && node.data.Position.X == volume.Position.X && node.data.Position.Y == volume.Position.Y && node.data.Position.Z == volume.Position.Z) return node.data; if (volume.Position.X < node.data.Middle.X) { if (volume.Position.Y < node.data.Middle.Y) { if (volume.Position.Z < node.data.Middle.Z) { if (node.BottomLeftBack == null) return null; return SearchHandler(ref node.BottomLeftBack, volume); } else { if (node.BottomLeftFront == null) return null; return SearchHandler(ref node.BottomLeftFront, volume); } } else { if (volume.Position.Z < node.data.Middle.Z) { if (node.TopLeftBack == null) return null; return SearchHandler(ref node.TopLeftBack, volume); } else { if (node.TopLeftFront == null) return null; return SearchHandler(ref node.TopLeftFront, volume); } } } else { if (volume.Position.Y < node.data.Middle.Y) { if (volume.Position.Z < node.data.Middle.Z) { if (node.BottomRightBack == null) return null; return SearchHandler(ref node.BottomRightBack, volume); } else { if (node.BottomRightFront == null) return null; return SearchHandler(ref node.BottomRightFront, volume); } } else { if (volume.Position.Z < node.data.Middle.Z) { if (node.TopRightBack == null) return null; return SearchHandler(ref node.TopRightBack, volume); } else { if (node.TopRightFront == null) return null; return SearchHandler(ref node.TopRightFront, volume); } } } }
/// <summary> /// Inserts a WorldVolume of size one, or greater, into an Octree. /// </summary> /// <param name="node">The Octree to insert into.</param> /// <param name="child">The WorldVolume to add to the Octree.</param> public static void AddHandler(ref Octree<Volume>.OctreeNode node, Volume child) { if (node == null) { return; } Volume parent = node.data; parent.Middle.X = (int)(parent.Half.X + parent.Position.X); parent.Middle.Y = (int)(parent.Half.Y + parent.Position.Y); parent.Middle.Z = (int)(parent.Half.Z + parent.Position.Z); #region // Stop condition if (parent.Size.X < 2 && parent.Size.Y < 2 && parent.Size.Z < 2) { parent.Visible = true; return; } #endregion #region // Overflow calculation. Vector3 Local = Vector3.Zero; Vector3 Overflow = Vector3.Zero; Vector3 Underflow = Vector3.Zero; // Determine the relative position from the parent. Needed for underflow/overflow calculations. Local.X = child.Position.X - parent.Position.X; Local.Y = child.Position.Y - parent.Position.Y; Local.Z = child.Position.Z - parent.Position.Z; // Calculate overflow and underflow along the x-axis. if ((child.Size.X + Local.X) - parent.Half.X > 0) { Underflow.X = (parent.Half.X - Local.X); Overflow.X = child.Size.X - Underflow.X; } // Calculate overflow and underflow along the y-axis. if ((child.Size.Y + Local.Y) - parent.Half.Y > 0) { Underflow.Y = (parent.Half.Y - Local.Y); Overflow.Y = child.Size.Y - Underflow.Y; } // Calculate overflow and underflow along the z-axis. if ((child.Size.Z + Local.Z) - parent.Half.Z > 0) { Underflow.Z = (parent.Half.Z - Local.Z); Overflow.Z = child.Size.Z - Underflow.Z; } #endregion #region Recursive overflow logic if (Local.X >= parent.Half.X) { if (Local.Y >= parent.Half.Y) { if (Local.Z >= parent.Half.Z) { // Octant #8 has no possible overflow. if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(child.Position, child.Size, ref child.color)); } else { // We know that the top, right, back octant has something in it. if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } // Test for overflow into the z direction. if (Overflow.Z > 0) { AddHandler(ref node.TopRightBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); } else { AddHandler(ref node.TopRightBack, new Volume(child.Position, child.Size, ref child.color)); } } } else { if (Local.Z >= parent.Half.Z) { // We know that the bottom, right, front octant has something in it... if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } // Test for overflow in the Y direction. if (Overflow.Y > 0) { AddHandler(ref node.BottomRightFront, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); } else { AddHandler(ref node.BottomRightFront, new Volume(child.Position, child.Size, ref child.color)); } } else { // We know that the bottom, right, back octant has something in it... if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } // Test for both cases. if (Overflow.Y > 0 && Overflow.Z > 0) { AddHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, Underflow.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, Underflow.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, Underflow.Y, Overflow.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(child.Size.X, Overflow.Y, Overflow.Z), ref child.color)); } else if (Overflow.Y > 0) { AddHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); } else if (Overflow.Z > 0) { AddHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); } else { AddHandler(ref node.BottomRightBack, new Volume(child.Position, child.Size, ref child.color)); } } } } else { if (Local.Y >= parent.Half.Y) { if (Local.Z >= parent.Half.Z) { if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } // Test for overflow into the X direction. if (Overflow.X > 0) { AddHandler(ref node.TopLeftFront, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); } else { AddHandler(ref node.TopLeftFront, new Volume(child.Position, child.Size, ref child.color)); } } else { // Octant #8 has no possible overflow. if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } // Test for three cases. if (Overflow.X > 0 && Overflow.Z > 0) { AddHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, child.Size.Y, Overflow.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, child.Size.Y, Overflow.Z), ref child.color)); } else if (Overflow.X > 0) { AddHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); } else if (Overflow.Z > 0) { AddHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); } else { AddHandler(ref node.TopLeftBack, new Volume(child.Position, child.Size, ref child.color)); } } } else { if (Local.Z >= parent.Half.Z) { // We know that the bottom, right, front octant has something in it... if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } // Test two cases. if (Overflow.X > 0 && Overflow.Y > 0) { AddHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(Underflow.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(Underflow.X, Overflow.Y, child.Size.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, child.Position.Z), new Vector3(Overflow.X, Overflow.Y, child.Size.Z), ref child.color)); } else if (Overflow.X > 0) { AddHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); } else if (Overflow.Y > 0) { AddHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); } else { AddHandler(ref node.BottomLeftFront, new Volume(child.Position, child.Size, ref child.color)); } } else { // We know that the bottom, right, back octant has something in it... if (node.BottomLeftBack == null) { node.BottomLeftBack = new Octree<Volume>.OctreeNode(new Volume(parent.Position, parent.Half, ref child.color)); } // Test for both cases. if (Overflow.X > 0 && Overflow.Y > 0 && Overflow.Z > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, Underflow, ref child.color)); // Primaries if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, Underflow.Y, Underflow.Z), ref child.color)); if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(Underflow.X, Overflow.Y, Underflow.Z), ref child.color)); if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, Underflow.Y, Overflow.Z), ref child.color)); // Secondaries if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(Underflow.X, Overflow.Y, Overflow.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, child.Position.Z), new Vector3(Overflow.X, Overflow.Y, Underflow.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, Underflow.Y, Overflow.Z), ref child.color)); // Tertiary if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(parent.Middle, Overflow, ref child.color)); } else if (Overflow.X > 0 && Overflow.Y > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(Underflow.X, Underflow.Y, child.Size.Z), ref child.color)); // Primaries if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(Underflow.X, Overflow.Y, child.Size.Z), ref child.color)); // Secondaries if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, child.Position.Z), new Vector3(Overflow.X, Overflow.Y, child.Size.Z), ref child.color)); } else if (Overflow.Y > 0 && Overflow.Z > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, Underflow.Z), ref child.color)); // Primaries if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, Underflow.Z), ref child.color)); if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, Underflow.Y, Overflow.Z), ref child.color)); // Secondaries if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(child.Size.X, Overflow.Y, Overflow.Z), ref child.color)); } else if (Overflow.X > 0 && Overflow.Z > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, Underflow.Z), ref child.color)); // Primaries if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, child.Size.Y, Overflow.Z), ref child.color)); if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, Underflow.Z), ref child.color)); // Secondaries if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, child.Size.Y, Overflow.Z), ref child.color)); } else if (Overflow.X > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); } else if (Overflow.Y > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, child.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); } else if (Overflow.Z > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); } else { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, child.Size, ref child.color)); } } } } #endregion #region // Collapsal logic. //TryCollapse(ref node); /* if (!parent.Collapsed && node.BottomLeftBack != null && node.BottomLeftFront != null && node.BottomRightBack != null && node.BottomRightFront != null && node.TopLeftBack != null && node.TopLeftFront != null && node.TopRightBack != null && node.TopRightFront != null) { if (node.BottomLeftBack.data.color == node.BottomLeftFront.data.color && node.BottomRightBack.data.color == node.BottomLeftFront.data.color && node.BottomRightFront.data.color == node.BottomLeftFront.data.color && node.TopLeftBack.data.color == node.BottomLeftFront.data.color && node.TopLeftFront.data.color == node.BottomLeftFront.data.color && node.TopRightBack.data.color == node.BottomLeftFront.data.color && node.TopRightFront.data.color == node.BottomLeftFront.data.color) if( node.TopRightFront.data.Collapsed && node.TopRightBack.data.Collapsed && node.TopLeftFront.data.Collapsed && node.TopLeftBack.data.Collapsed && node.BottomRightFront.data.Collapsed && node.BottomRightBack.data.Collapsed && node.BottomLeftFront.data.Collapsed && node.BottomLeftBack.data.Collapsed ) node.data.Collapse(ref node); } if (parent.Collapsed && parent.Size != Vector3.One && (node.BottomRightFront == null || node.BottomRightBack == null || node.BottomLeftFront == null || node.BottomLeftBack == null || node.TopRightFront == null || node.TopRightBack == null || node.TopLeftFront == null || node.TopLeftBack == null) ) node.data.Expand( ref node ); * */ #endregion }
public void Add(Volume volume) { AddQueue.Enqueue(volume); lock (Locked) { Monitor.Pulse( Locked ); } }
public void loadFromJSONFile(string filename) { using (StreamReader sr = new StreamReader(filename)) { JsonTextReader jtr = new JsonTextReader(sr); //JObject nodes = JObject.Parse(sr.ReadToEnd()); Volume node = new Volume(); Hashtable jobject = new Hashtable(); string property = ""; while (jtr.Read()) { switch (jtr.TokenType) { case JsonToken.StartObject: Console.Write("Start object: "); break; case JsonToken.StartArray: break; case JsonToken.EndArray: break; case JsonToken.PropertyName: property = jtr.Value.ToString(); break; case JsonToken.EndObject: if (jobject.Count > 0) { System.Drawing.Color c = System.Drawing.Color.FromArgb(int.Parse(jobject["r"].ToString()), int.Parse(jobject["g"].ToString()), int.Parse(jobject["b"].ToString())); Add( new Volume( new Vector3(int.Parse(jobject["x"].ToString()), int.Parse(jobject["y"].ToString()), int.Parse(jobject["z"].ToString())), new Vector3(1f, 1f, 1f), new Color(c.R, c.G, c.B, c.A)) ); jobject.Clear(); } break; case JsonToken.Integer: case JsonToken.Float: case JsonToken.String: jobject.Add(property, jtr.Value); break; } } } }
/// <summary> /// Inserts a volume of size one, or greater, into an Octree. /// </summary> /// <param name="node">The Octree to insert into.</param> /// <param name="child">The volume to add to the Octree.</param> public static void AddHandler(ref Octree<Volume>.OctreeNode node, Volume child) { if (node == null) { return; } Volume parent = node.data; #region // Stop condition if (parent.Size.X < 2 && parent.Size.Y < 2 && parent.Size.Z < 2) { parent.Remove(); Volume tmp = Game.world.Search((int)child.Position.X, (int)child.Position.Y, (int)child.Position.Z - 1); // Add faces if the neighbors do not exist, otherwise delete the appropriate neighboring cube's faces. if (tmp == null) parent.AddFace(Face.Facing.Backward); else tmp.RemoveFace(Face.Facing.Forward); tmp = Game.world.Search((int)child.Position.X, (int)child.Position.Y, (int)child.Position.Z + 1); if (tmp == null) parent.AddFace(Face.Facing.Forward); else tmp.RemoveFace(Face.Facing.Backward); tmp = Game.world.Search((int)child.Position.X - 1, (int)child.Position.Y, (int)child.Position.Z); if (tmp == null) parent.AddFace(Face.Facing.Left); else tmp.RemoveFace(Face.Facing.Right); tmp = Game.world.Search((int)child.Position.X + 1, (int)child.Position.Y, (int)child.Position.Z); if (tmp == null) parent.AddFace(Face.Facing.Right); else tmp.RemoveFace(Face.Facing.Left); tmp = Game.world.Search((int)child.Position.X, (int)child.Position.Y + 1, (int)child.Position.Z); if (tmp == null) parent.AddFace(Face.Facing.Up); else tmp.RemoveFace(Face.Facing.Down); tmp = Game.world.Search((int)child.Position.X, (int)child.Position.Y - 1, (int)child.Position.Z); if (tmp == null) parent.AddFace(Face.Facing.Down); else tmp.RemoveFace(Face.Facing.Up); return; } #endregion #region // Overflow calculation. Vector3 Local = Vector3.Zero; Vector3 Overflow = Vector3.Zero; Vector3 Underflow = Vector3.Zero; // Determine the relative position from the parent. Needed for underflow/overflow calculations. Local.X = child.Position.X - parent.Position.X; Local.Y = child.Position.Y - parent.Position.Y; Local.Z = child.Position.Z - parent.Position.Z; // Calculate overflow and underflow along the x-axis. if ((child.Size.X + Local.X) - parent.Half.X > 0) { Underflow.X = (parent.Half.X - Local.X); Overflow.X = child.Size.X - Underflow.X; } // Calculate overflow and underflow along the y-axis. if ((child.Size.Y + Local.Y) - parent.Half.Y > 0) { Underflow.Y = (parent.Half.Y - Local.Y); Overflow.Y = child.Size.Y - Underflow.Y; } // Calculate overflow and underflow along the z-axis. if ((child.Size.Z + Local.Z) - parent.Half.Z > 0) { Underflow.Y = (parent.Half.Z - Local.Z); Overflow.Z = child.Size.Z - Underflow.Z; } #endregion #region Recursive overflow logic if (Local.X >= parent.Half.X) { if (Local.Y >= parent.Half.Y) { if (Local.Z >= parent.Half.Z) { // Octant #8 has no possible overflow. if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(child.Position, child.Size, ref child.color)); } else { // We know that the top, right, back octant has something in it. if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } // Test for overflow into the z direction. if (Overflow.Z > 0) { AddHandler(ref node.TopRightBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); } else { AddHandler(ref node.TopRightBack, new Volume(child.Position, child.Size, ref child.color)); } } } else { if (Local.Z >= parent.Half.Z) { // We know that the bottom, right, front octant has something in it... if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } // Test for overflow in the Y direction. if (Overflow.Y > 0) { AddHandler(ref node.BottomRightFront, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); } else { AddHandler(ref node.BottomRightFront, new Volume(child.Position, child.Size, ref child.color)); } } else { // We know that the bottom, right, back octant has something in it... if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } // Test for both cases. if (Overflow.Y > 0 && Overflow.Z > 0) { AddHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, Underflow.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(child.Size.X, Overflow.Y, Underflow.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, Underflow.Y, Overflow.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(child.Size.X, Overflow.Y, Overflow.Z), ref child.color)); } else if (Overflow.Y > 0) { AddHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); } else if (Overflow.Z > 0) { AddHandler(ref node.BottomRightBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); } else { AddHandler(ref node.BottomRightBack, new Volume(child.Position, child.Size, ref child.color)); } } } } else { if (Local.Y >= parent.Half.Y) { if (Local.Z >= parent.Half.Z) { if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } // Test for overflow into the X direction. if (Overflow.X > 0) { AddHandler(ref node.TopLeftFront, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); } else { AddHandler(ref node.TopLeftFront, new Volume(child.Position, child.Size, ref child.color)); } } else { // Octant #8 has no possible overflow. if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } // Test for three cases. if (Overflow.X > 0 && Overflow.Z > 0) { AddHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, child.Size.Y, Overflow.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, child.Size.Y, Overflow.Z), ref child.color)); } else if (Overflow.X > 0) { AddHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); } else if (Overflow.Z > 0) { AddHandler(ref node.TopLeftBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); } else { AddHandler(ref node.TopLeftBack, new Volume(child.Position, child.Size, ref child.color)); } } } else { if (Local.Z >= parent.Half.Z) { // We know that the bottom, right, front octant has something in it... if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } // Test two cases. if (Overflow.X > 0 && Overflow.Y > 0) { AddHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(Underflow.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(Underflow.X, Overflow.Y, child.Size.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), new Vector3(Overflow.X, Overflow.Y, child.Size.Z), ref child.color)); } else if (Overflow.X > 0) { AddHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); } else if (Overflow.Y > 0) { AddHandler(ref node.BottomLeftFront, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); } else { AddHandler(ref node.BottomLeftFront, new Volume(child.Position, child.Size, ref child.color)); } } else { // We know that the bottom, right, back octant has something in it... if (node.BottomLeftBack == null) { node.BottomLeftBack = new Octree<Volume>.OctreeNode(new Volume(parent.Position, parent.Half, ref child.color)); } // Test for both cases. if (Overflow.X > 0 && Overflow.Y > 0 && Overflow.Z > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, Underflow, ref child.color)); // Primaries if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, Underflow.Y, Underflow.Z), ref child.color)); if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(Underflow.X, Overflow.Y, Underflow.Z), ref child.color)); if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, Underflow.Y, Overflow.Z), ref child.color)); // Secondaries if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(Underflow.X, Overflow.Y, Overflow.Z), ref child.color)); if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), new Vector3(Overflow.X, Overflow.Y, Underflow.Z), ref child.color)); if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, Underflow.Y, Overflow.Z), ref child.color)); // Tertiary if (node.TopRightFront == null) { node.TopRightFront = new Octree<Volume>.OctreeNode(new Volume(parent.Middle, parent.Half, ref child.color)); } AddHandler(ref node.TopRightFront, new Volume(parent.Middle, Overflow, ref child.color)); } else if (Overflow.X > 0 && Overflow.Y > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(Underflow.X, Underflow.Y, child.Size.Z), ref child.color)); // Primaries if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(Underflow.X, Overflow.Y, child.Size.Z), ref child.color)); // Secondaries if (node.TopRightBack == null) { node.TopRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopRightBack, new Volume(new Vector3(parent.Middle.X, parent.Middle.Y, parent.Position.Z), new Vector3(Overflow.X, Overflow.Y, child.Size.Z), ref child.color)); } else if (Overflow.Y > 0 && Overflow.Z > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, Underflow.Z), ref child.color)); // Primaries if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(child.Size.X, Overflow.Y, Underflow.Z), ref child.color)); if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, Underflow.Y, Overflow.Z), ref child.color)); // Secondaries if (node.TopLeftFront == null) { node.TopLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftFront, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Middle.Z), new Vector3(child.Size.X, Overflow.Y, Overflow.Z), ref child.color)); } else if (Overflow.X > 0 && Overflow.Z > 0) { AddHandler(ref node.BottomLeftBack, new Volume(new Vector3(child.Position.X, child.Position.Y, child.Position.Z), new Vector3(Underflow.X, child.Size.Y, Underflow.Z), ref child.color)); // Primaries if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(Underflow.X, child.Size.Y, Overflow.Z), ref child.color)); if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, Underflow.Z), ref child.color)); // Secondaries if (node.BottomRightFront == null) { node.BottomRightFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightFront, new Volume(new Vector3(parent.Middle.X, child.Position.Y, parent.Middle.Z), new Vector3(Overflow.X, child.Size.Y, Overflow.Z), ref child.color)); } else if (Overflow.X > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(Underflow.X, child.Size.Y, child.Size.Z), ref child.color)); if (node.BottomRightBack == null) { node.BottomRightBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Middle.X, parent.Position.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomRightBack, new Volume(new Vector3(parent.Middle.X, child.Position.Y, child.Position.Z), new Vector3(Overflow.X, child.Size.Y, child.Size.Z), ref child.color)); } else if (Overflow.Y > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, Underflow.Y, child.Size.Z), ref child.color)); if (node.TopLeftBack == null) { node.TopLeftBack = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Middle.Y, parent.Position.Z), parent.Half, ref child.color)); } AddHandler(ref node.TopLeftBack, new Volume(new Vector3(child.Position.X, parent.Middle.Y, parent.Position.Z), new Vector3(child.Size.X, Overflow.Y, child.Size.Z), ref child.color)); } else if (Overflow.Z > 0) { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, new Vector3(child.Size.X, child.Size.Y, Underflow.Z), ref child.color)); if (node.BottomLeftFront == null) { node.BottomLeftFront = new Octree<Volume>.OctreeNode(new Volume(new Vector3(parent.Position.X, parent.Position.Y, parent.Middle.Z), parent.Half, ref child.color)); } AddHandler(ref node.BottomLeftFront, new Volume(new Vector3(child.Position.X, child.Position.Y, parent.Middle.Z), new Vector3(child.Size.X, child.Size.Y, Overflow.Z), ref child.color)); } else { AddHandler(ref node.BottomLeftBack, new Volume(child.Position, child.Size, ref child.color)); } } } } #endregion #region // Collapsal logic. if ( !parent.Collapsed && node.BottomLeftBack != null && node.BottomLeftFront != null && node.BottomRightBack != null && node.BottomRightFront != null && node.TopLeftBack != null && node.TopLeftFront != null && node.TopRightBack != null && node.TopRightFront != null) node.data.Collapse( ref node ); if (parent.Collapsed && (node.BottomRightFront == null || node.BottomRightBack == null || node.BottomLeftFront == null || node.BottomLeftBack == null || node.TopRightFront == null || node.TopRightBack == null || node.TopLeftFront == null || node.TopLeftBack == null) ) node.data.Expand( ref node ); #endregion }