public static PSA FromFile(string filePath) { var psa = new PSA(); using FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); psa.Serialize(new SerializingContainer2(fs, null, true)); return(psa); }
//All Animsequences MUST have the same BoneLists! public static PSA CreateFrom(List <AnimSequence> animSeqs) { if (animSeqs == null) { throw new ArgumentNullException(nameof(animSeqs)); } if (animSeqs.Count == 0) { throw new ArgumentException("No AnimSequences!", nameof(animSeqs)); } var psa = new PSA { Bones = new List <PSABone>(), Infos = new List <PSAAnimInfo>(), Keys = new List <PSAAnimKeys>() }; int numBones = animSeqs[0].Bones.Count; for (int i = 0; i < numBones; i++) { psa.Bones.Add(new PSABone { Name = animSeqs[0].Bones[i], ParentIndex = i == 0 ? -1 : 0 }); } int frameCount = 0; foreach (AnimSequence animSeq in animSeqs) { int numFrames = animSeq.NumFrames; psa.Infos.Add(new PSAAnimInfo { Name = animSeq.Name.Instanced, Group = "None", TotalBones = numBones, KeyQuotum = numBones * numFrames, TrackTime = numFrames, AnimRate = animSeq.NumFrames / animSeq.SequenceLength * animSeq.RateScale, FirstRawFrame = frameCount, NumRawFrames = numFrames }); frameCount += numFrames; if (animSeq.RawAnimationData is null) { animSeq.DecompressAnimationData(); } for (int frameIdx = 0; frameIdx < numFrames; frameIdx++) { for (int boneIdx = 0; boneIdx < numBones; boneIdx++) { AnimTrack animTrack = animSeq.RawAnimationData[boneIdx]; Vector3 posVec = animTrack.Positions.Count > frameIdx ? animTrack.Positions[frameIdx] : animTrack.Positions[animTrack.Positions.Count - 1]; Quaternion rotQuat = animTrack.Rotations.Count > frameIdx ? animTrack.Rotations[frameIdx] : animTrack.Rotations[animTrack.Rotations.Count - 1]; rotQuat = new Quaternion(rotQuat.X, rotQuat.Y * -1, rotQuat.Z, rotQuat.W * -1); posVec = new Vector3(posVec.X, posVec.Y * -1, posVec.Z); psa.Keys.Add(new PSAAnimKeys { Position = posVec, Rotation = rotQuat, Time = 1 }); } } } return(psa); }