using System; using System.Collections.Generic; namespace Oni.Totoro { internal static class BodyDatWriter { public static ImporterDescriptor Write(Body body, ImporterFile importer) { var trcm = importer.CreateInstance(TemplateTag.TRCM); var trga = importer.CreateInstance(TemplateTag.TRGA); var trta = importer.CreateInstance(TemplateTag.TRTA); var tria = importer.CreateInstance(TemplateTag.TRIA); var nodes = body.Nodes; int nodeCount = nodes.Count; var geometryDescriptors = new ImporterDescriptor[nodeCount]; var translations = new Vector3[nodeCount]; var indices = new NodeIndices[nodeCount]; foreach (var node in nodes) { int nodeIndex = node.Index; geometryDescriptors[nodeIndex] = Motoko.GeometryDatWriter.Write(node.Geometry, importer); translations[nodeIndex] = node.Translation; int childCount = node.Nodes.Count; if (childCount > 0) { indices[nodeIndex].FirstChildIndex = (byte)node.Nodes[0].Index; int lastChildIndex = childCount - 1; for (int i = 0; i < childCount; i++) { int childIndex = node.Nodes[i].Index; if (i != lastChildIndex) indices[childIndex].SiblingIndex = (byte)node.Nodes[i + 1].Index; indices[childIndex].ParentIndex = (byte)nodeIndex; } } } WriteTRCM(trcm, trga, trta, tria, nodeCount); WriteTRGA(trga, geometryDescriptors); WriteTRTA(trta, translations); WriteTRIA(tria, indices); return trcm; } private static void WriteTRCM(ImporterDescriptor trcm, ImporterDescriptor trga, ImporterDescriptor trta, ImporterDescriptor tria, int nodeCount) { using (var writer = trcm.OpenWrite(4)) { writer.WriteInt16(nodeCount); writer.Skip(78); writer.Write(trga); writer.Write(trta); writer.Write(tria); } } private static void WriteTRGA(ImporterDescriptor trga, ImporterDescriptor[] descriptors) { using (var writer = trga.OpenWrite(22)) { writer.WriteInt16(descriptors.Length); writer.Write(descriptors); } } private static void WriteTRTA(ImporterDescriptor trta, Vector3[] translations) { using (var writer = trta.OpenWrite(22)) { writer.WriteInt16(translations.Length); writer.Write(translations); } } private struct NodeIndices { public byte ParentIndex; public byte FirstChildIndex; public byte SiblingIndex; } private static void WriteTRIA(ImporterDescriptor tria, NodeIndices[] indices) { using (var writer = tria.OpenWrite(22)) { writer.WriteInt16(indices.Length); foreach (var node in indices) { writer.WriteByte(node.ParentIndex); writer.WriteByte(node.FirstChildIndex); writer.WriteByte(node.SiblingIndex); writer.WriteByte(0); } } } } }