コード例 #1
0
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            var    manifestPath = path / "meta.json";
            string manifestContents;

            using (var manifestFile = cache.ContentFileRead(manifestPath))
                using (var reader = new StreamReader(manifestFile))
                {
                    manifestContents = reader.ReadToEnd();
                }

#if DEBUG
            if (RSISchema != null)
            {
                var errors = RSISchema.Validate(manifestContents);
                if (errors.Count != 0)
                {
                    Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:");

                    foreach (var error in errors)
                    {
                        Logger.Error("{0}", error.ToString());
                    }

                    throw new RSILoadException($"{errors.Count} errors while loading RSI. See console.");
                }
            }
#endif

            // Ok schema validated just fine.
            var manifestJson = JObject.Parse(manifestContents);

            var toAtlas = new List <(Image <Rgba32> src, Texture[][] output, int[][] indices, Vector2i[][] offsets, int totalFrameCount)>();
コード例 #2
0
ファイル: RSIResource.cs プロジェクト: modi0012/RobustToolbox
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            var    manifestPath = path / "meta.json";
            string manifestContents;

            using (var manifestFile = cache.ContentFileRead(manifestPath))
                using (var reader = new StreamReader(manifestFile))
                {
                    manifestContents = reader.ReadToEnd();
                }

            if (RSISchema != null)
            {
                var errors = RSISchema.Validate(manifestContents);
                if (errors.Count != 0)
                {
                    Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:");

                    foreach (var error in errors)
                    {
                        Logger.Error("{0}", error.ToString());
                    }

                    throw new RSILoadException($"{errors.Count} errors while loading RSI. See console.");
                }
            }

            // Ok schema validated just fine.
            var manifestJson = JObject.Parse(manifestContents);
            var size         = manifestJson["size"].ToObject <Vector2u>();

            var rsi = new RSI(size);

            var images = new List <Image <Rgba32> >();
            var directionFramesList = new List <(Texture, float)[]>();
コード例 #3
0
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            var    manifestPath = path / "meta.json";
            string manifestContents;

            using (var manifestFile = cache.ContentFileRead(manifestPath))
                using (var reader = new StreamReader(manifestFile))
                {
                    manifestContents = reader.ReadToEnd();
                }

            if (RSISchema != null)
            {
                var errors = RSISchema.Validate(manifestContents);
                if (errors.Count != 0)
                {
                    Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:");

                    foreach (var error in errors)
                    {
                        Logger.Error("{0}", error.ToString());
                    }

                    throw new RSILoadException($"{errors.Count} errors while loading RSI. See console.");
                }
            }

            // Ok schema validated just fine.
            var manifestJson = JObject.Parse(manifestContents);
            var size         = manifestJson["size"].ToObject <Vector2u>();

            var rsi = new RSI(size);

            // Do every state.
            foreach (var stateObject in manifestJson["states"].Cast <JObject>())
            {
                var stateName = stateObject["name"].ToObject <string>();
                var dirValue  = stateObject["directions"].ToObject <int>();
                RSI.State.DirectionType directions;

                switch (dirValue)
                {
                case 1:
                    directions = RSI.State.DirectionType.Dir1;
                    break;

                case 4:
                    directions = RSI.State.DirectionType.Dir4;
                    break;

                default:
                    throw new RSILoadException($"Invalid direction: {dirValue}");
                }

                // We can ignore selectors and flags for now,
                // because they're not used yet!

                // Get the lists of delays.
                float[][] delays;
                if (stateObject.TryGetValue("delays", out var delayToken))
                {
                    delays = delayToken.ToObject <float[][]>();

                    if (delays.Length != dirValue)
                    {
                        throw new RSILoadException($"Directions count does not match amount of delays specified.");
                    }

                    for (var i = 0; i < delays.Length; i++)
                    {
                        var delayList = delays[i];
                        if (delayList.Length == 0)
                        {
                            delays[i] = new float[] { 1 };
                        }
                    }
                }
                else
                {
                    delays = new float[dirValue][];
                    // No delays specified, default to 1 frame per dir.
                    for (var i = 0; i < dirValue; i++)
                    {
                        delays[i] = new float[] { 1 };
                    }
                }

                var texPath = path / (stateName + ".png");
                var texture = cache.GetResource <TextureResource>(texPath).Texture;

                if (texture.Width % size.X != 0 || texture.Height % size.Y != 0)
                {
                    throw new RSILoadException("State image size is not a multiple of the icon size.");
                }

                // Amount of icons per row of the sprite sheet.
                var sheetWidth = texture.Width / size.X;

                var iconFrames = new (Texture, float)[dirValue][];
コード例 #4
0
        public override void Load(IResourceCache cache, ResourcePath path)
        {
            var    manifestPath = path / "meta.json";
            string manifestContents;

            using (var manifestFile = cache.ContentFileRead(manifestPath))
                using (var reader = new StreamReader(manifestFile))
                {
                    manifestContents = reader.ReadToEnd();
                }

#if DEBUG
            if (RSISchema != null)
            {
                var errors = RSISchema.Validate(manifestContents);
                if (errors.Count != 0)
                {
                    Logger.Error($"Unable to load RSI from '{path}', {errors.Count} errors:");

                    foreach (var error in errors)
                    {
                        Logger.Error("{0}", error.ToString());
                    }

                    throw new RSILoadException($"{errors.Count} errors while loading RSI. See console.");
                }
            }
#endif

            // Ok schema validated just fine.
            var manifestJson = JObject.Parse(manifestContents);

            var toAtlas = new List <(Image <Rgba32> src, Texture[][] output, int[][] indices, int totalFrameCount)>();

            var metaData  = ParseMetaData(manifestJson);
            var frameSize = metaData.Size;
            var rsi       = new RSI(frameSize);

            // Do every state.
            foreach (var stateObject in metaData.States)
            {
                // Load image from disk.
                var texPath   = path / (stateObject.StateId + ".png");
                var image     = Image.Load(cache.ContentFileRead(texPath));
                var sheetSize = new Vector2i(image.Width, image.Height);

                if (sheetSize.X % frameSize.X != 0 || sheetSize.Y % frameSize.Y != 0)
                {
                    throw new RSILoadException("State image size is not a multiple of the icon size.");
                }

                // Load all frames into a list so we can operate on it more sanely.
                var frameCount = stateObject.Delays.Sum(delayList => delayList.Length);

                var(foldedDelays, foldedIndices) = FoldDelays(stateObject.Delays);

                var textures = new Texture[foldedIndices.Length][];

                for (var i = 0; i < textures.Length; i++)
                {
                    textures[i] = new Texture[foldedIndices[0].Length];
                }

                var state = new RSI.State(frameSize, stateObject.StateId, stateObject.DirType, foldedDelays, textures);
                rsi.AddState(state);

                toAtlas.Add((image, textures, foldedIndices, frameCount));
            }

            // Poorly hacked in texture atlas support here.
            {
                var totalFrameCount = toAtlas.Sum(p => p.totalFrameCount);

                // Generate atlas.
                var dimensionX = (int)MathF.Ceiling(MathF.Sqrt(totalFrameCount));
                var dimensionY = (int)MathF.Ceiling((float)totalFrameCount / dimensionX);

                using var sheet = new Image <Rgba32>(dimensionX * frameSize.X, dimensionY * frameSize.Y);

                var sheetIndex = 0;
                foreach (var(src, _, _, frameCount) in toAtlas)
                {
                    // Blit all the frames over.
                    for (var i = 0; i < frameCount; i++)
                    {
                        var srcWidth  = (src.Width / frameSize.X);
                        var srcColumn = i % srcWidth;
                        var srcRow    = i / srcWidth;
                        var srcPos    = (srcColumn * frameSize.X, srcRow *frameSize.Y);

                        var sheetColumn = (sheetIndex + i) % dimensionX;
                        var sheetRow    = (sheetIndex + i) / dimensionX;
                        var sheetPos    = (sheetColumn * frameSize.X, sheetRow *frameSize.Y);

                        var srcBox = UIBox2i.FromDimensions(srcPos, frameSize);

                        src.Blit(srcBox, sheet, sheetPos);
                    }

                    sheetIndex += frameCount;
                }

                // Load atlas.
                var texture = Texture.LoadFromImage(sheet, path.ToString());

                var sheetOffset = 0;
                foreach (var(src, output, indices, frameCount) in toAtlas)
                {
                    for (var i = 0; i < indices.Length; i++)
                    {
                        var dirIndices = indices[i];
                        var dirOutput  = output[i];

                        for (var j = 0; j < dirIndices.Length; j++)
                        {
                            var index = sheetOffset + dirIndices[j];

                            var sheetColumn = index % dimensionX;
                            var sheetRow    = index / dimensionX;
                            var sheetPos    = (sheetColumn * frameSize.X, sheetRow *frameSize.Y);

                            dirOutput[j] = new AtlasTexture(texture, UIBox2.FromDimensions(sheetPos, frameSize));
                        }
                    }

                    sheetOffset += frameCount;
                }
            }

            foreach (var(image, _, _, _) in toAtlas)
            {
                image.Dispose();
            }

            RSI = rsi;
        }