Example #1
0
        public Texture CreateTexture(Device device)
        {
            lock (FLockTexture)
            {
                if (InputOK)
                {
                    Texture output;

                    if (FNeedsConversion)
                    {
                        output = ImageUtils.CreateTexture(FBufferConverted.ImageAttributes.Clone() as CVImageAttributes, device);
                    }
                    else
                    {
                        output = ImageUtils.CreateTexture(FInput.ImageAttributes, device);
                    }

                    FNeedsRefresh.Add(output, true);
                    return(output);
                }
                else
                {
                    return(TextureUtils.CreateTexture(device, 1, 1));
                }
            }
        }
		//this method gets called, when Reinitialize() was called in evaluate,
		//or a graphics device asks for its data
		protected override Texture CreateTexture(int Slice, Device device)
		{
			if (FProcessor.SliceCount > Slice)
				if (FProcessor.GetProcessor(Slice) != null) // we do have a connected input for this slice
					return FProcessor.GetProcessor(Slice).CreateTexture(device);
			
			return TextureUtils.CreateTexture(device, 1, 1);
				
		}
Example #3
0
 //this method gets called, when Reinitialize() was called in evaluate,
 //or a graphics device asks for its data
 Texture CreateTexture(Info info, Device device)
 {
     if (info.QRCodeBMP != null)
     {
         return(TextureUtils.CreateTexture(device, Math.Max(info.QRCodeBMP.Width, 1), Math.Max(info.QRCodeBMP.Height, 1)));
     }
     else
     {
         return(null);
     }
 }
        //this method gets called, when Reinitialize() was called in evaluate,
        //or a graphics device asks for its data
        protected override Texture CreateTexture(int slice, Device device)
        {
            FLogger.Log(LogType.Debug, "Creating new texture at slice: " + slice);

            if (FImageInstances.SliceCount > 0)
            {
                if (FImageInstances[slice].Initialised)
                {
                    return(TextureUtils.CreateTexture(device, Math.Max(FImageInstances[slice].Width, 1), Math.Max(FImageInstances[slice].Height, 1)));
                }

                return(TextureUtils.CreateTexture(device, 1, 1));
            }
            return(TextureUtils.CreateTexture(device, 1, 1));
        }
        //this method gets called, when Reinitialize() was called in evaluate,
        //or a graphics device asks for its data
        protected override Texture CreateTexture(int Slice, Device device)
        {
            FLogger.Log(LogType.Debug, "Creating new texture at slice: " + Slice);

            if (FImageInstances.Count > 0)
            {
                if (FImageInstances[Slice].Initialised)
                {
                    return(new Texture(device, Math.Max(FImageInstances[Slice].Width, 1), Math.Max(FImageInstances[Slice].Height, 1), 1, Usage.None, Format.L16, Pool.Managed));
                }
                //return TextureUtils.CreateTexture(device, Math.Max(FImageInstances[Slice].Width, 1), Math.Max(FImageInstances[Slice].Height, 1));
                else
                {
                    return(TextureUtils.CreateTexture(device, 1, 1));
                }
            }
            else
            {
                return(TextureUtils.CreateTexture(device, 1, 1));
            }
        }
        // TODO: Use custom structs for all the maps, move out atlas generation to a separate .cs (?).
        private bool CreateAtlasTextures(Dictionary <string, List <DicedUnit> > dicedUnits)
        {
            DisplayProgressBar("Processing diced textures...", .5f);

            // Delete any previously generated atlas textures.
            for (int i = atlasTexturesProperty.arraySize - 1; i >= 0; i--)
            {
                var unusedTexture = atlasTexturesProperty.GetArrayElementAtIndex(i).objectReferenceValue;
                AssetDatabase.DeleteAsset(AssetDatabase.GetAssetPath(unusedTexture));
                DestroyImmediate(unusedTexture, true);
            }
            atlasTexturesProperty.arraySize = 0;

            var atlasCount         = 0;
            var unitSize           = diceUnitSizeProperty.intValue;
            var paddingSize        = paddingProperty.intValue;
            var paddedUnitSize     = unitSize + paddingSize * 2;
            var forceSquare        = this.forceSquareProperty.boolValue;
            var atlasSizeLimit     = this.atlasSizeLimitProperty.intValue;
            var unitsPerAtlasLimit = Mathf.Pow(atlasSizeLimit / paddedUnitSize, 2);

            // Group name->units to name->hash->units map.
            var unitsToPackMap = dicedUnits.Select(nameToUnits => new KeyValuePair <string, Dictionary <int, List <DicedUnit> > >(nameToUnits.Key, nameToUnits.Value
                                                                                                                                  .GroupBy(units => units.ColorsHashCode).ToDictionary(hashToUnitsGroup => hashToUnitsGroup.Key, hashToUnitsGroup => hashToUnitsGroup.ToList())))
                                 .ToDictionary(nameToHashToUnits => nameToHashToUnits.Key, nameToHashToUnits => nameToHashToUnits.Value);

            // Pack units with distinct (inside atlas group) colors to the atlas textures.
            // Insure sprites integrity (units belonging to one sprite should be in a common atlas) and atlas size limit (distinct units per atlas count).
            while (unitsToPackMap.Count > 0)
            {
                atlasCount++;

                var atlasTexture = TextureUtils.CreateTexture(atlasSizeLimit, name: $"{target.name} {atlasCount:000}");
                var hashToUV     = new Dictionary <int, Rect>();         // Colors hash to UV rects map of the packed diced units in the current atlas.
                var yToLastXMap  = new Dictionary <int, int>();          // Y position of a units row in the current atlas to the x position of the last unit in this row.
                var xLimit       = Mathf.NextPowerOfTwo(paddedUnitSize); // Maximum allowed width of the current atlas. Increases by the power of two in the process.
                var packedUnits  = new List <DicedUnit>();               // List of the units packed to the current atlas.

                // Find units that can be packed to the current atlas (respecting atlas size limit and remaining free space).
                Func <KeyValuePair <string, Dictionary <int, List <DicedUnit> > > > findSuitableUnitsToPack = () => {
                    return(unitsToPackMap.FirstOrDefault(nameToHashToUnits => {
                        var unitsToPackCount = nameToHashToUnits.Value.Count(hashToUnits => !hashToUV.ContainsKey(hashToUnits.Key));
                        return hashToUV.Keys.Count + unitsToPackCount <= unitsPerAtlasLimit;
                    }));
                };

                var suitableUnits = findSuitableUnitsToPack();
                if (suitableUnits.Key == null) // None of the source textures fit atlas limit.
                {
                    Debug.LogError("SpriteDicing: Unable to fit input textures to the atlas. Consider increasing atlas size limit.");
                    return(false);
                }

                while (suitableUnits.Key != null)
                {
                    var packingProgress = 1f - (unitsToPackMap.Count / (float)dicedUnits.Count);
                    DisplayProgressBar("Packing diced textures...", .5f + .5f * packingProgress);

                    // Iterate suitable for packing units grouped by their color hashes.
                    foreach (var hashToUnits in suitableUnits.Value)
                    {
                        if (hashToUV.ContainsKey(hashToUnits.Key))
                        {
                            // We've already packed unit with the same colors to this atlas; assign it's UVs to the others in the group.
                            hashToUnits.Value.ForEach(unit => unit.QuadUVs = hashToUV[hashToUnits.Key]);
                            continue;
                        }

                        int posX, posY; // Position of the new unit on the atlas texture.
                        // Find row positions that have enough room for more units until next power of two.
                        var suitableYToLastXEnumerable = yToLastXMap.Where(yToLastX => xLimit - yToLastX.Value >= paddedUnitSize * 2);
                        if (suitableYToLastXEnumerable.Count() == 0) // When no suitable rows found.
                        {
                            // Handle corner case when we just started.
                            if (yToLastXMap.Count == 0)
                            {
                                yToLastXMap.Add(0, 0);
                                posX = 0;
                                posY = 0;
                            }
                            // Determine whether we need to add a new row or increase x limit.
                            else if (xLimit > yToLastXMap.Last().Key)
                            {
                                var newRowYPos = yToLastXMap.Last().Key + paddedUnitSize;
                                yToLastXMap.Add(newRowYPos, 0);
                                posX = 0;
                                posY = newRowYPos;
                            }
                            else
                            {
                                xLimit         = Mathf.NextPowerOfTwo(xLimit + 1);
                                posX           = yToLastXMap.First().Value + paddedUnitSize;
                                posY           = 0;
                                yToLastXMap[0] = posX;
                            }
                        }
                        else // When suitable rows found.
                        {
                            // Find one with the least number of elements and use it.
                            var suitableYToLastX = suitableYToLastXEnumerable.OrderBy(yToLastX => yToLastX.Value).First();
                            posX = suitableYToLastX.Value + paddedUnitSize;
                            posY = suitableYToLastX.Key;
                            yToLastXMap[posY] = posX;
                        }

                        // Write colors of the unit to the current atlas texture.
                        var colorsToPack = hashToUnits.Value.First().PaddedColors;
                        atlasTexture.SetPixels(posX, posY, paddedUnitSize, paddedUnitSize, colorsToPack);
                        // Evaluate and assign UVs of the unit to the other units in the group.
                        var unitUVRect = new Rect(posX, posY, paddedUnitSize, paddedUnitSize).Crop(-paddingSize).Scale(1f / atlasSizeLimit);
                        hashToUnits.Value.ForEach(unit => unit.QuadUVs = unitUVRect);
                        hashToUV.Add(hashToUnits.Key, unitUVRect);
                    }

                    packedUnits.AddRange(suitableUnits.Value.SelectMany(u => u.Value));
                    unitsToPackMap.Remove(suitableUnits.Key);
                    suitableUnits = findSuitableUnitsToPack();
                }

                // Crop unused atlas texture space.
                var needToCrop = xLimit < atlasSizeLimit || (!forceSquare && yToLastXMap.Last().Key + paddedUnitSize < atlasSizeLimit);
                if (needToCrop)
                {
                    var croppedWidth  = xLimit;
                    var croppedHeight = forceSquare ? croppedWidth : yToLastXMap.Last().Key + paddedUnitSize;
                    var croppedPixels = atlasTexture.GetPixels(0, 0, croppedWidth, croppedHeight);
                    atlasTexture = TextureUtils.CreateTexture(croppedWidth, croppedHeight, name: atlasTexture.name);
                    atlasTexture.SetPixels(croppedPixels);

                    // Correct UV rects after crop.
                    packedUnits.ForEach(unit => unit.QuadUVs = unit.QuadUVs
                                                               .Scale(new Vector2(atlasSizeLimit / (float)croppedWidth, atlasSizeLimit / (float)croppedHeight)));
                }

                // Save atlas texture.
                atlasTexture.alphaIsTransparency = true;
                atlasTexture.Apply();
                var savedTexture = atlasTexture.SaveAsPng(AssetDatabase.GetAssetPath(target));
                atlasTexturesProperty.arraySize = Mathf.Max(atlasTexturesProperty.arraySize, atlasCount);
                atlasTexturesProperty.GetArrayElementAtIndex(atlasCount - 1).objectReferenceValue = savedTexture;
                packedUnits.ForEach(unit => unit.AtlasTexture = savedTexture);
            }

            return(true);
        }
Example #7
0
 //this method gets called, when Reinitialize() was called in evaluate,
 //or a graphics device asks for its data
 Texture CreateTexture(Info info, Device device)
 {
     FLogger.Log(LogType.Debug, "Creating new texture at slice: " + info.Slice);
     return(TextureUtils.CreateTexture(device, Math.Max(info.Width, 1), Math.Max(info.Height, 1)));
 }
Example #8
0
 //this method gets called, when Reinitialize() was called in evaluate,
 //or a graphics device asks for its data
 Texture CreateTexture(Info info, Device device)
 {
     return(TextureUtils.CreateTexture(device, Math.Max(info.Width, 1), Math.Max(info.Height, 1)));
 }
Example #9
0
 //this method gets called, when Reinitialize() was called in evaluate,
 //or a graphics device asks for its data
 protected override Texture CreateTexture(int Slice, Device device)
 {
     FLogger.Log(LogType.Debug, "Creating new texture at slice: " + Slice);
     return(TextureUtils.CreateTexture(device, Math.Max(FSizes[Slice].Width, 1), Math.Max(FSizes[Slice].Height, 1)));
 }
Example #10
0
 public void SetBackground(LColor color)
 {
     this.SetBackground(TextureUtils.CreateTexture(width, height, color));
 }
Example #11
0
 public static LTransition NewCrossRandom(LColor c)
 {
     return(NewCross(MathUtils.Random(0, 1), TextureUtils
                     .CreateTexture(LSystem.screenRect.width,
                                    LSystem.screenRect.height, c)));
 }
Example #12
0
 public static LTransition NewSplitRandom(LColor c)
 {
     return(NewSplitRandom(TextureUtils.CreateTexture(
                               LSystem.screenRect.width, LSystem.screenRect.height, c)));
 }
Example #13
0
            Texture CreateTexture(Info info, Device device)
            {
                //FLogger.Log(LogType.Debug, "CreateTexture()");

                return(TextureUtils.CreateTexture(device, info.Width, info.Height));
            }
Example #14
0
 public void SetBackground(LColor color)
 {
     SetBackground(TextureUtils
                   .CreateTexture(GetWidth(), GetHeight(), color));
 }