SanAndreasUnity/Assets/Scripts/Importing/Animation/Section.cs

130 lines
3.3 KiB
C#
Raw Normal View History

2020-05-31 17:07:22 +00:00
using SanAndreasUnity.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace SanAndreasUnity.Importing.Animation
{
public abstract class Section
{
public readonly string Identifier;
public readonly long Length;
protected Section(BinaryReader reader)
{
Identifier = reader.ReadString(4);
Length = reader.ReadUInt32();
}
}
public class Clip
{
public readonly string Name;
public readonly Int32 BoneCount;
public readonly Int32 FrameLength;
public readonly Int32 Unknown;
public readonly Bone[] Bones;
public readonly int EndTime;
public Clip(BinaryReader reader)
{
Name = reader.ReadString(24);
BoneCount = reader.ReadInt32();
FrameLength = reader.ReadInt32();
Unknown = reader.ReadInt32();
Bones = new Bone[BoneCount];
for (int i = 0; i < BoneCount; ++i)
{
Bones[i] = new Bone(reader);
}
if (BoneCount > 0)
{
EndTime = Bones.Max(x => x.EndTime);
}
}
}
public class Bone
{
public readonly string Name;
public readonly Int32 FrameType;
public readonly Int32 FrameCount;
public readonly Int32 BoneId;
public readonly Frame[] Frames;
public readonly int EndTime;
public Bone(BinaryReader reader)
{
Name = reader.ReadString(24);
FrameType = reader.ReadInt32();
FrameCount = reader.ReadInt32();
BoneId = reader.ReadInt32();
Frames = new Frame[FrameCount];
for (int i = 0; i < FrameCount; ++i)
{
Frames[i] = new Frame(reader, FrameType == 4);
}
if (FrameCount > 0)
{
EndTime = Frames[FrameCount - 1].Time;
}
}
}
public class Frame
{
public readonly Vector3 Translation;
public readonly Quaternion Rotation;
public readonly Int16 Time;
public Frame(BinaryReader reader, bool root)
{
Rotation = new Quaternion(reader, QuaternionCompression.Animation);
Time = reader.ReadInt16();
if (root)
{
Translation = new Vector3(reader, VectorCompression.Animation);
}
}
}
public class AnimationPackage : Section
{
private readonly Dictionary<string, Clip> _namedClips
= new Dictionary<string, Clip>(StringComparer.InvariantCultureIgnoreCase);
public readonly string FileName;
public readonly Int32 ClipCount;
public readonly Clip[] Clips;
public AnimationPackage(BinaryReader reader)
: base(reader)
{
FileName = reader.ReadString(24);
ClipCount = reader.ReadInt32();
Clips = new Clip[ClipCount];
for (int i = 0; i < ClipCount; ++i)
{
var clip = Clips[i] = new Clip(reader);
_namedClips.Add(clip.Name, clip);
}
}
public Clip this[string name]
{
get { return _namedClips[name]; }
}
}
}