private static void ReadAnimationSource(BinaryReader br, ModelData data, DataStructures.Models.Model model, int[] groupsize) { if (groupsize.Length == 0) return; var animIndices = br.ReadShortArray(groupsize[0] * groupsize[1]); // Just use the first animation for now var srcAnim = data.SourceAnimations.FirstOrDefault(x => x.AnimID == animIndices[0]); if (srcAnim == null) return; var numframes = srcAnim.NumFrames; var anim = new Animation(); // Add all the empty frames for (var i = 0; i < numframes; i++) anim.Frames.Add(new AnimationFrame()); foreach (var bone in model.Bones) { var animBone = srcAnim.AnimationBones.FirstOrDefault(x => x.Bone == bone.BoneIndex); for (var f = 0; f < numframes; f++) { var fpos = CoordinateF.Zero; var fang = CoordinateF.Zero; if (animBone != null) { if (animBone.FixedPosition != null) fpos = animBone.FixedPosition; else if (animBone.FramePositions.Count > f) fpos = animBone.FramePositions[f]; if (animBone.FixedQuaternion == null) fang = animBone.FrameAngles[f]; } fpos = fpos.ComponentMultiply(bone.DefaultPositionScale);// +bone.DefaultPosition; var fangq = animBone != null && animBone.FixedQuaternion != null ? animBone.FixedQuaternion : QuaternionF.EulerAngles(fang.ComponentMultiply(bone.DefaultAnglesScale));// + bone.DefaultAngles); anim.Frames[f].Bones.Add(new BoneAnimationFrame(bone, fpos, fangq)); } } model.Animations.Add(anim); }
private static void ReadAnimationGoldsource(BinaryReader br, DataStructures.Models.Model model, int numframes) { var anim = new Animation(); // Add all the empty frames for (var i = 0; i < numframes; i++) anim.Frames.Add(new AnimationFrame()); // Now we have a reader with the position at the start of the animation data // First up is the list of offset indexes for the data, one for each bone in the model. // Bones are already loaded up, so loop through those. foreach (var bone in model.Bones) { var offsetPos = br.BaseStream.Position; var offsets = br.ReadShortArray(6); var restorePoint = br.BaseStream.Position; var position = bone.DefaultPosition; var angles = bone.DefaultAngles; var boneFrames = new List<float[]>(); for (var i = 0; i < numframes; i++) boneFrames.Add(new float[] {0, 0, 0, 0, 0, 0}); for (var i = 0; i < 6; i++) // For each offset [X, Y, Z, XR, YR, ZR] { if (offsets[i] <= 0) continue; br.BaseStream.Position = offsetPos + offsets[i]; var values = ReadRLEEncodedAnimationFrameValues(br, numframes); for (var f = 0; f < numframes; f++) { boneFrames[f][i] += values[f]; } } for (var f = 0; f < numframes; f++) { var frame = boneFrames[f]; var fpos = new CoordinateF(frame[0], frame[1], frame[2]).ComponentMultiply(bone.DefaultPositionScale) + bone.DefaultPosition; var fang = new CoordinateF(frame[3], frame[4], frame[5]).ComponentMultiply(bone.DefaultAnglesScale) + bone.DefaultAngles; anim.Frames[f].Bones.Add(new BoneAnimationFrame(bone, fpos, QuaternionF.EulerAngles(fang))); } br.BaseStream.Position = restorePoint; } model.Animations.Add(anim); }