/// <summary> /// Builds a uniformly subdivided tree for the given world size. /// </summary> /// <param name="depth"></param> /// <param name="bounds"></param> /// <param name="?"></param> /// <returns></returns> private ClipSector CreateClipSectors(int depth, idBounds bounds, ref Vector3 maxSector) { idBounds front, back; ClipSector anode = _clipSectors[_clipSectorCount] = new ClipSector(); _clipSectorCount++; if (depth == idClip.MaxSectorDepth) { anode.Axis = -1; anode.Children[0] = anode.Children[1] = null; if ((bounds.Max.X - bounds.Min.X) > maxSector.X) { maxSector.X = bounds.Max.X - bounds.Min.X; } if ((bounds.Max.Y - bounds.Min.Y) > maxSector.Y) { maxSector.Y = bounds.Max.Y - bounds.Min.Y; } if ((bounds.Max.Z - bounds.Min.Z) > maxSector.Z) { maxSector.Z = bounds.Max.Z - bounds.Min.Z; } return(anode); } Vector3 size = bounds.Max - bounds.Min; front = bounds; back = bounds; if ((size.X >= size.Y) && (size.X >= size.Z)) { anode.Axis = 0; anode.Distance = 0.5f * (bounds.Max.X + bounds.Min.X); front.Min.X = back.Max.X = anode.Distance; } else if ((size.Y >= size.X) && (size.Y >= size.Z)) { anode.Axis = 1; anode.Distance = 0.5f * (bounds.Max.Y + bounds.Min.Y); front.Min.Y = back.Max.Y = anode.Distance; } else { anode.Axis = 2; anode.Distance = 0.5f * (bounds.Max.Z + bounds.Min.Z); front.Min.Z = back.Max.Z = anode.Distance; } anode.Children[0] = CreateClipSectors(depth + 1, front, ref maxSector); anode.Children[1] = CreateClipSectors(depth + 1, back, ref maxSector); return(anode); }
private void LinkSectors(ClipSector node) { ClipLink link; while (node.Axis != -1) { float min = ((node.Axis == 0) ? _absBounds.Min.X : ((node.Axis == 1) ? _absBounds.Min.Y : _absBounds.Min.Z)); float max = ((node.Axis == 0) ? _absBounds.Max.X : ((node.Axis == 1) ? _absBounds.Max.Y : _absBounds.Max.Z)); if (min > node.Distance) { node = node.Children[0]; } else if (max < node.Distance) { node = node.Children[1]; } else { LinkSectors(node.Children[0]); node = node.Children[1]; } } link = new ClipLink(); link.Model = this; link.Sector = node; link.NextInSector = node.Links; link.PreviousInSector = null; if (node.Links != null) { node.Links.PreviousInSector = link; } node.Links = link; link.NextLink = _clipLinks; _clipLinks = link; }
/// <summary> /// Builds a uniformly subdivided tree for the given world size. /// </summary> /// <param name="depth"></param> /// <param name="bounds"></param> /// <param name="?"></param> /// <returns></returns> private ClipSector CreateClipSectors(int depth, idBounds bounds, ref Vector3 maxSector) { idBounds front, back; ClipSector anode = _clipSectors[_clipSectorCount] = new ClipSector(); _clipSectorCount++; if(depth == idClip.MaxSectorDepth) { anode.Axis = -1; anode.Children[0] = anode.Children[1] = null; if((bounds.Max.X - bounds.Min.X) > maxSector.X) { maxSector.X = bounds.Max.X - bounds.Min.X; } if((bounds.Max.Y - bounds.Min.Y) > maxSector.Y) { maxSector.Y = bounds.Max.Y - bounds.Min.Y; } if((bounds.Max.Z - bounds.Min.Z) > maxSector.Z) { maxSector.Z = bounds.Max.Z - bounds.Min.Z; } return anode; } Vector3 size = bounds.Max - bounds.Min; front = bounds; back = bounds; if((size.X >= size.Y) && (size.X >= size.Z)) { anode.Axis = 0; anode.Distance = 0.5f * (bounds.Max.X + bounds.Min.X); front.Min.X = back.Max.X = anode.Distance; } else if((size.Y >= size.X) && (size.Y >= size.Z)) { anode.Axis = 1; anode.Distance = 0.5f * (bounds.Max.Y + bounds.Min.Y); front.Min.Y = back.Max.Y = anode.Distance; } else { anode.Axis = 2; anode.Distance = 0.5f * (bounds.Max.Z + bounds.Min.Z); front.Min.Z = back.Max.Z = anode.Distance; } anode.Children[0] = CreateClipSectors(depth + 1, front, ref maxSector); anode.Children[1] = CreateClipSectors(depth + 1, back, ref maxSector); return anode; }
private void LinkSectors(ClipSector node) { ClipLink link; while(node.Axis != -1) { float min = ((node.Axis == 0) ? _absBounds.Min.X : ((node.Axis == 1) ? _absBounds.Min.Y : _absBounds.Min.Z)); float max = ((node.Axis == 0) ? _absBounds.Max.X : ((node.Axis == 1) ? _absBounds.Max.Y : _absBounds.Max.Z)); if(min > node.Distance) { node = node.Children[0]; } else if(max < node.Distance) { node = node.Children[1]; } else { LinkSectors(node.Children[0]); node = node.Children[1]; } } link = new ClipLink(); link.Model = this; link.Sector = node; link.NextInSector = node.Links; link.PreviousInSector = null; if(node.Links != null) { node.Links.PreviousInSector = link; } node.Links = link; link.NextLink = _clipLinks; _clipLinks = link; }