internal void Write(EndianBinaryWriter writer) { var stringSet = new StringSet(this); writer.ScheduleWriteOffset(16, AlignmentMode.Center, () => { foreach (var bone in Bones) { if (bone.IsEx) { bone.Id = stringSet.GetStringId(bone.Name); } writer.Write(bone.Id); } }); writer.ScheduleWriteOffset(16, AlignmentMode.Center, () => { foreach (var bone in Bones) { writer.Write(bone.InverseBindPoseMatrix); } }); writer.ScheduleWriteOffset(16, AlignmentMode.Center, () => { foreach (var bone in Bones) { writer.AddStringToStringTable(bone.Name); } writer.WriteNulls(writer.AddressSpace.GetByteSize()); }); writer.ScheduleWriteOffsetIf(stringSet.Strings.Count > 0 || Blocks.Count > 0, 16, AlignmentMode.Center, () => { var osageNames = new List <string>(Blocks.Count / 2); var osageBones = new List <OsageBone>(Blocks.Count / 2); foreach (var block in Blocks) { if (!(block is OsageBlock osageBlock)) { continue; } osageBlock.StartIndex = osageBones.Count; osageBones.AddRange(osageBlock.Bones); osageNames.Add(osageBlock.ExternalName); }
internal void Write(EndianBinaryWriter writer, BinaryFormat format) { var stringSet = new StringSet(this); writer.ScheduleWriteOffset(16, AlignmentMode.Center, () => { foreach (var bone in Bones) { if (bone.IsEx) { bone.Id = stringSet.GetStringId(bone.Name); } writer.Write(bone.Id); } }); writer.ScheduleWriteOffset(16, AlignmentMode.Center, () => { foreach (var bone in Bones) { writer.Write(bone.InverseBindPoseMatrix); } }); writer.ScheduleWriteOffset(16, AlignmentMode.Center, () => { foreach (var bone in Bones) { writer.AddStringToStringTable(bone.Name); } writer.WriteNulls(writer.AddressSpace.GetByteSize()); }); writer.ScheduleWriteOffsetIf(stringSet.Strings.Count > 0 || Blocks.Count > 0, 16, AlignmentMode.Center, () => { var osageNames = new List <string>(Blocks.Count / 2); var osageNodes = new List <OsageNode>(Blocks.Count / 2); var clothNames = new List <string>(Blocks.Count / 8); foreach (var block in Blocks) { switch (block) { case OsageBlock osageBlock: osageBlock.StartIndex = osageNodes.Count; osageNodes.AddRange(osageBlock.Nodes); osageNames.Add(osageBlock.ExternalName); break; case ClothBlock clothBlock: clothNames.Add(clothBlock.Name); break; } } writer.Write(osageNames.Count); writer.Write(osageNodes.Count); writer.WriteNulls(sizeof(uint)); writer.ScheduleWriteOffset(4, AlignmentMode.Left, () => { foreach (var osageNode in osageNodes) { osageNode.Write(writer, stringSet); } writer.WriteNulls(3 * sizeof(uint)); }); writer.ScheduleWriteOffset(16, AlignmentMode.Left, () => { foreach (string value in osageNames) { writer.AddStringToStringTable(value); } foreach (string value in clothNames) { writer.AddStringToStringTable(value); } writer.WriteNulls(writer.AddressSpace.GetByteSize()); }); writer.ScheduleWriteOffset(16, AlignmentMode.Left, () => { foreach (var block in Blocks) { writer.AddStringToStringTable(block.Signature); writer.ScheduleWriteOffset(8, AlignmentMode.Left, () => block.Write(writer, stringSet, format)); } writer.WriteNulls(writer.AddressSpace.GetByteSize() * 2); }); writer.Write(stringSet.Strings.Count); writer.ScheduleWriteOffset(16, AlignmentMode.Left, () => { foreach (string value in stringSet.Strings) { writer.AddStringToStringTable(value); } writer.WriteNulls(writer.AddressSpace.GetByteSize()); }); writer.ScheduleWriteOffset(16, AlignmentMode.Left, () => { foreach (var osageNode in osageNodes) { if (string.IsNullOrEmpty(osageNode.SiblingName)) { continue; } stringSet.WriteString(writer, osageNode.Name); stringSet.WriteString(writer, osageNode.SiblingName); writer.Write(osageNode.SiblingMaxDistance); } writer.WriteNulls(3 * sizeof(uint)); }); writer.Write(clothNames.Count); if (writer.AddressSpace == AddressSpace.Int64) { writer.WriteNulls(4); } writer.WriteNulls(7 * writer.AddressSpace.GetByteSize()); }); writer.Write(Bones.Count); writer.ScheduleWriteOffsetIf(Bones.Any(x => x.Parent != null), 16, AlignmentMode.Center, () => { foreach (var bone in Bones) { writer.Write(bone.Parent?.Id ?? 0xFFFFFFFF); } }); writer.WriteNulls(3 * writer.AddressSpace.GetByteSize()); }