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); } } } }
public bool Write(Animation anim, Stream output, object[] data) { Dictionary <int, Dictionary <AnimChannelID, SortedList <int, object> > > framesByBone = new Dictionary <int, Dictionary <AnimChannelID, SortedList <int, object> > >(); SortedSet <int> boneIds = new SortedSet <int>(); SEAnimPresence everHas = 0; int frameCount = 0; foreach (Keyframe keyframe in anim.Animations) { int pos = keyframe.FramePositionI; if (pos > frameCount) { frameCount = pos; } foreach (BoneAnimation bone in keyframe.BoneFrames) { foreach (FrameValue value in bone.Values) { everHas |= (SEAnimPresence)value.Channel; if (!framesByBone.ContainsKey(bone.BoneID)) { boneIds.Add(bone.BoneID); framesByBone[bone.BoneID] = new Dictionary <AnimChannelID, SortedList <int, object> >(); } if (!framesByBone[bone.BoneID].ContainsKey(value.Channel)) { framesByBone[bone.BoneID][value.Channel] = new SortedList <int, object>(); } framesByBone[bone.BoneID][value.Channel].Add(pos, value.Value); } } } if (everHas == 0) { return(false); } byte frameWidth; if (frameCount <= 0xFF) { frameWidth = 1; } else if (frameCount <= 0xFFFF) { frameWidth = 2; } else { frameWidth = 4; } /* * byte boneWidth; * if(boneIds.Count <= 0xFF) { * boneWidth = 1; * } else if(boneIds.Count <= 0xFFFF) { * boneWidth = 2; * } else { * boneWidth = 4; * } */ using (BinaryWriter writer = new BinaryWriter(output, Encoding.Default, false)) { writer.Write(MAGIC); writer.Write(VERSION); writer.Write(HEADER_SZ); writer.Write((byte)SEAnimType.ABSOLUTE); writer.Write((byte)0); writer.Write((byte)everHas); writer.Write((byte)SEAnimProperty.HighPrecision); writer.Write(new byte[2] { 0, 0 }); writer.Write(anim.FramesPerSecond); writer.Write(frameCount + 1); writer.Write(boneIds.Count); writer.Write((byte)0); writer.Write(new byte[3] { 0, 0, 0 }); writer.Write((uint)0); foreach (int boneId in boneIds) { WriteCString(writer, OWMDLWriter.IdToString("bone", (uint)boneId)); } foreach (int boneId in boneIds) { Dictionary <AnimChannelID, SortedList <int, object> > dict = framesByBone[boneId]; writer.Write((byte)0); if (everHas.HasFlag(SEAnimPresence.BoneLocation)) { if (!dict.ContainsKey(AnimChannelID.POSITION)) { WriteFrameT(writer, frameWidth, 0); } else { WriteFrames3d(writer, frameWidth, dict[AnimChannelID.POSITION], 2.54f); } } if (everHas.HasFlag(SEAnimPresence.BoneRotation)) { if (!dict.ContainsKey(AnimChannelID.ROTATION)) { WriteFrameT(writer, frameWidth, 0); } else { WriteFrames4d(writer, frameWidth, dict[AnimChannelID.ROTATION]); } } if (everHas.HasFlag(SEAnimPresence.BoneScale)) { if (!dict.ContainsKey(AnimChannelID.SCALE)) { WriteFrameT(writer, frameWidth, 0); } else { WriteFrames3d(writer, frameWidth, dict[AnimChannelID.SCALE]); } } } } return(true); }