Esempio n. 1
0
        private int Process(ref Image <Rgba32> target, KeyValuePair <ResourceLocation, Image <Rgba32> >[] data, ref int xi, ref int yi, ref int xOffset, ref int yRemaining, int total, int processed, IDictionary <ResourceLocation, TextureInfo> locations, IProgressReceiver progressReceiver, bool animated)
        {
            int done  = processed;
            var count = 0;

            foreach (var bm in data.OrderByDescending(x => x.Value.Height))
            {
                var key = bm.Key;
                count++;

                // double percentage = 100D * ((double)processed / (double)total);
                progressReceiver.UpdateProgress(processed, total, null, key.ToString());

                var sourceRegion = new System.Drawing.Rectangle(0, 0, bm.Value.Width, bm.Value.Height);
                var targetRegion = new System.Drawing.Rectangle(xi, yi, bm.Value.Width, bm.Value.Height);

                TextureUtils.CopyRegionIntoImage(bm.Value, sourceRegion, ref target, targetRegion);

                if (!locations.ContainsKey(key))
                {
                    locations.Add(key, new TextureInfo(new Vector2(target.Width, target.Height), new Vector2(xi, yi), bm.Value.Width / 16, bm.Value.Height / 16, animated, true));
                }

                if (bm.Value.Height > TextureHeight)
                {
                    xOffset    = xi;
                    yRemaining = bm.Value.Height;
                }
                xi += bm.Value.Width;

                if (count == target.Width / TextureWidth)
                {
                    yi         += TextureHeight;
                    xi          = 0;
                    yRemaining -= TextureHeight;

                    count = 0;
                }

                done++;
            }

            return(done);
        }
Esempio n. 2
0
        private PooledTexture2D[] ProcessFrames(GraphicsDevice device, IProgressReceiver progressReceiver,
                                                IDictionary <ResourceLocation, ImageEntry> blockTextures)
        {
            Dictionary <ResourceLocation, Image <Rgba32>[]> blockFrames =
                new Dictionary <ResourceLocation, Image <Rgba32>[]>();

            foreach (var other in blockTextures.Where(
                         x => x.Value.Image.Height != x.Value.Image.Width))
            {
                if (!blockFrames.TryGetValue(other.Key, out _))
                {
                    blockFrames.Add(other.Key, GetFrames(other.Value, TextureWidth, TextureHeight));
                }
            }

            var animatedFrameInfo = new Dictionary <ResourceLocation, TextureInfo>();

            GenerateAtlasInternal(
                blockFrames.Select(x => new KeyValuePair <ResourceLocation, Image <Rgba32> >(x.Key, x.Value[0])).ToArray(),
                progressReceiver, animatedFrameInfo, true, out var animatedFrame);

            AnimatedAtlasSize       = new Vector2(animatedFrame.Width, animatedFrame.Height);
            _animatedAtlasLocations = animatedFrameInfo;


            var frameCount = blockFrames.Max(x => x.Value.Length);

            while (frameCount % 2 != 0)
            {
                frameCount++;
            }

            var frames = new Image <Rgba32> [frameCount];

            frames[0] = animatedFrame;

            for (int i = 1; i < frames.Length; i++)
            {
                //  double percentage = 100D * ((double) i / (double) frames.Length);
                progressReceiver.UpdateProgress(i, frames.Length, $"Animating frame {i + 1} / {frames.Length}...");

                var target = (i > 0 ? frames[i - 1] : animatedFrame).CloneAs <Rgba32>();            //new Bitmap(animatedFrame);

                // System.Drawing.Rectangle destination;

                foreach (var animated in blockFrames)
                {
                    progressReceiver.UpdateProgress(i, frames.Length, null, animated.Key.ToString());

                    if (animatedFrameInfo.TryGetValue(animated.Key, out var textureInfo))
                    {
                        //((i % 3 == 0 ? i - 1 : i) / 6)

                        var destination = new System.Drawing.Rectangle(
                            (int)textureInfo.Position.X, (int)textureInfo.Position.Y, textureInfo.Width * 16,
                            textureInfo.Height * 16);

                        var sourceRegion = new System.Drawing.Rectangle(0, 0, textureInfo.Width * 16, textureInfo.Height * 16);

                        var index = i % animated.Value.Length;

                        var   indexOffset        = 0;
                        bool  shouldInterpolate  = false;
                        float interpolationValue = 0.5f;

                        if (blockTextures.TryGetValue(animated.Key, out var imageEntry) && imageEntry.Meta != null)
                        {
                            var meta = imageEntry.Meta;

                            if (meta.Animation != null)
                            {
                                if (meta.Animation.Interpolate)
                                {
                                    int extraFrames = (frames.Length - animated.Value.Length);

                                    var interpolationFrames = (int)Math.Floor(
                                        ((double)extraFrames / (double)animated.Value.Length));

                                    var remainder = i % interpolationFrames;

                                    if (remainder != 0)
                                    {
                                        shouldInterpolate  = true;
                                        interpolationValue = (1f / interpolationFrames) * remainder;

                                        indexOffset = -remainder;
                                        //   index -= remainder;
                                    }
                                }

                                if (meta.Animation.Frames != null)
                                {
                                    var entry = meta.Animation.Frames[(i + indexOffset) % meta.Animation.Frames.Length];

                                    if (entry.Integer.HasValue)
                                    {
                                        index = (int)entry.Integer.Value;
                                    }
                                    else if (entry.FrameClass != null)
                                    {
                                        index = (int)entry.FrameClass.Index;
                                    }
                                }
                                else
                                {
                                    index = (i + indexOffset) % animated.Value.Length;
                                }
                            }
                        }

                        //TextureUtils.ClearRegion(ref target, destination);

                        if (shouldInterpolate)
                        {
                            TextureUtils.CopyRegionIntoImage(
                                ((i + indexOffset >= 0) ? frames[(i + indexOffset) % frames.Length] : animatedFrame),
                                destination, ref target, destination, clear: true);
                        }

                        var texture = animated.Value[index];

                        TextureUtils.CopyRegionIntoImage(
                            texture, sourceRegion, ref target, destination, shouldInterpolate, interpolationValue,
                            clear: !shouldInterpolate);
                    }
                }

                frames[i] = target;
            }

            return(frames.Select(
                       (x, index) =>
            {
                var a = GetMipMappedTexture2D(device, x);
                //totalSize += a.MemoryUsage;

                return a;
            }).ToArray());
        }