public void Trim(ref BitmapExtended target) { // Get biggest Y float biggestY = GetBiggestYPoint(); // Get biggest X float biggestX = GetBiggestXPoint(); // Get next largest power of two int atlasWidth = biggestX < AtlasCreator.AtlasSize ? GetNextPowerOfTwo(biggestX) : AtlasCreator.AtlasSize; int atlasHeight = biggestY < AtlasCreator.AtlasSize ? GetNextPowerOfTwo(biggestY) : AtlasCreator.AtlasSize; TrimRecs(atlasWidth, atlasHeight); target = new BitmapExtended(atlasWidth, atlasHeight); }
public void Clear() { if (child != null) { if (child[0] != null) { child[0].Clear(); } if (child[1] != null) { child[1].Clear(); } } if (imageRef != null) { imageRef = null; } }
public void Build(BitmapExtended target) { if (child != null) { if (child[0] != null) { child[0].Build(target); } if (child[1] != null) { child[1].Build(target); } } if (imageRef != null) { PixelMap data = imageRef.GetPixels(); for (int x = 0; x < imageRef.Width; ++x) { for (int y = 0; y < imageRef.Height; ++y) { //target.SetPixel(x + (int)rc.X, y + (int)rc.Y, data[x + y]);// * imageRef.Width]); target.SetPixel(x + (int)rc.X, y + (int)rc.Y, data.GetPixel(x, y)); } } // Artificial texture bleeding! if (TEXTURE_PADDING > 0 && BLEED) { for (int y = 0; y < imageRef.Height; ++y) { int x = imageRef.Width - 1; target.SetPixel(x + (int)rc.X + TEXTURE_PADDING, y + (int)rc.Y, data.GetPixel(x, y)); } for (int x = 0; x < imageRef.Width; ++x) { int y = imageRef.Height - 1; target.SetPixel(x + (int)rc.X, y + (int)rc.Y + TEXTURE_PADDING, data.GetPixel(x, y)); } } } }
// The insert function traverses the tree looking for a place to insert the texture. // It returns the node of the atlas the texture can go into or null to say it can't fit. // Note we really don't have to store the rectangle for each node. // All we need is a split direction and coordinate like in a kd-tree, but it's more convenient with rects. public AtlasNode Insert(BitmapExtended image, int index) { if (image == null) // Obviously an error! { return(null); } if (child != null) {// If this node is not a leaf, try inserting into first child. AtlasNode newNode = child[0].Insert(image, index); if (newNode != null) { return(newNode); } // No more room in first child, insert into second child! return(child[1].Insert(image, index)); } else { // If there is already a lightmap in this node, early out if (hasBitmapExtended) { return(null); } // If this node is too small for the image, return if (!BitmapExtendedFits(image, rc)) { return(null); } // If the image is perfect, accept! if (PerfectFit(image, rc)) { hasBitmapExtended = true; imageRef = image; name = imageRef.Name; sortIndex = index; return(this); } // If we made it this far, this node must be split. child = new AtlasNode[2]; child[0] = new AtlasNode(); child[1] = new AtlasNode(); // Decide which way to split image float deltaW = rc.Width - image.Width; float deltaH = rc.Height - image.Height; if (deltaW > deltaH) { child[0].rc = new Rect(rc.xMin, rc.yMin, image.Width, rc.Height); child[1].rc = new Rect(rc.xMin + image.Width + TEXTURE_PADDING, rc.yMin, rc.Width - (image.Width + TEXTURE_PADDING), rc.Height); } else { child[0].rc = new Rect(rc.xMin, rc.yMin, rc.Width, image.Height); child[1].rc = new Rect(rc.xMin, rc.yMin + image.Height + TEXTURE_PADDING, rc.Width, rc.Height - (image.Height + TEXTURE_PADDING)); } // Lets try inserting into first child, eh? return(child[0].Insert(image, index)); } }
static bool PerfectFit(BitmapExtended image, Rect rect) { return(rect.Width == image.Width && rect.Height == image.Height); }
static bool BitmapExtendedFits(BitmapExtended image, Rect rect) { return(rect.Width >= image.Width && rect.Height >= image.Height); }