Exemplo n.º 1
0
 /// <summary>
 /// Function to save the animation data to a stream.
 /// </summary>
 /// <param name="animation">The animation to serialize into the stream.</param>
 /// <param name="stream">The stream that will contain the animation.</param>
 protected override void OnSaveToStream(IGorgonAnimation animation, Stream stream)
 {
     using (var writer = new StreamWriter(stream, Encoding.UTF8, 1024, true))
     {
         writer.Write(animation.ToJson());
     }
 }
Exemplo n.º 2
0
        /// <summary>
        /// Function to build up an animation for the torus.
        /// </summary>
        private void BuildAnimation()
        {
            var builder = new GorgonAnimationBuilder();

            IGorgonTrackKeyBuilder <GorgonKeyTexture2D> track = builder.Edit2DTexture();

            float time       = 0;
            int   frameCount = 0;

            for (int y = 0; y < _torusTexture.Height && frameCount < 60; y += 64)
            {
                for (int x = 0; x < _torusTexture.Width && frameCount < 60; x += 64, frameCount++)
                {
                    DX.RectangleF texCoords = _torusTexture.ToTexel(new DX.Rectangle(x, y, 64, 64));

                    track.SetKey(new GorgonKeyTexture2D(time, _torusTexture, texCoords, 0));

                    // 30 FPS.
                    time += 1 / 30.0f;
                }
            }

            track.EndEdit();

            _torusAnim          = builder.Build("Torus Animation");
            _torusAnim.IsLooped = true;

            _controllerLeft  = new GorgonSpriteAnimationController();
            _controllerRight = new GorgonSpriteAnimationController();

            _controllerLeft.Play(_torusLeft, _torusAnim);
            _controllerRight.Play(_torusRight, _torusAnim);
            _controllerRight.Pause();
        }
Exemplo n.º 3
0
        /// <summary>
        /// Function to update the entity during a frame.
        /// </summary>
        public void Update()
        {
            float depth = _position.Z;

            for (int meshIndex = 0; meshIndex < Layers.Count; ++meshIndex)
            {
                MeshAnimationController controller = _animController[meshIndex];
                MoveableMesh            mesh       = Layers[meshIndex].Mesh;
                IGorgonAnimation        animation  = Layers[meshIndex].Animation;

                if (animation == null)
                {
                    mesh.Rotation = Rotation;
                }

                mesh.Position = new DX.Vector3(_position.X, _position.Y, depth);
                mesh.Rotation = Rotation;

                if ((animation != null) && (controller.State != AnimationState.Playing))
                {
                    controller.Play(mesh, animation);
                }

                controller.Update();
                // Increase the depth of the mesh so that we
                depth -= 0.02f;
            }
        }
        /// <summary>
        /// Function to convert a <see cref="IGorgonAnimation"/> to a JSON string.
        /// </summary>
        /// <param name="animation">The animation to convert.</param>
        /// <param name="prettyFormat">[Optional] <b>true</b> to use pretty formatting for the string, or <b>false</b> to use a compact form.</param>
        /// <returns>The animation encoded as a JSON string.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="animation"/> parameter is <b>null</b>.</exception>
        /// <seealso cref="IGorgonAnimation"/>
        public static string ToJson(this IGorgonAnimation animation, bool prettyFormat = false)
        {
            if (animation == null)
            {
                throw new ArgumentNullException(nameof(animation));
            }

            var settings = new JsonSerializer
            {
                Formatting = prettyFormat ? Formatting.Indented : Formatting.None,
                Converters =
                {
                    new JsonTextureKeyConverter(null),
                    new JsonVector3KeyConverter(),
                    new JsonGorgonColorKeyConverter(),
                    new JsonRectKeyConverter()
                }
            };

            var    jsonObj   = JObject.FromObject(animation, settings);
            JToken firstProp = jsonObj.First;

            firstProp.AddBeforeSelf(new JProperty(JsonHeaderProp, GorgonAnimationCodecCommon.CurrentFileHeader));
            firstProp.AddBeforeSelf(new JProperty(JsonVersionProp, GorgonAnimationCodecCommon.CurrentVersion.ToString(2)));

            return(jsonObj.ToString(prettyFormat ? Formatting.Indented : Formatting.None));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Function to generate animations for the entities in the application.
        /// </summary>
        private void GenerateAnimations()
        {
            var builder = new GorgonAnimationBuilder();

            IGorgonAnimation planetRotation = builder
                                              .Clear()
                                              .EditRotation()
                                              .SetKey(new GorgonKeyVector3(0, new DX.Vector3(0, 0, 180)))
                                              .SetKey(new GorgonKeyVector3(600, new DX.Vector3(0, 360, 180)))
                                              .EndEdit()
                                              .RotationInterpolationMode(TrackInterpolationMode.Linear)
                                              .Build("PlanetRotation");

            planetRotation.IsLooped          = true;
            _animations[planetRotation.Name] = planetRotation;

            IGorgonAnimation cloudRotation = builder
                                             .Clear()
                                             .EditRotation()
                                             .SetKey(new GorgonKeyVector3(0, new DX.Vector3(0, 0, 180)))
                                             .SetKey(new GorgonKeyVector3(600, new DX.Vector3(100, 180, 180)))
                                             .SetKey(new GorgonKeyVector3(1200, new DX.Vector3(0, 360, 180)))
                                             .EndEdit()
                                             .RotationInterpolationMode(TrackInterpolationMode.Linear)
                                             .Build("CloudRotation");

            cloudRotation.IsLooped          = true;
            _animations[cloudRotation.Name] = cloudRotation;

            GorgonSprite[] frames = Sprites.Where(item => item.Key.StartsWith("Fighter_Engine_F", StringComparison.OrdinalIgnoreCase))
                                    .OrderBy(item => item.Key)
                                    .Select(item => item.Value)
                                    .ToArray();

            IGorgonAnimation engineGlow = builder
                                          .Clear()
                                          .Edit2DTexture()
                                          .SetKey(new GorgonKeyTexture2D(0, frames[0].Texture, frames[0].TextureRegion, frames[0].TextureArrayIndex))
                                          .SetKey(new GorgonKeyTexture2D(0.1f, frames[1].Texture, frames[1].TextureRegion, frames[1].TextureArrayIndex))
                                          .SetKey(new GorgonKeyTexture2D(0.2f, frames[2].Texture, frames[2].TextureRegion, frames[2].TextureArrayIndex))
                                          .SetKey(new GorgonKeyTexture2D(0.3f, frames[1].Texture, frames[1].TextureRegion, frames[1].TextureArrayIndex))
                                          .EndEdit()
                                          .RotationInterpolationMode(TrackInterpolationMode.Linear)
                                          .Build("EngineGlow");

            engineGlow.IsLooped          = true;
            _animations[engineGlow.Name] = engineGlow;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Function to save the animation data to a file on a physical file system.
        /// </summary>
        /// <param name="animation">The animation to serialize into the file.</param>
        /// <param name="filePath">The path to the file to write.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="filePath" /> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="filePath" /> parameter is empty.</exception>
        /// <exception cref="NotSupportedException">This method is not supported by this codec.</exception>
        public void Save(IGorgonAnimation animation, string filePath)
        {
            if (!CanEncode)
            {
                throw new NotSupportedException();
            }

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

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

            using (FileStream stream = File.Open(filePath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                Save(animation, stream);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Function to save the animation data to a stream.
        /// </summary>
        /// <param name="animation">The animation to serialize into the stream.</param>
        /// <param name="stream">The stream that will contain the animation.</param>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="animation"/>, or the <paramref name="stream"/> parameter is <b>null</b>.</exception>
        /// <exception cref="GorgonException">Thrown if the stream is read only.</exception>
        /// <exception cref="NotSupportedException">This method is not supported by this codec.</exception>
        public void Save(IGorgonAnimation animation, Stream stream)
        {
            if (!CanEncode)
            {
                throw new NotSupportedException();
            }

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

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

            if (!stream.CanWrite)
            {
                throw new GorgonException(GorgonResult.CannotWrite, Resources.GOR2DIO_ERR_STREAM_IS_READ_ONLY);
            }

            OnSaveToStream(animation, stream);
        }
        /// <summary>
        /// Function to load a <see cref="IGorgonAnimation"/> from a <see cref="GorgonFileSystem"/>.
        /// </summary>
        /// <param name="fileSystem">The file system to load the animation from.</param>
        /// <param name="renderer">The renderer for the animation.</param>
        /// <param name="path">The path to the animation file in the file system.</param>
        /// <param name="textureOptions">[Optional] Options for the texture loaded associated the sprite.</param>
        /// <param name="animationCodecs">The list of animation codecs to try and load the animation with.</param>
        /// <param name="imageCodecs">The list of image codecs to try and load the animation texture(s) with.</param>
        /// <returns>The animation data in the file as a <see cref="IGorgonAnimation"/>.</returns>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="fileSystem"/>, <paramref name="renderer"/>, or <paramref name="path"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="path"/> parameter is empty.</exception>
        /// <exception cref="FileNotFoundException">Thrown if the file in the <paramref name="path"/> was not found.</exception>
        /// <exception cref="GorgonException">Thrown if the animation data in the file system could not be loaded because a suitable codec was not found.</exception>
        /// <remarks>
        /// <para>
        /// This method extends a <see cref="GorgonFileSystem"/> so that animations can be loaded by calling a method on the file system object itself. This negates the need for users to create complex code
        /// for loading an animation.
        /// </para>
        /// <para>
        /// When loading an animation, the method will attempt to locate any <see cref="GorgonTexture2DView"/> objects associated with the animation (if they exist). When loading, it will check:
        /// <list type="number">
        ///     <item>
        ///         <description>For a texture resource with the same name that is already loaded into memory.</description>
        ///     </item>
        ///     <item>
        ///         <description>Use the local <see cref="IGorgonVirtualDirectory"/> for the sprite file and search for the texture in that directory.</description>
        ///     </item>
        ///     <item>
        ///         <description>Check the entire <paramref name="fileSystem"/> for a file if the texture name contains path information (this is done by the GorgonEditor from v2).</description>
        ///     </item>
        /// </list>
        /// If the file is found, and can be loaded by one of the <paramref name="imageCodecs"/>, then it is loaded and assigned to the sprite.
        /// </para>
        /// <para>
        /// The <paramref name="animationCodecs"/> is a list of codecs for loading sprite data. If the user specifies this parameter, the only the codecs provided will be used for determining if an
        /// animation can be read. If it is not supplied, then all built-in (i.e. not plug in based) sprite codecs will be used.
        /// </para>
        /// <para>
        /// The <paramref name="imageCodecs"/> is a list of codecs for loading image data. If the user specifies this parameter, the only the codecs provided will be used for determining if an image can be
        /// read. If it is not supplied, then all built-in (i.e. not plug in based) image codecs will be used.
        /// </para>
        /// </remarks>
        /// <seealso cref="GorgonFileSystem"/>
        /// <seealso cref="GorgonTexture2DView"/>
        /// <seealso cref="IGorgonAnimation"/>
        public static IGorgonAnimation LoadAnimationFromFileSystem(this GorgonFileSystem fileSystem,
                                                                   Gorgon2D renderer,
                                                                   string path,
                                                                   GorgonTexture2DLoadOptions textureOptions           = null,
                                                                   IEnumerable <IGorgonAnimationCodec> animationCodecs = null,
                                                                   IEnumerable <IGorgonImageCodec> imageCodecs         = null)
        {
            if (fileSystem == null)
            {
                throw new ArgumentNullException(nameof(fileSystem));
            }

            IGorgonVirtualFile file = fileSystem.GetFile(path);

            if (file == null)
            {
                throw new FileNotFoundException(string.Format(Resources.GOR2DIO_ERR_FILE_NOT_FOUND, path));
            }

            if ((imageCodecs == null) || (!imageCodecs.Any()))
            {
                // If we don't specify any codecs, then use the built in ones.
                imageCodecs = new IGorgonImageCodec[]
                {
                    new GorgonCodecPng(),
                    new GorgonCodecBmp(),
                    new GorgonCodecDds(),
                    new GorgonCodecGif(),
                    new GorgonCodecJpeg(),
                    new GorgonCodecTga(),
                };
            }
            else
            {
                // Only use codecs that can decode image data.
                imageCodecs = imageCodecs.Where(item => item.CanDecode);
            }

            if ((animationCodecs == null) || (!animationCodecs.Any()))
            {
                // Use all built-in codecs if we haven't asked for any.
                animationCodecs = new IGorgonAnimationCodec[]
                {
                    new GorgonV3AnimationBinaryCodec(renderer),
                    new GorgonV3AnimationJsonCodec(renderer),
                    new GorgonV1AnimationCodec(renderer)
                };
            }
            else
            {
                // Only use codecs that can decode sprite data.
                animationCodecs = animationCodecs.Where(item => item.CanDecode);
            }

            Stream animStream = file.OpenStream();

            try
            {
                if (!animStream.CanSeek)
                {
                    Stream newStream = new DataStream((int)animStream.Length, true, true);
                    animStream.CopyTo(newStream);
                    newStream.Position = 0;

                    animStream.Dispose();
                    animStream = newStream;
                }

                IGorgonAnimationCodec animationCodec = GetAnimationCodec(animStream, animationCodecs);

                if (animationCodec == null)
                {
                    throw new GorgonException(GorgonResult.CannotRead, string.Format(Resources.GOR2DIO_ERR_NO_SUITABLE_ANIM_CODEC_FOUND, path));
                }

                // Load the animation.
                IGorgonAnimation animation = animationCodec.FromStream(animStream, (int)file.Size);

                // We have no textures to update, leave.
                if (animation.Texture2DTrack.KeyFrames.Count == 0)
                {
                    return(animation);
                }

                // Try to locate the textures.

                // V1 sprite animations need texture coordinate correction.
                bool needsCoordinateFix = animationCodec is GorgonV1AnimationCodec;

                foreach (GorgonKeyTexture2D textureKey in animation.Texture2DTrack.KeyFrames)
                {
                    // Let's try and load the texture into memory.
                    // This does this by:
                    // 1. Checking to see if a texture resource with the name specified is already available in memory.
                    // 2. Checking the local directory of the file to see if the texture is there.
                    // 3. A file system wide search.

                    // ReSharper disable once InvertIf
                    (IGorgonImageCodec codec, IGorgonVirtualFile textureFile, bool loaded) =
                        LocateTextureCodecAndFile(fileSystem, file.Directory, renderer, textureKey.TextureName, imageCodecs);

                    // We have not loaded the texture yet.  Do so now.
                    // ReSharper disable once InvertIf
                    if ((!loaded) && (textureFile != null) && (codec != null))
                    {
                        using (Stream textureStream = textureFile.OpenStream())
                        {
                            textureKey.Value = GorgonTexture2DView.FromStream(renderer.Graphics,
                                                                              textureStream,
                                                                              codec,
                                                                              textureFile.Size, GetTextureOptions(textureFile.FullPath, textureOptions));
                        }
                    }

                    if ((needsCoordinateFix) && (textureKey.Value != null))
                    {
                        textureKey.TextureCoordinates = new RectangleF(textureKey.TextureCoordinates.X / textureKey.Value.Width,
                                                                       textureKey.TextureCoordinates.Y / textureKey.Value.Height,
                                                                       textureKey.TextureCoordinates.Width / textureKey.Value.Width,
                                                                       textureKey.TextureCoordinates.Height / textureKey.Value.Height);
                    }
                }

                return(animation);
            }
            finally
            {
                animStream?.Dispose();
            }
        }
        /// <summary>
        /// Function to save the animation data to a stream.
        /// </summary>
        /// <param name="animation">The animation to serialize into the stream.</param>
        /// <param name="stream">The stream that will contain the animation.</param>
        protected override void OnSaveToStream(IGorgonAnimation animation, Stream stream)
        {
            var writer = new GorgonChunkFileWriter(stream, CurrentFileHeader);
            GorgonBinaryWriter binWriter = null;

            try
            {
                writer.Open();
                binWriter = writer.OpenChunk(VersionData);
                binWriter.Write((byte)Version.Major);
                binWriter.Write((byte)Version.Minor);
                writer.CloseChunk();

                binWriter = writer.OpenChunk(AnimationData);
                binWriter.Write(animation.Name);
                binWriter.Write(animation.Length);
                binWriter.Write(animation.IsLooped);
                binWriter.Write(animation.LoopCount);
                writer.CloseChunk();

                // Write out position track.
                if (animation.PositionTrack.KeyFrames.Count > 0)
                {
                    binWriter = writer.OpenChunk(PositionData);
                    binWriter.WriteValue(animation.PositionTrack.InterpolationMode);
                    binWriter.Write(animation.PositionTrack.KeyFrames.Count);

                    for (int i = 0; i < animation.PositionTrack.KeyFrames.Count; ++i)
                    {
                        GorgonKeyVector3 key = animation.PositionTrack.KeyFrames[i];
                        binWriter.Write(key.Time);
                        binWriter.WriteValue(ref key.Value);
                    }

                    writer.CloseChunk();
                }

                // Write out position track.
                if (animation.ScaleTrack.KeyFrames.Count > 0)
                {
                    binWriter = writer.OpenChunk(ScaleData);
                    binWriter.WriteValue(animation.ScaleTrack.InterpolationMode);
                    binWriter.Write(animation.ScaleTrack.KeyFrames.Count);

                    for (int i = 0; i < animation.ScaleTrack.KeyFrames.Count; ++i)
                    {
                        GorgonKeyVector3 key = animation.ScaleTrack.KeyFrames[i];
                        binWriter.Write(key.Time);
                        binWriter.WriteValue(ref key.Value);
                    }

                    writer.CloseChunk();
                }

                // Write out rotation track.
                if (animation.RotationTrack.KeyFrames.Count > 0)
                {
                    binWriter = writer.OpenChunk(RotationData);
                    binWriter.WriteValue(animation.RotationTrack.InterpolationMode);
                    binWriter.Write(animation.RotationTrack.KeyFrames.Count);

                    for (int i = 0; i < animation.RotationTrack.KeyFrames.Count; ++i)
                    {
                        GorgonKeyVector3 key = animation.RotationTrack.KeyFrames[i];
                        binWriter.Write(key.Time);
                        binWriter.WriteValue(ref key.Value);
                    }

                    writer.CloseChunk();
                }

                // Write out size track.
                if (animation.SizeTrack.KeyFrames.Count > 0)
                {
                    binWriter = writer.OpenChunk(SizeData);
                    binWriter.WriteValue(animation.SizeTrack.InterpolationMode);
                    binWriter.Write(animation.SizeTrack.KeyFrames.Count);

                    for (int i = 0; i < animation.SizeTrack.KeyFrames.Count; ++i)
                    {
                        GorgonKeyVector3 key = animation.SizeTrack.KeyFrames[i];
                        binWriter.Write(key.Time);
                        binWriter.WriteValue(ref key.Value);
                    }

                    writer.CloseChunk();
                }

                // Write out bounds track.
                if (animation.RectBoundsTrack.KeyFrames.Count > 0)
                {
                    binWriter = writer.OpenChunk(BoundsData);
                    binWriter.WriteValue(animation.RectBoundsTrack.InterpolationMode);
                    binWriter.Write(animation.RectBoundsTrack.KeyFrames.Count);

                    for (int i = 0; i < animation.RectBoundsTrack.KeyFrames.Count; ++i)
                    {
                        GorgonKeyRectangle key = animation.RectBoundsTrack.KeyFrames[i];
                        binWriter.Write(key.Time);
                        binWriter.WriteValue(ref key.Value);
                    }

                    writer.CloseChunk();
                }

                // Write out colors track.
                if (animation.ColorTrack.KeyFrames.Count > 0)
                {
                    binWriter = writer.OpenChunk(ColorData);
                    binWriter.WriteValue(animation.ColorTrack.InterpolationMode);
                    binWriter.Write(animation.ColorTrack.KeyFrames.Count);

                    for (int i = 0; i < animation.ColorTrack.KeyFrames.Count; ++i)
                    {
                        GorgonKeyGorgonColor key = animation.ColorTrack.KeyFrames[i];
                        binWriter.Write(key.Time);
                        binWriter.WriteValue(ref key.Value);
                    }

                    writer.CloseChunk();
                }

                if (animation.Texture2DTrack.KeyFrames.Count == 0)
                {
                    return;
                }

                binWriter = writer.OpenChunk(TextureData);
                binWriter.Write(animation.Texture2DTrack.KeyFrames.Count);

                for (int i = 0; i < animation.Texture2DTrack.KeyFrames.Count; ++i)
                {
                    GorgonKeyTexture2D key = animation.Texture2DTrack.KeyFrames[i];

                    binWriter.Write(key.Time);

                    if (key.Value == null)
                    {
                        binWriter.WriteValue <byte>(0);
                    }
                    else
                    {
                        binWriter.WriteValue <byte>(1);
                        binWriter.Write(key.Value.Texture.Name);
                        binWriter.Write(key.Value.Texture.Width);
                        binWriter.Write(key.Value.Texture.Height);
                        binWriter.WriteValue(key.Value.Texture.Format);
                        binWriter.Write(key.Value.Texture.ArrayCount);
                        binWriter.Write(key.Value.Texture.MipLevels);
                        binWriter.Write(key.Value.ArrayIndex);
                        binWriter.Write(key.Value.ArrayCount);
                        binWriter.Write(key.Value.MipSlice);
                        binWriter.Write(key.Value.MipCount);
                        binWriter.WriteValue(key.Value.Format);
                    }

                    binWriter.WriteValue(ref key.TextureCoordinates);
                    binWriter.Write(key.TextureArrayIndex);
                }

                writer.CloseChunk();
            }
            finally
            {
                binWriter?.Dispose();
                writer.Close();
            }
        }
Exemplo n.º 10
0
        // ReSharper disable once InconsistentNaming
        /// <summary>
        /// Function to build our animation... like an 80's music video... this is going to be ugly.
        /// </summary>
        private static void MakeAn80sMusicVideo()
        {
            var animBuilder = new GorgonAnimationBuilder();

            animBuilder.PositionInterpolationMode(TrackInterpolationMode.Spline)
            .ScaleInterpolationMode(TrackInterpolationMode.Spline)
            .RotationInterpolationMode(TrackInterpolationMode.Spline)
            .ColorInterpolationMode(TrackInterpolationMode.Spline)
            // Set up some scaling...
            .EditScale()
            .SetKey(new GorgonKeyVector3(0, new DX.Vector2(1, 1)))
            .SetKey(new GorgonKeyVector3(2, new DX.Vector2(0.5f, 0.5f)))
            .SetKey(new GorgonKeyVector3(4, new DX.Vector2(4.0f, 4.0f)))
            .SetKey(new GorgonKeyVector3(6, new DX.Vector2(1, 1)))
            .EndEdit()
            // Set up some positions...
            .EditPositions()
            .SetKey(new GorgonKeyVector3(0, new DX.Vector2(_screen.Width / 2.0f, _screen.Height / 2.0f)))
            .SetKey(new GorgonKeyVector3(2, new DX.Vector2(200, 220)))
            .SetKey(new GorgonKeyVector3(3, new DX.Vector2(_screen.Width - 2, 130)))
            .SetKey(new GorgonKeyVector3(4, new DX.Vector2(255, _screen.Height - _metal.Height)))
            .SetKey(new GorgonKeyVector3(5, new DX.Vector2(200, 180)))
            .SetKey(new GorgonKeyVector3(6, new DX.Vector2(180, 160)))
            .SetKey(new GorgonKeyVector3(7, new DX.Vector2(150, 180)))
            .SetKey(new GorgonKeyVector3(8, new DX.Vector2(150, 160)))
            .SetKey(new GorgonKeyVector3(9, new DX.Vector2(_screen.Width / 2, _screen.Height / 2)))
            .EndEdit()
            // Set up some colors...By changing the alpha, we can simulate a motion blur effect.
            .EditColors()
            .SetKey(new GorgonKeyGorgonColor(0, GorgonColor.Black))
            .SetKey(new GorgonKeyGorgonColor(2, new GorgonColor(GorgonColor.RedPure, 0.25f)))
            .SetKey(new GorgonKeyGorgonColor(4, new GorgonColor(GorgonColor.GreenPure, 0.5f)))
            .SetKey(new GorgonKeyGorgonColor(6, new GorgonColor(GorgonColor.BluePure, 0.25f)))
            .SetKey(new GorgonKeyGorgonColor(8, new GorgonColor(GorgonColor.LightCyan, 0.25f)))
            .SetKey(new GorgonKeyGorgonColor(10, new GorgonColor(GorgonColor.Black, 1.0f)))
            .EndEdit()
            // And finally, some MuchMusic/MTV style rotation... because.
            .EditRotation()
            .SetKey(new GorgonKeyVector3(0, new DX.Vector3(0, 0, 0)))
            .SetKey(new GorgonKeyVector3(2, new DX.Vector3(0, 0, 180)))
            .SetKey(new GorgonKeyVector3(4, new DX.Vector3(0, 0, 270.0f)))
            .SetKey(new GorgonKeyVector3(6, new DX.Vector3(0, 0, 0)))
            .EndEdit();

            IGorgonTrackKeyBuilder <GorgonKeyTexture2D> trackBuilder = animBuilder.Edit2DTexture();
            float time = 0;

            // Now, add the animation frames from our GIF.
            for (int i = 0; i < _metal.ArrayCount; ++i)
            {
                trackBuilder.SetKey(new GorgonKeyTexture2D(time, _metal, new DX.RectangleF(0, 0, 1, 1), i));
                time += _frameDelays[i];
            }

            float delay = (10.0f - time).Max(0) / 15.0f;

            // Now add in a texture switch with coordinate update... because.
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.25f, 0.25f, 0.5f, 0.5f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.125f, 0.125f, 0.75f, 0.75f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0, 0, 1, 1), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.125f, 0.125f, 0.75f, 0.75f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.25f, 0.25f, 0.5f, 0.5f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.125f, 0.125f, 0.75f, 0.75f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0, 0, 1, 1), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.125f, 0.125f, 0.75f, 0.75f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.25f, 0.25f, 0.5f, 0.5f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.125f, 0.125f, 0.75f, 0.75f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0, 0, 1, 1), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.125f, 0.125f, 0.75f, 0.75f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.25f, 0.25f, 0.5f, 0.5f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0.125f, 0.125f, 0.75f, 0.75f), 0));
            time += delay;
            trackBuilder.SetKey(new GorgonKeyTexture2D(time, _trooper, new DX.RectangleF(0, 0, 1, 1), 0));

            trackBuilder.EndEdit();

            _animation          = animBuilder.Build(@"\m/");
            _animation.IsLooped = true;

            _animController = new GorgonSpriteAnimationController();
        }
Exemplo n.º 11
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);
        }
 /// <summary>
 /// Function to save the animation data to a stream.
 /// </summary>
 /// <param name="animation">The animation to serialize into the stream.</param>
 /// <param name="stream">The stream that will contain the animation.</param>
 protected override void OnSaveToStream(IGorgonAnimation animation, Stream stream) => throw new NotSupportedException();
Exemplo n.º 13
0
 /// <summary>
 /// Function to save the animation data to a stream.
 /// </summary>
 /// <param name="animation">The animation to serialize into the stream.</param>
 /// <param name="stream">The stream that will contain the animation.</param>
 protected abstract void OnSaveToStream(IGorgonAnimation animation, Stream stream);