/ContentSystem/Rendering/MeshAnimationData.cs
C# | 206 lines | 109 code | 16 blank | 81 comment | 11 complexity | e803a852f432ba8acda0b7440a919f28 MD5 | raw file
Possible License(s): Apache-2.0
- using System;
- using System.IO;
- using Delta.Utilities;
- using Delta.Utilities.Datatypes;
- using Delta.Utilities.Helpers;
-
- namespace Delta.ContentSystem.Rendering
- {
- /// <summary>
- /// Mesh Animation data class, which keeps all the data (matrices) for one
- /// mesh animation. This can be something like a simple Idle animation or
- /// some really complex cinematic animation for a character with bones.
- /// See BoneData for the bone details. Mesh and MeshAnimations must fit.
- /// </summary>
- public class MeshAnimationData : Content, ISaveLoadBinary
- {
- #region Constants
- /// <summary>
- /// Version number for this MeshData. If this goes above 1, we need
- /// to support loading older versions as well. Saving is always going
- /// to be the latest version (this one).
- /// </summary>
- private const int CurrentVersion = 1;
- #endregion
-
- #region Get (Static)
- /// <summary>
- /// Get and load content based on the content name. This method makes sure
- /// we do not load the same content twice (the constructor is protected).
- /// </summary>
- /// <param name="contentName">Content name we want to load, this is
- /// passed onto the Content System, which will do the actual loading with
- /// help of the Load method in this class.</param>
- /// <returns>The loaded Content object, always unique for the same
- /// name, this helps comparing data.</returns>
- public static MeshAnimationData Get(string contentName)
- {
- return Get<MeshAnimationData>(contentName,
- ContentType.MeshAnimation);
- }
- #endregion
-
- #region Frames (Public)
- /// <summary>
- /// Array of animation frames (as array of bone matrices), e.g.
- /// <para />
- /// Frames[0] -> Frame 1
- /// Frames[0][0] -> Bone Matrix 1
- /// Frames[0][1] -> Bone Matrix 2
- /// Frames[1] -> Frame 2
- /// Frames[1][0] -> Bone Matrix 1
- /// Frames[1][1] -> Bone Matrix 2
- /// </summary>
- public Matrix[][] Frames
- {
- get;
- private set;
- }
- #endregion
-
- #region Constructors
- /// <summary>
- /// Create mesh animation data with a given set of matrices for the bones.
- /// </summary>
- /// <param name="setAnimationFrames">Set animation frames</param>
- public MeshAnimationData(Matrix[][] setAnimationFrames)
- : base(EmptyName, ContentType.MeshAnimation)
- {
- Frames = setAnimationFrames;
- }
-
- /// <summary>
- /// Create mesh animation data by loading it from content, use the static
- /// Get method to call this.
- /// </summary>
- /// <param name="contentName">Name of the content.</param>
- protected MeshAnimationData(string contentName)
- : base(contentName, ContentType.MeshAnimation)
- {
- }
- #endregion
-
- #region ISaveLoadBinary Members
- /// <summary>
- /// Load animation data, which is mostly animation matrices.
- /// </summary>
- /// <param name="reader">Reader</param>
- public void Load(BinaryReader reader)
- {
- // We currently only support our version, if more versions are added,
- // we need to do different loading code depending on the version here.
- int version = reader.ReadInt32();
- if (version != CurrentVersion)
- {
- Log.InvalidVersionWarning(GetType().Name, version, CurrentVersion);
- return;
- }
-
- // Load the frames now
- // At first we need the number of frames we will get
- int frameCount = reader.ReadInt32();
- // and at second the number of bone transformations we will get for every
- // single frame
- // Note:
- // 1. The value is only be saved if we have any frames
- // 2. We only get one number for all bones, because for every frame the
- // number of bones is the same
- int boneCountPerFrame = (frameCount > 0)
- ? reader.ReadInt32()
- : 0;
-
- // Finally just reconstruct the frames now
- Frames = new Matrix[frameCount][];
- for (int frameId = 0; frameId < frameCount; frameId++)
- {
- Frames[frameId] = new Matrix[boneCountPerFrame];
- for (int boneIndex = 0; boneIndex < boneCountPerFrame; boneIndex++)
- {
- Frames[frameId][boneIndex].Load(reader);
- }
- }
- }
-
- /// <summary>
- /// Save animation data, which is mostly animation matrices.
- /// </summary>
- /// <param name="dataWriter">Data writer</param>
- public void Save(BinaryWriter dataWriter)
- {
- dataWriter.Write(CurrentVersion);
-
- // Save out the frames
- // at first the number of frames in total
- dataWriter.Write(Frames.Length);
- // and then the number of bones / bone transformations (only if needed)
- // Note:
- // We can do this only once, because here we have always the same amount
- // of bones for ALL frames, else we have to save the number of bones for
- // every single frame
- int boneCountPerFrame = (Frames.Length > 0)
- ? Frames[0].Length
- : 0;
- if (boneCountPerFrame > 0)
- {
- dataWriter.Write(boneCountPerFrame);
- }
-
- // Finally iterate through every frame
- for (int frameId = 0; frameId < Frames.Length; frameId++)
- {
- // and every bone transformation which is in the current frame
- for (int boneIndex = 0; boneIndex < boneCountPerFrame; boneIndex++)
- {
- // and save it out
- Frames[frameId][boneIndex].Save(dataWriter);
- }
- }
- }
- #endregion
-
- #region Methods (Private)
-
- #region Load
- /// <summary>
- /// Native load method, will just load the data.
- /// </summary>
- /// <param name="alreadyLoadedNativeData">
- /// The first instance that has already loaded the required content data
- /// of this content class or just 'null' if there is none loaded yet (or
- /// anymore).
- /// </param>
- protected override void Load(Content alreadyLoadedNativeData)
- {
- try
- {
- if (alreadyLoadedNativeData != null)
- {
- // Just clone all data
- MeshAnimationData otherData =
- alreadyLoadedNativeData as MeshAnimationData;
- Frames = otherData.Frames;
- // This object cannot be used for cloning now, but the caller (Mesh)
- // can set itself as the NativeClassObject and allow native cloning.
- return;
- }
-
- if (String.IsNullOrEmpty(RelativeFilePath) == false)
- {
- // Load via the ISaveLoadBinary interface methods below.
- // Cloning should not really happen for shaders anyway.
- FileHelper.Load(RelativeFilePath, this);
- }
- }
- catch (Exception ex)
- {
- Log.Warning("Failed to load mesh animation data from file '" +
- RelativeFilePath + "': " + ex);
- FailedToLoad = true;
- }
- }
- #endregion
-
- #endregion
- }
- }
-