public void SplitX(int width_left) { if (occupant != null || first != null) throw new InvalidOperationException(); if (width_left >= width || width_left <= 0) throw new InvalidOperationException(); first = new PlacingNode(x, y, width_left, height); second = new PlacingNode(x + width_left, y, width - width_left, height); }
public void SplitY(int height_left) { if (occupant != null || first != null) throw new InvalidOperationException(); if (height_left >= height || height_left <= 0) throw new InvalidOperationException(); first = new PlacingNode(x, y, width, height_left); second = new PlacingNode(x, y + height_left, width, height - height_left); }
private List<PlacingTexture> PlaceAllTextures(out int width, out int height) { // Divides space using a binary tree and places textures in nodes containing enough room. // http://www.blackpawn.com/texts/lightmaps/ List<PlacingTexture> result = new List<PlacingTexture>(m_textures.Count); long pixelcount = 0; int max_width = 0; int max_height = 0; int y = 0; foreach (LoadingTexture l in m_textures) { PlacingTexture p = new PlacingTexture(l); max_width = Math.Max(max_width, p.CorrectedWidth); max_height = Math.Max(max_height, p.CorrectedHeight); pixelcount += p.Area; p.index = y; result.Add(p); y++; } // sort by area descending result.Sort((p, q) => q.Area.CompareTo(p.Area)); int min_width = Math.Max(max_width, MinWidth); int min_height = Math.Max(max_height, MinHeight); int guess_width, guess_height; if (MinWidth == 0 && MinHeight == 0) { guess_width = (int)(Math.Sqrt(pixelcount * 2.0d) + 1); guess_height = Math.Max(min_height, guess_width); guess_width = Math.Max(min_width, guess_width); } else if (MinWidth == 0) { guess_width = Math.Max((int)(pixelcount / min_height), min_width); guess_height = min_height; } else if (MinHeight == 0) { guess_width = min_width; guess_height = Math.Max((int)(pixelcount / MinWidth), min_height); } else { guess_width = min_width; guess_height = min_height; } int real_max_width = MaxWidth; int real_max_height = MaxHeight; if (RequirePot) { guess_width = 1 << (MathHelper.Log2(guess_width)); guess_height = 1 << (MathHelper.Log2(guess_height)); real_max_width = 1 << (MathHelper.Log2(MaxWidth)); real_max_height = 1 << (MathHelper.Log2(MaxHeight)); } if (guess_width == 0) guess_width = guess_height; if (guess_width == 0) { guess_width = 512; guess_height = 512; } PlacingNode root = new PlacingNode(0, 0, guess_width, guess_height); for (int x = 0; x < result.Count; x++) { PlacingTexture p = result[x]; PlacingNode node = root.FindPlacement(p); if (node == null) { if (guess_width <= guess_height && (guess_width < real_max_width || real_max_width == 0)) guess_width = 1 << (MathHelper.Log2(guess_width) + 1); else if (guess_height < real_max_height || real_max_height == 0) guess_height = 1 << (MathHelper.Log2(guess_height) + 1); else if (guess_width < real_max_width || real_max_width == 0) guess_width = 1 << (MathHelper.Log2(guess_width) + 1); else throw new Exception("No room left to place textures."); AssertHelper.Assert(guess_width > root.width || guess_height > root.height); PlacingNode new_root = new PlacingNode(guess_width, guess_height); if (guess_width > root.width) { AssertHelper.Assert(guess_height == root.height); new_root.first = root; new_root.second = new PlacingNode(root.width, 0, guess_width - root.width, root.height); } else { AssertHelper.Assert(guess_width == root.width); new_root.first = root; new_root.second = new PlacingNode(0, root.height, root.width, guess_height - root.height); } root = new_root; x--; continue; } node.Place(p); p.X = node.x; p.Y = node.y; result[x] = p; } width = root.width; height = root.height; result.Sort((p, q) => p.index.CompareTo(q.index)); return result; }