public void Write(Stream stream) { System.Threading.Thread.CurrentThread.CurrentCulture = _culture; teModelChunk_Skeleton skeleton = ChunkedData.GetChunk <teModelChunk_Skeleton>(); teModelChunk_Cloth cloth = ChunkedData.GetChunk <teModelChunk_Cloth>(); if (skeleton == null) { return; } short[] hierarchy; Dictionary <int, teModelChunk_Cloth.ClothNode> clothNodeMap = null; if (cloth != null) { hierarchy = cloth.CreateFakeHierarchy(skeleton, out clothNodeMap); } else { hierarchy = skeleton.Hierarchy; } using (StreamWriter writer = new StreamWriter(stream, Encoding.Default, 512)) { writer.WriteLine("{0}", skeleton.Header.BonesAbs); writer.WriteLine("version 1"); writer.WriteLine("nodes"); for (int i = 0; i < skeleton.Header.BonesAbs; ++i) { writer.WriteLine("{0} \"bone_{1:X4}\" {2}", i, skeleton.IDs[i], hierarchy[i]); } writer.WriteLine("end"); writer.WriteLine("skeleton"); writer.WriteLine("time 0"); for (int i = 0; i < skeleton.Header.BonesAbs; ++i) { OverwatchModel.GetRefPoseTransform(i, hierarchy, skeleton, clothNodeMap, out teVec3 scale, out teQuat quat, out teVec3 pos); teVec3 rot = quat.ToEulerAngles(); writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} {1:0.000000} {2:0.000000} {3:0.000000} {4:0.000000} {5:0.000000} {6:0.000000} {7:0.000000} {8:0.000000} {9:0.000000}", i, pos.X, pos.Y, pos.Z, rot.X, rot.Y, rot.Z, scale.X, scale.Y, scale.Z)); } } }
public void Write(Stream stream) { SEAnimPresence everHas = 0; foreach (teAnimation.BoneAnimation boneAnimation in Animation.BoneAnimations) { if (boneAnimation.Positions.Count > 0) { everHas |= SEAnimPresence.BoneLocation; } if (boneAnimation.Scales.Count > 0) { everHas |= SEAnimPresence.BoneScale; } if (boneAnimation.Rotations.Count > 0) { everHas |= SEAnimPresence.BoneRotation; } } int frameCount = Animation.InfoTableSize - 1; byte frameWidth; if (frameCount <= 0xFF) { frameWidth = 1; } else if (frameCount <= 0xFFFF) { frameWidth = 2; } else { frameWidth = 4; } using (BinaryWriter writer = new BinaryWriter(stream)) { writer.Write(Magic); writer.Write(Version); writer.Write(HeaderSize); writer.Write((byte)SEAnimType.Absolute); writer.Write((byte)0); writer.Write((byte)everHas); writer.Write((byte)SEAnimProperty.HighPrecision); writer.Write(new byte[] { 0, 0 }); writer.Write(Animation.Header.FPS); writer.Write(frameCount + 1); writer.Write(Animation.BoneList.Length); writer.Write((byte)0); writer.Write(new byte[] { 0, 0, 0 }); writer.Write((uint)0); foreach (int boneID in Animation.BoneList) { WriteString(writer, OverwatchModel.GetBoneName((uint)boneID)); } foreach (teAnimation.BoneAnimation boneAnimation in Animation.BoneAnimations) { writer.Write((byte)0); if (everHas.HasFlag(SEAnimPresence.BoneLocation)) { WriteFrames3D(writer, frameWidth, boneAnimation.Positions, 2.54f); } if (everHas.HasFlag(SEAnimPresence.BoneRotation)) { WriteFrames4D(writer, frameWidth, boneAnimation.Rotations); } if (everHas.HasFlag(SEAnimPresence.BoneScale)) { WriteFrames3D(writer, frameWidth, boneAnimation.Scales); } } } }