static AnimationHeader GetAnimationHeader(ByteChunk chunk) { if (chunk.BytesLeft == 0) { throw new Exception("Trying to load animation header with no data, chunk size = 0"); } var header = new AnimationHeader(); header.AnimationType = chunk.ReadUInt32(); header.Unknown0_alwaysOne = chunk.ReadUInt32(); // Always 1? header.FrameRate = chunk.ReadSingle(); var nameLength = chunk.ReadShort(); header.SkeletonName = chunk.ReadFixedLength(nameLength); header.Unknown1_alwaysZero = chunk.ReadUInt32(); // Always 0? padding? if (header.AnimationType == 7) { header.AnimationTotalPlayTimeInSec = chunk.ReadSingle(); // Play time } bool isSupportedAnimationFile = header.AnimationType == 5 || header.AnimationType == 6 || header.AnimationType == 7; if (!isSupportedAnimationFile) { throw new Exception($"Unsuported animation format: {header.AnimationType}"); } return(header); }
public static AnimationFile Create(ByteChunk chunk) { if (chunk.BytesLeft == 0) { throw new Exception("Trying to load animation with no data, chunk size = 0"); } var output = new AnimationFile(); chunk.Reset(); output.Header = GetAnimationHeader(chunk); var boneCount = chunk.ReadUInt32(); output.Bones = new BoneInfo[boneCount]; for (int i = 0; i < boneCount; i++) { var boneNameSize = chunk.ReadShort(); output.Bones[i] = new BoneInfo() { Name = chunk.ReadFixedLength(boneNameSize), ParentId = chunk.ReadInt32(), Id = i }; } // Remapping tables, not sure how they really should be used, but this works. for (int i = 0; i < boneCount; i++) { int mappingValue = chunk.ReadInt32(); output.TranslationMappings.Add(new AnimationBoneMapping(mappingValue)); } for (int i = 0; i < boneCount; i++) { int mappingValue = chunk.ReadInt32(); output.RotationMappings.Add(new AnimationBoneMapping(mappingValue)); } // A single static frame - Can be inverse, a pose or empty. Not sure? Hand animations are stored here if (output.Header.AnimationType == 7) { var staticPosCount = chunk.ReadUInt32(); var staticRotCount = chunk.ReadUInt32(); if (staticPosCount != 0 || staticRotCount != 0) { output.StaticFrame = ReadFrame(chunk, staticPosCount, staticRotCount); } } // Animation Data var animPosCount = chunk.ReadInt32(); var animRotCount = chunk.ReadInt32(); var frameCount = chunk.ReadInt32(); // Always 3 when there is no data? Why? if (animPosCount != 0 || animRotCount != 0) { for (int i = 0; i < frameCount; i++) { var frame = ReadFrame(chunk, (uint)animPosCount, (uint)animRotCount); output.DynamicFrames.Add(frame); } } // ---------------------- return(output); }