Example #1
0
        /// <summary>Optimizes the atlas by removing all 'holes' (removed images) from the atlas.
        /// It reconstructs the whole atlas (only when there are actually holes), so this method should be considered expensive.
        /// This is only ever called when we fail to add something to the atlas; Theres no performace issues of a non-optimized atlas.
        /// Instead it just simply has very fragmented space available.</summary>
        public bool Optimize()
        {
            if (!CanOptimize)
            {
                // It'll do as it is.
                return(false);
            }

            // Make sure it's not called again:
            CanOptimize       = false;
            OptimizeRequested = false;

            Dictionary <int, AtlasLocation> allImages = Stack.ActiveImages;

            // Clear the textures and add in the starting empty location.
            Reset();

            // Next up, add them all back in, and that's it!
            // The optimizing comes from them trying to fit in the smallest possible gap they can when added.
            foreach (KeyValuePair <int, AtlasLocation> kvp in allImages)
            {
                AtlasLocation location = kvp.Value;

                if (location.Atlas == this)
                {
                    AtlasEntity image = location.Image;

                    int entityID = image.GetAtlasID();

                    int width;
                    int height;

                    image.GetDimensionsOnAtlas(out width, out height);

                    Add(image, entityID, width, height);
                }
            }

            return(true);
        }
        /// <summary>Require the given image on any atlas. Note that this may reject the requirement if the image is too big and isn't worthwhile on an atlas.</summary>
        public AtlasLocation RequireImage(AtlasEntity image)
        {
            int entityID = image.GetAtlasID();

            AtlasLocation result;

            if (ActiveImages.TryGetValue(entityID, out result))
            {
                // Most calls fall through here.
                return(result);
            }

            int width;
            int height;

            image.GetDimensionsOnAtlas(out width, out height);

            if (width > InitialSize || height > InitialSize)
            {
                // Won't fit or is unsuitable for atlasing anyway.
                return(null);
            }

            if (Last == null)
            {
                Create();
            }
            else
            {
                // Fast check - was this texture recently removed from any atlas?
                // We might have the chance of restoring it.
                // Their added at the back of the empty queue, so naturally, start at the end of the empty set
                // and go back until we hit one with a null texture.

                TextureAtlas currentAtlas = Last;

                while (currentAtlas != null)
                {
                    AtlasLocation currentE = currentAtlas.LastEmpty;

                    while (currentE != null)
                    {
                        if (currentE.Image == null)
                        {
                            // Nope! Shame.
                            break;
                        }
                        else if (currentE.AtlasID == entityID)
                        {
                            // Ace! Time to bring it back from the dead.
                            currentE.Select(image, width, height, Spacing);
                            ActiveImages[entityID] = currentE;

                            return(currentE);
                        }

                        currentE = currentE.EmptyBefore;
                    }

                    currentAtlas = currentAtlas.Previous;
                }
            }

            // Push to top of stack:
            result = Last.Add(image, entityID, width, height);

            if (result != null)
            {
                return(result);
            }

            // Non-fitter - try fitting in lower stack frames:

            TextureAtlas current = Last.Previous;

            while (current != null)
            {
                result = current.Add(image, entityID, width, height);

                if (result != null)
                {
                    return(result);
                }

                current = current.Previous;
            }

            // Still not fitting! Create a new stack frame:
            Create();

            return(Last.Add(image, entityID, width, height));
        }
		/// <summary>Require the given image on any atlas. Note that this may reject the requirement if the image is too big and isn't worthwhile on an atlas.</summary>
		public AtlasLocation RequireImage(AtlasEntity image){
			
			int entityID=image.GetAtlasID();
			
			AtlasLocation result;
			if(ActiveImages.TryGetValue(entityID,out result)){
				// Most calls fall through here.
				return result;
			}
			
			int width;
			int height;
			
			image.GetDimensionsOnAtlas(out width,out height);
			
			if(width>InitialSize || height>InitialSize){
				// Won't fit or is unsuitable for atlasing anyway.
				return null;
			}
			
			if(Last==null){
				Create();
			}else{
				
				// Fast check - was this texture recently removed from any atlas?
				// We might have the chance of restoring it.
				// Their added at the back of the empty queue, so naturally, start at the end of the empty set
				// and go back until we hit one with a null texture.
				
				TextureAtlas currentAtlas=Last;
				
				while(currentAtlas!=null){
					
					AtlasLocation currentE=currentAtlas.LastEmpty;
					
					while(currentE!=null){
						
						if(currentE.Image==null){
							// Nope! Shame.
							break;
						}else if(currentE.AtlasID==entityID){
							// Ace! Time to bring it back from the dead.
							currentE.Select(image,width,height,Spacing);
							ActiveImages[entityID]=currentE;
							
							return currentE;
						}
						
						currentE=currentE.EmptyBefore;
					}
					
					currentAtlas=currentAtlas.Previous;
				}
				
			}
			
			// Push to top of stack:
			result=Last.Add(image,entityID,width,height);
			
			if(result!=null){
				return result;
			}
			
			// Non-fitter - try fitting in lower stack frames:
			
			TextureAtlas current=Last.Previous;
			
			while(current!=null){
				
				result=current.Add(image,entityID,width,height);
				
				if(result!=null){
					return result;
				}
				
				current=current.Previous;
			}
			
			// Still not fitting! Create a new stack frame:
			Create();
			
			return Last.Add(image,entityID,width,height);
			
		}