예제 #1
0
        static bool AddSubImageIfPossible( InputBitmap ib, OutputBitmap ob, bool allowImageResize )
        {
            if ( ob.SingleImageOutput )
                return false;

            // attempt to fill a small power of 2 texture first, then expand it gradually up to the maximum size
            // if the sub images don't fit. mVirtualSize is the size of the current rect we are trying to fill
            if ( ob.AvailableRects.Count == 0 )
            {
                // first time this output bitmap has been used, try using the smallest possible virtual texture size
                ob.InitVirtualSize( ib.mBitmap.Size );
            }

            if ( allowImageResize )
            {
                while ( !InsertImage( ib, ob ) )
                {
                    // no images could be inserted in current image using current virtual size.
                    // increase virtual size and try again
                    if ( !ob.IncreaseVirtualSize() )
                        return false; // cannot fit anymore images into this output image
                }
                return true;
            }
            else
                return InsertImage( ib, ob );
        }
예제 #2
0
        public static List<OutputBitmap> BreakIntoOutputBitmaps( List<InputBitmap> inputBitmaps, string outputName )
        {
            RemoveInvalidInputBitmaps( inputBitmaps );
            SortBySize( inputBitmaps );

            List<OutputBitmap> outputBitmaps = new List<OutputBitmap>();
            while ( inputBitmaps.Count > 0 )
            {
                InputBitmap inputImage = inputBitmaps[ 0 ];
                if ( OutputBitmap.IsInputImageValidSize( inputBitmaps[ 0 ].mBitmap ) )
                {
                    bool imageHasBeenAdded = AddSubImageIfPossible( inputBitmaps[ 0 ], outputBitmaps );

                    // add a new output bitmap if an existing space can't be found
                    if ( !imageHasBeenAdded )
                    {
                        OutputBitmap newOutput = new OutputBitmap( outputName, outputBitmaps.Count );
                        outputBitmaps.Add( newOutput );
                    }
                    else
                        inputBitmaps.Remove( inputBitmaps[ 0 ] );
                }
                else
                {
                    // if larger than target atlas size, just copy the input image over and add it to the page list
                    OutputBitmap newOutput = new OutputBitmap( outputName, outputBitmaps.Count, inputBitmaps[0].mBitmap.Width, inputBitmaps[0].mBitmap.Height );
                    newOutput.CopyImageIntoImage( inputBitmaps[ 0 ].mBitmap, new Point( 0, 0 ), false );
                    newOutput.SubImages.Add( new SubImage( inputImage.mName, Util.FormatSubImageName( inputImage.mName ), new Rectangle( new Point( 0, 0 ), inputImage.mBitmap.Size ), false ) );
                    outputBitmaps.Add( newOutput );
                    inputBitmaps.Remove( inputBitmaps[ 0 ] );
                }
            }
            return outputBitmaps;
        }
예제 #3
0
 static void AddAvailableRect( OutputBitmap ob, Rectangle rect )
 {
     if ( Util.IsValidRect( rect ) )
     {
         ob.AvailableRects.Add( rect );
     }
 }
예제 #4
0
 static void AddAvailableRect(OutputBitmap ob, Rectangle rect)
 {
     if (Util.IsValidRect(rect))
     {
         ob.AvailableRects.Add(rect);
     }
 }
예제 #5
0
        static bool InsertImage(InputBitmap inputImage, OutputBitmap ob)
        {
            foreach (Rectangle rect in ob.AvailableRects)
            {
                bool isRotated = false;
                if (ImageFitsInRect(rect, inputImage.mBitmap, out isRotated))
                {
                    Size  paddingSize = new Size(GetPaddingWidth(rect), GetPaddingHeight(rect));
                    Point locationIncludingPadding = new Point(rect.X + paddingSize.Width, rect.Y + paddingSize.Height);
                    // copy image data
                    ob.CopyImageIntoImage(inputImage.mBitmap, locationIncludingPadding, isRotated);

                    // remove old rect, add 2 new ones
                    // when storing a square inside a larger square, will always leave 2 other rectangles, one on the bottom
                    // and one on the right. These rects are added to a list and then used to see if any future input images can fit
                    ob.AvailableRects.Remove(rect);
                    Size subImageSize = isRotated ? new Size(inputImage.mBitmap.Height, inputImage.mBitmap.Width) : inputImage.mBitmap.Size;
                    SplitRect(ob, rect, subImageSize + paddingSize);

                    ob.SubImages.Add(new SubImage(inputImage.mName, Util.FormatSubImageName(inputImage.mName), new Rectangle(locationIncludingPadding, subImageSize), isRotated));

                    ob.SortRectList();

                    return(true);
                }
            }

            return(false);
        }
예제 #6
0
        static bool AddSubImageIfPossible(InputBitmap ib, OutputBitmap ob, bool allowImageResize)
        {
            if (ob.SingleImageOutput)
            {
                return(false);
            }

            // attempt to fill a small power of 2 texture first, then expand it gradually up to the maximum size
            // if the sub images don't fit. mVirtualSize is the size of the current rect we are trying to fill
            if (ob.AvailableRects.Count == 0)
            {
                // first time this output bitmap has been used, try using the smallest possible virtual texture size
                ob.InitVirtualSize(ib.mBitmap.Size);
            }

            if (allowImageResize)
            {
                while (!InsertImage(ib, ob))
                {
                    // no images could be inserted in current image using current virtual size.
                    // increase virtual size and try again
                    if (!ob.IncreaseVirtualSize())
                    {
                        return(false);                        // cannot fit anymore images into this output image
                    }
                }
                return(true);
            }
            else
            {
                return(InsertImage(ib, ob));
            }
        }
예제 #7
0
        static void SplitRect(OutputBitmap ob, Rectangle rect, Size newImageSize)
        {
            // Split area into 2 rects, calculate which will generate the largest possible child.

            Rectangle rightRectLarge = new Rectangle();

            rightRectLarge.X      = rect.X + newImageSize.Width;
            rightRectLarge.Y      = rect.Y;
            rightRectLarge.Width  = rect.Width - newImageSize.Width;
            rightRectLarge.Height = rect.Height;

            Rectangle bottomRectSmall = new Rectangle();

            bottomRectSmall.X      = rect.X;
            bottomRectSmall.Y      = rect.Y + newImageSize.Height;
            bottomRectSmall.Width  = rect.Width - rightRectLarge.Width;
            bottomRectSmall.Height = rect.Height - newImageSize.Height;

            Rectangle bottomRectLarge = new Rectangle();

            bottomRectLarge.X      = rect.X;
            bottomRectLarge.Y      = rect.Y + newImageSize.Height;
            bottomRectLarge.Width  = rect.Width;
            bottomRectLarge.Height = rect.Height - newImageSize.Height;

            Rectangle rightRectSmall = new Rectangle();

            rightRectSmall.X      = rect.X + newImageSize.Width;
            rightRectSmall.Y      = rect.Y;
            rightRectSmall.Width  = rect.Width - newImageSize.Width;
            rightRectSmall.Height = rect.Height - bottomRectLarge.Height;

            int rightRectLargeArea  = rightRectLarge.Width * rightRectLarge.Height;
            int bottomRectSmallArea = bottomRectSmall.Width * bottomRectSmall.Height;
            int rightRectSmallArea  = rightRectSmall.Width * rightRectSmall.Height;
            int bottomRectLargeArea = bottomRectLarge.Width * bottomRectLarge.Height;

            if (rightRectLargeArea > bottomRectLargeArea || bottomRectSmallArea > rightRectSmallArea ||
                rightRectLargeArea > rightRectSmallArea || bottomRectSmallArea > bottomRectLargeArea)
            {
                AddAvailableRect(ob, rightRectLarge);
                AddAvailableRect(ob, bottomRectSmall);
            }
            else
            {
                AddAvailableRect(ob, bottomRectLarge);
                AddAvailableRect(ob, rightRectSmall);
            }
        }
예제 #8
0
        static void RunDirectory(List <string> inputDirectories, string outputName)
        {
            // Load xml file (if exists)
            string         xmlFilename = GetXmlFilename(outputName);
            InputFileStore fileStore   = InputFileStore.LoadXmlFile(xmlFilename);

            // see if any images have been added / removed / modified
            if (Settings.Instance.ForceBuild || fileStore.RequiresBuild(inputDirectories))
            {
                System.Console.WriteLine("Modifications detected, processing...");

                if (fileStore.XmlSettings != null)
                {
                    Settings.Instance.MergeSettings(fileStore.XmlSettings);
                }

                // if they have, rebuild entire texture listing
                List <InputBitmap> inputBitmaps = new List <InputBitmap>();

                foreach (string dir in inputDirectories)
                {
                    ParseDir(dir, inputBitmaps);
                }

                List <OutputBitmap> outputBitmaps = PackingProcess.BreakIntoOutputBitmaps(inputBitmaps, outputName);

                int index = 0;
                foreach (OutputBitmap obi in outputBitmaps)
                {
                    obi.SaveFile();
                    index++;
                }

                foreach (InputBitmap ib in inputBitmaps)
                {
                    ib.mBitmap.Dispose();
                    ib.mBitmap = null;
                }

                OutputBitmap.OutputXmlFile(outputBitmaps, xmlFilename);

                System.Console.WriteLine("Texture building completed successfully");
            }
            else
            {
                System.Console.WriteLine("No modifications detected, exiting...");
            }
        }
예제 #9
0
        public static List <OutputBitmap> BreakIntoOutputBitmaps(List <InputBitmap> inputBitmaps, string outputName)
        {
            RemoveInvalidInputBitmaps(inputBitmaps);
            SortBySize(inputBitmaps);

            List <OutputBitmap> outputBitmaps = new List <OutputBitmap>();

            while (inputBitmaps.Count > 0)
            {
                InputBitmap inputImage = inputBitmaps[0];
                if (OutputBitmap.IsInputImageValidSize(inputBitmaps[0].mBitmap))
                {
                    bool imageHasBeenAdded = AddSubImageIfPossible(inputBitmaps[0], outputBitmaps);

                    // add a new output bitmap if an existing space can't be found
                    if (!imageHasBeenAdded)
                    {
                        OutputBitmap newOutput = new OutputBitmap(outputName, outputBitmaps.Count);
                        outputBitmaps.Add(newOutput);
                    }
                    else
                    {
                        inputBitmaps.Remove(inputBitmaps[0]);
                    }
                }
                else
                {
                    // if larger than target atlas size, just copy the input image over and add it to the page list
                    OutputBitmap newOutput = new OutputBitmap(outputName, outputBitmaps.Count, inputBitmaps[0].mBitmap.Width, inputBitmaps[0].mBitmap.Height);
                    newOutput.CopyImageIntoImage(inputBitmaps[0].mBitmap, new Point(0, 0), false);
                    newOutput.SubImages.Add(new SubImage(inputImage.mName, Util.FormatSubImageName(inputImage.mName), new Rectangle(new Point(0, 0), inputImage.mBitmap.Size), false));
                    outputBitmaps.Add(newOutput);
                    inputBitmaps.Remove(inputBitmaps[0]);
                }
            }
            return(outputBitmaps);
        }
예제 #10
0
        static void SplitRect( OutputBitmap ob, Rectangle rect, Size newImageSize )
        {
            // Split area into 2 rects, calculate which will generate the largest possible child.

            Rectangle rightRectLarge = new Rectangle();
            rightRectLarge.X = rect.X + newImageSize.Width;
            rightRectLarge.Y = rect.Y;
            rightRectLarge.Width = rect.Width - newImageSize.Width;
            rightRectLarge.Height = rect.Height;

            Rectangle bottomRectSmall = new Rectangle();
            bottomRectSmall.X = rect.X;
            bottomRectSmall.Y = rect.Y + newImageSize.Height;
            bottomRectSmall.Width = rect.Width - rightRectLarge.Width;
            bottomRectSmall.Height = rect.Height - newImageSize.Height;

            Rectangle bottomRectLarge = new Rectangle();
            bottomRectLarge.X = rect.X;
            bottomRectLarge.Y = rect.Y + newImageSize.Height;
            bottomRectLarge.Width = rect.Width;
            bottomRectLarge.Height = rect.Height - newImageSize.Height;

            Rectangle rightRectSmall = new Rectangle();
            rightRectSmall.X = rect.X + newImageSize.Width;
            rightRectSmall.Y = rect.Y;
            rightRectSmall.Width = rect.Width - newImageSize.Width;
            rightRectSmall.Height = rect.Height - bottomRectLarge.Height;

            int rightRectLargeArea = rightRectLarge.Width * rightRectLarge.Height;
            int bottomRectSmallArea = bottomRectSmall.Width * bottomRectSmall.Height;
            int rightRectSmallArea = rightRectSmall.Width * rightRectSmall.Height;
            int bottomRectLargeArea = bottomRectLarge.Width * bottomRectLarge.Height;

            if ( rightRectLargeArea > bottomRectLargeArea || bottomRectSmallArea > rightRectSmallArea
                || rightRectLargeArea > rightRectSmallArea || bottomRectSmallArea > bottomRectLargeArea )
            {
                AddAvailableRect( ob, rightRectLarge );
                AddAvailableRect( ob, bottomRectSmall );
            }
            else
            {
                AddAvailableRect( ob, bottomRectLarge );
                AddAvailableRect( ob, rightRectSmall );
            }
        }
예제 #11
0
        static bool InsertImage( InputBitmap inputImage, OutputBitmap ob )
        {
            foreach ( Rectangle rect in ob.AvailableRects )
            {
                bool isRotated = false;
                if ( ImageFitsInRect( rect, inputImage.mBitmap, out isRotated ) )
                {
                    Size paddingSize = new Size( GetPaddingWidth( rect ), GetPaddingHeight( rect ) );
                    Point locationIncludingPadding = new Point( rect.X + paddingSize.Width, rect.Y + paddingSize.Height );
                    // copy image data
                    ob.CopyImageIntoImage( inputImage.mBitmap, locationIncludingPadding, isRotated );

                    // remove old rect, add 2 new ones
                    // when storing a square inside a larger square, will always leave 2 other rectangles, one on the bottom
                    // and one on the right. These rects are added to a list and then used to see if any future input images can fit
                    ob.AvailableRects.Remove( rect );
                    Size subImageSize = isRotated ? new Size( inputImage.mBitmap.Height, inputImage.mBitmap.Width ) : inputImage.mBitmap.Size;
                    SplitRect( ob, rect, subImageSize + paddingSize );

                    ob.SubImages.Add( new SubImage( inputImage.mName, Util.FormatSubImageName( inputImage.mName ), new Rectangle( locationIncludingPadding, subImageSize ), isRotated ) );

                    ob.SortRectList();

                    return true;
                }
            }

            return false;
        }