コード例 #1
0
        /// <summary>
        /// Function to read the animation data from a stream.
        /// </summary>
        /// <param name="stream">The stream containing the animation.</param>
        /// <param name="byteCount">The number of bytes to read from the stream.</param>
        /// <returns>A new <see cref="IGorgonAnimation"/>.</returns>
        protected override IGorgonAnimation OnReadFromStream(Stream stream, int byteCount)
        {
            var builder = new GorgonAnimationBuilder();

            var reader = new GorgonChunkFileReader(stream,
                                                   new[]
            {
                CurrentFileHeader
            });
            GorgonBinaryReader binReader = null;

            try
            {
                reader.Open();
                binReader = reader.OpenChunk(AnimationData);
                string name      = binReader.ReadString();
                float  length    = binReader.ReadSingle();
                bool   isLooped  = binReader.ReadBoolean();
                int    loopCount = binReader.ReadInt32();
                reader.CloseChunk();

                int keyCount;

                if (reader.Chunks.Contains(PositionData))
                {
                    binReader = reader.OpenChunk(PositionData);
                    builder.PositionInterpolationMode(binReader.ReadValue <TrackInterpolationMode>());
                    keyCount = binReader.ReadInt32();

                    IGorgonTrackKeyBuilder <GorgonKeyVector3> track = builder.EditPositions();
                    for (int i = 0; i < keyCount; ++i)
                    {
                        track.SetKey(new GorgonKeyVector3(binReader.ReadSingle(), binReader.ReadValue <DX.Vector3>()));
                    }
                    track.EndEdit();
                    reader.CloseChunk();
                }

                if (reader.Chunks.Contains(ScaleData))
                {
                    binReader = reader.OpenChunk(ScaleData);
                    builder.ScaleInterpolationMode(binReader.ReadValue <TrackInterpolationMode>());
                    keyCount = binReader.ReadInt32();

                    IGorgonTrackKeyBuilder <GorgonKeyVector3> track = builder.EditScale();
                    for (int i = 0; i < keyCount; ++i)
                    {
                        track.SetKey(new GorgonKeyVector3(binReader.ReadSingle(), binReader.ReadValue <DX.Vector3>()));
                    }
                    track.EndEdit();
                    reader.CloseChunk();
                }

                if (reader.Chunks.Contains(RotationData))
                {
                    binReader = reader.OpenChunk(RotationData);
                    builder.RotationInterpolationMode(binReader.ReadValue <TrackInterpolationMode>());
                    keyCount = binReader.ReadInt32();

                    IGorgonTrackKeyBuilder <GorgonKeyVector3> track = builder.EditRotation();
                    for (int i = 0; i < keyCount; ++i)
                    {
                        track.SetKey(new GorgonKeyVector3(binReader.ReadSingle(), binReader.ReadValue <DX.Vector3>()));
                    }
                    track.EndEdit();
                    reader.CloseChunk();
                }

                if (reader.Chunks.Contains(SizeData))
                {
                    binReader = reader.OpenChunk(SizeData);
                    builder.SizeInterpolationMode(binReader.ReadValue <TrackInterpolationMode>());
                    keyCount = binReader.ReadInt32();

                    IGorgonTrackKeyBuilder <GorgonKeyVector3> track = builder.EditSize();
                    for (int i = 0; i < keyCount; ++i)
                    {
                        track.SetKey(new GorgonKeyVector3(binReader.ReadSingle(), binReader.ReadValue <DX.Vector3>()));
                    }
                    track.EndEdit();
                    reader.CloseChunk();
                }

                if (reader.Chunks.Contains(BoundsData))
                {
                    binReader = reader.OpenChunk(BoundsData);
                    builder.RotationInterpolationMode(binReader.ReadValue <TrackInterpolationMode>());
                    keyCount = binReader.ReadInt32();

                    IGorgonTrackKeyBuilder <GorgonKeyRectangle> track = builder.EditRectangularBounds();
                    for (int i = 0; i < keyCount; ++i)
                    {
                        track.SetKey(new GorgonKeyRectangle(binReader.ReadSingle(), binReader.ReadValue <DX.RectangleF>()));
                    }
                    track.EndEdit();
                    reader.CloseChunk();
                }

                if (reader.Chunks.Contains(ColorData))
                {
                    binReader = reader.OpenChunk(ColorData);
                    builder.RotationInterpolationMode(binReader.ReadValue <TrackInterpolationMode>());
                    keyCount = binReader.ReadInt32();

                    IGorgonTrackKeyBuilder <GorgonKeyGorgonColor> track = builder.EditColors();
                    for (int i = 0; i < keyCount; ++i)
                    {
                        track.SetKey(new GorgonKeyGorgonColor(binReader.ReadSingle(), binReader.ReadValue <GorgonColor>()));
                    }
                    track.EndEdit();
                    reader.CloseChunk();
                }

                IGorgonAnimation result;
                if (!reader.Chunks.Contains(TextureData))
                {
                    result           = builder.Build(name, length);
                    result.IsLooped  = isLooped;
                    result.LoopCount = loopCount;
                    return(result);
                }

                binReader = reader.OpenChunk(TextureData);
                keyCount  = binReader.ReadInt32();

                IGorgonTrackKeyBuilder <GorgonKeyTexture2D> textureTrack = builder.Edit2DTexture();
                for (int i = 0; i < keyCount; ++i)
                {
                    float time                  = binReader.ReadSingle();
                    byte  hasTexture            = binReader.ReadByte();
                    GorgonTexture2DView texture = null;
                    string textureName          = string.Empty;

                    if (hasTexture != 0)
                    {
                        texture = LoadTexture(binReader, out textureName);

                        if ((texture == null) && (string.IsNullOrWhiteSpace(textureName)))
                        {
                            Renderer.Log.Print("Attempted to load a texture from the data, but the texture was not in memory and the name is unknown.",
                                               LoggingLevel.Verbose);
                            continue;
                        }
                    }

                    if ((texture == null) && (hasTexture != 0))
                    {
                        textureTrack.SetKey(new GorgonKeyTexture2D(time, textureName, binReader.ReadValue <DX.RectangleF>(), binReader.ReadInt32()));
                    }
                    else
                    {
                        textureTrack.SetKey(new GorgonKeyTexture2D(time, texture, binReader.ReadValue <DX.RectangleF>(), binReader.ReadInt32()));
                    }
                }
                textureTrack.EndEdit();
                reader.CloseChunk();

                result           = builder.Build(name, length);
                result.IsLooped  = isLooped;
                result.LoopCount = loopCount;
                return(result);
            }
            finally
            {
                binReader?.Dispose();
                reader.Close();
            }
        }
コード例 #2
0
        /// <summary>
        /// Function to convert a JSON formatted string into a <see cref="IGorgonAnimation"/> object.
        /// </summary>
        /// <param name="renderer">The renderer for the animation.</param>
        /// <param name="json">The JSON string containing the animation data.</param>
        /// <returns>A new <see cref="IGorgonAnimation"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="renderer"/>, or the <paramref name="json"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="json"/> parameter is empty.</exception>
        /// <exception cref="GorgonException">Thrown if the JSON string does not contain animation data, or there is a version mismatch.</exception>
        public IGorgonAnimation FromJson(Gorgon2D renderer, string json)
        {
            if (renderer == null)
            {
                throw new ArgumentNullException(nameof(renderer));
            }

            if (json == null)
            {
                throw new ArgumentNullException(nameof(json));
            }

            if (string.IsNullOrWhiteSpace(json))
            {
                throw new ArgumentEmptyException(nameof(json));
            }

            string animName   = string.Empty;
            float  animLength = 0;
            int    loopCount  = 0;
            bool   isLooped   = false;

            var colorConvert   = new JsonGorgonColorKeyConverter();
            var textureConvert = new JsonTextureKeyConverter(renderer.Graphics);
            var vec3Converter  = new JsonVector3KeyConverter();
            var rectConverter  = new JsonRectKeyConverter();

            TrackInterpolationMode posInterp   = TrackInterpolationMode.None;
            TrackInterpolationMode scaleInterp = TrackInterpolationMode.None;
            TrackInterpolationMode rotInterp   = TrackInterpolationMode.None;
            TrackInterpolationMode sizeInterp  = TrackInterpolationMode.None;
            TrackInterpolationMode colorInterp = TrackInterpolationMode.None;
            TrackInterpolationMode boundInterp = TrackInterpolationMode.None;

            List <GorgonKeyVector3>     positions = null;
            List <GorgonKeyVector3>     rotations = null;
            List <GorgonKeyVector3>     scales    = null;
            List <GorgonKeyVector3>     sizes     = null;
            List <GorgonKeyGorgonColor> colors    = null;
            List <GorgonKeyRectangle>   bounds    = null;
            List <GorgonKeyTexture2D>   textures  = null;

            using (var baseReader = new StringReader(json))
                using (var reader = new JsonTextReader(baseReader))
                {
                    if (!IsReadableJObject(reader))
                    {
                        throw new GorgonException(GorgonResult.CannotRead, Resources.GOR2DIO_ERR_JSON_NOT_ANIM);
                    }

                    while (reader.Read())
                    {
                        if (reader.TokenType != JsonToken.PropertyName)
                        {
                            continue;
                        }

                        string propName = reader.Value.ToString().ToUpperInvariant();

                        switch (propName)
                        {
                        case "POSITIONS":
                            positions = ReadVector3(reader, vec3Converter, out posInterp);
                            break;

                        case "SCALES":
                            scales = ReadVector3(reader, vec3Converter, out scaleInterp);
                            break;

                        case "ROTATIONS":
                            rotations = ReadVector3(reader, vec3Converter, out rotInterp);
                            break;

                        case "SIZE":
                            sizes = ReadVector3(reader, vec3Converter, out sizeInterp);
                            break;

                        case "BOUNDS":
                            bounds = ReadRects(reader, rectConverter, out boundInterp);
                            break;

                        case "COLORS":
                            colors = ReadColors(reader, colorConvert, out colorInterp);
                            break;

                        case "TEXTURES":
                            textures = ReadTextures(reader, textureConvert);
                            break;

                        case "NAME":
                            animName = reader.ReadAsString();
                            break;

                        case "LENGTH":
                            animLength = (float)(reader.ReadAsDecimal() ?? 0);
                            break;

                        case "ISLOOPED":
                            isLooped = (reader.ReadAsBoolean() ?? false);
                            break;

                        case "LOOPCOUNT":
                            loopCount = (reader.ReadAsInt32() ?? 0);
                            break;
                        }
                    }
                }

            // There's no name, so it's a broken JSON.
            if (string.IsNullOrWhiteSpace(animName))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GOR2DIO_ERR_JSON_NOT_ANIM);
            }

            var builder = new GorgonAnimationBuilder();

            if ((positions != null) && (positions.Count > 0))
            {
                builder.PositionInterpolationMode(posInterp)
                .EditPositions()
                .SetKeys(positions)
                .EndEdit();
            }

            if ((scales != null) && (scales.Count > 0))
            {
                builder.ScaleInterpolationMode(scaleInterp)
                .EditScale()
                .SetKeys(scales)
                .EndEdit();
            }

            if ((rotations != null) && (rotations.Count > 0))
            {
                builder.RotationInterpolationMode(rotInterp)
                .EditRotation()
                .SetKeys(rotations)
                .EndEdit();
            }

            if ((sizes != null) && (sizes.Count > 0))
            {
                builder.SizeInterpolationMode(sizeInterp)
                .EditSize()
                .SetKeys(sizes)
                .EndEdit();
            }

            if ((colors != null) && (colors.Count > 0))
            {
                builder.ColorInterpolationMode(colorInterp)
                .EditColors()
                .SetKeys(colors)
                .EndEdit();
            }

            if ((bounds != null) && (bounds.Count > 0))
            {
                builder.RotationInterpolationMode(boundInterp)
                .EditRectangularBounds()
                .SetKeys(bounds)
                .EndEdit();
            }

            if ((textures != null) && (textures.Count > 0))
            {
                builder.Edit2DTexture()
                .SetKeys(textures)
                .EndEdit();
            }

            IGorgonAnimation result = builder.Build(animName, animLength);

            result.LoopCount = loopCount;
            result.IsLooped  = isLooped;
            result.Speed     = 1.0f;

            return(result);
        }