/// <summary> /// Reads animation information from the file. /// </summary> protected void ReadAnimation(BinaryMemoryReader reader) { // name of the animation string name = ReadString(reader); // length in seconds of the animation float length = ReadFloat(reader); // create an animation from the skeleton Animation anim = skeleton.CreateAnimation(name, length); // keep reading all keyframes for this track if (!IsEOF(reader)) { SkeletonChunkID chunkID = ReadChunk(reader); while (!IsEOF(reader) && (chunkID == SkeletonChunkID.AnimationTrack)) { // read the animation track ReadAnimationTrack(reader, anim); // read the next chunk id // If we're not end of file get the next chunk ID if (!IsEOF(reader)) { chunkID = ReadChunk(reader); } } // backpedal to the start of the chunk if (!IsEOF(reader)) { Seek(reader, -ChunkOverheadSize); } } }
/// <summary> /// Reads an animation track. /// </summary> protected void ReadAnimationTrack(BinaryMemoryReader reader, Animation anim) { // read the bone handle to apply this track to ushort boneHandle = ReadUShort(reader); // get a reference to the target bone Bone targetBone = skeleton.GetBone(boneHandle); // create an animation track for this bone NodeAnimationTrack track = anim.CreateNodeTrack(boneHandle, targetBone); // keep reading all keyframes for this track if (!IsEOF(reader)) { SkeletonChunkID chunkID = ReadChunk(reader); while (!IsEOF(reader) && (chunkID == SkeletonChunkID.KeyFrame)) { // read the key frame ReadKeyFrame(reader, track); // read the next chunk id // If we're not end of file get the next chunk ID if (!IsEOF(reader)) { chunkID = ReadChunk(reader); } } // backpedal to the start of the chunk if (!IsEOF(reader)) { Seek(reader, -ChunkOverheadSize); } } }
public void ImportSkeleton(Stream stream, Skeleton skeleton) { // store a local reference to the mesh for modification this.skeleton = skeleton; var reader = new BinaryReader(stream, System.Text.Encoding.UTF8); // start off by taking a look at the header ReadFileHeader(reader); SkeletonChunkID chunkID = 0; while (!IsEOF(reader)) { chunkID = ReadChunk(reader); switch (chunkID) { case SkeletonChunkID.Bone: ReadBone(reader); break; case SkeletonChunkID.BoneParent: ReadBoneParent(reader); break; case SkeletonChunkID.Animation: ReadAnimation(reader); break; case SkeletonChunkID.AttachmentPoint: ReadAttachmentPoint(reader); break; default: LogManager.Instance.Write( "Can only parse bones, parents, and animations at the top level during skeleton loading."); LogManager.Instance.Write("Unexpected chunk: " + chunkID.ToString()); break; } // switch } // while // assume bones are stored in binding pose skeleton.SetBindingPose(); }
/// <summary> /// Writes a chunk ID and chunk size. This would be more accurately named /// WriteChunkHeader, but this name is the counter of ReadChunk. /// </summary> protected void WriteChunk(BinaryWriter writer, SkeletonChunkID id, int chunkLength) { writer.Write((short)id); writer.Write(chunkLength); }