| 1 | using System; | 
 
 
 
 
 | 2 | using Oni.Motoko; | 
 
 
 
 
 | 3 |  | 
 
 
 
 
 | 4 | namespace Oni.Totoro | 
 
 
 
 
 | 5 | { | 
 
 
 
 
 | 6 | internal static class BodyDatReader | 
 
 
 
 
 | 7 | { | 
 
 
 
 
 | 8 | public static Body Read(InstanceDescriptor source) | 
 
 
 
 
 | 9 | { | 
 
 
 
 
 | 10 | InstanceDescriptor trcm = ReadTRCM(source); | 
 
 
 
 
 | 11 |  | 
 
 
 
 
 | 12 | InstanceDescriptor trga; | 
 
 
 
 
 | 13 | InstanceDescriptor trta; | 
 
 
 
 
 | 14 | InstanceDescriptor tria; | 
 
 
 
 
 | 15 |  | 
 
 
 
 
 | 16 | using (var reader = trcm.OpenRead(84)) | 
 
 
 
 
 | 17 | { | 
 
 
 
 
 | 18 | trga = reader.ReadInstance(); | 
 
 
 
 
 | 19 | trta = reader.ReadInstance(); | 
 
 
 
 
 | 20 | tria = reader.ReadInstance(); | 
 
 
 
 
 | 21 | } | 
 
 
 
 
 | 22 |  | 
 
 
 
 
 | 23 | var geometries = ReadTRGA(trga); | 
 
 
 
 
 | 24 | var translations = ReadTRTA(trta); | 
 
 
 
 
 | 25 | var indices = ReadTRIA(tria); | 
 
 
 
 
 | 26 |  | 
 
 
 
 
 | 27 | var nodes = new BodyNode[geometries.Length]; | 
 
 
 
 
 | 28 |  | 
 
 
 
 
 | 29 | for (int i = 0; i < nodes.Length; i++) | 
 
 
 
 
 | 30 | { | 
 
 
 
 
 | 31 | nodes[i] = new BodyNode | 
 
 
 
 
 | 32 | { | 
 
 
 
 
 | 33 | Name = BodyNode.Names[i], | 
 
 
 
 
 | 34 | Index = i, | 
 
 
 
 
 | 35 | Geometry = geometries[i], | 
 
 
 
 
 | 36 | Translation = translations[i], | 
 
 
 
 
 | 37 | }; | 
 
 
 
 
 | 38 | } | 
 
 
 
 
 | 39 |  | 
 
 
 
 
 | 40 | for (int i = 0; i < nodes.Length; i++) | 
 
 
 
 
 | 41 | { | 
 
 
 
 
 | 42 | var node = nodes[i]; | 
 
 
 
 
 | 43 |  | 
 
 
 
 
 | 44 | for (int j = indices[i].FirstChildIndex; j != 0; j = indices[j].SiblingIndex) | 
 
 
 
 
 | 45 | { | 
 
 
 
 
 | 46 | nodes[j].Parent = node; | 
 
 
 
 
 | 47 | node.Nodes.Add(nodes[j]); | 
 
 
 
 
 | 48 | } | 
 
 
 
 
 | 49 | } | 
 
 
 
 
 | 50 |  | 
 
 
 
 
 | 51 | var body = new Body(); | 
 
 
 
 
 | 52 | body.Nodes.AddRange(nodes); | 
 
 
 
 
 | 53 | return body; | 
 
 
 
 
 | 54 | } | 
 
 
 
 
 | 55 |  | 
 
 
 
 
 | 56 | private static InstanceDescriptor ReadTRCM(InstanceDescriptor source) | 
 
 
 
 
 | 57 | { | 
 
 
 
 
 | 58 | if (source.Template.Tag == TemplateTag.TRCM) | 
 
 
 
 
 | 59 | return source; | 
 
 
 
 
 | 60 |  | 
 
 
 
 
 | 61 | if (source.Template.Tag == TemplateTag.ONCC) | 
 
 
 
 
 | 62 | source = Game.CharacterClass.Read(source).Body; | 
 
 
 
 
 | 63 |  | 
 
 
 
 
 | 64 | if (source.Template.Tag != TemplateTag.TRBS) | 
 
 
 
 
 | 65 | throw new InvalidOperationException(string.Format("Invalid body source type {0}", source.Template.Tag)); | 
 
 
 
 
 | 66 |  | 
 
 
 
 
 | 67 | return ReadTRBS(source).Last(); | 
 
 
 
 
 | 68 | } | 
 
 
 
 
 | 69 |  | 
 
 
 
 
 | 70 | private static InstanceDescriptor[] ReadTRBS(InstanceDescriptor trbs) | 
 
 
 
 
 | 71 | { | 
 
 
 
 
 | 72 | using (var reader = trbs.OpenRead()) | 
 
 
 
 
 | 73 | return reader.ReadInstanceArray(5); | 
 
 
 
 
 | 74 | } | 
 
 
 
 
 | 75 |  | 
 
 
 
 
 | 76 | private static Geometry[] ReadTRGA(InstanceDescriptor trga) | 
 
 
 
 
 | 77 | { | 
 
 
 
 
 | 78 | InstanceDescriptor[] descriptors; | 
 
 
 
 
 | 79 |  | 
 
 
 
 
 | 80 | using (var reader = trga.OpenRead(22)) | 
 
 
 
 
 | 81 | descriptors = reader.ReadInstanceArray(reader.ReadInt16()); | 
 
 
 
 
 | 82 |  | 
 
 
 
 
 | 83 | var geometries = new Geometry[descriptors.Length]; | 
 
 
 
 
 | 84 |  | 
 
 
 
 
 | 85 | for (int i = 0; i < descriptors.Length; i++) | 
 
 
 
 
 | 86 | geometries[i] = GeometryDatReader.Read(descriptors[i]); | 
 
 
 
 
 | 87 |  | 
 
 
 
 
 | 88 | return geometries; | 
 
 
 
 
 | 89 | } | 
 
 
 
 
 | 90 |  | 
 
 
 
 
 | 91 | private static Vector3[] ReadTRTA(InstanceDescriptor trta) | 
 
 
 
 
 | 92 | { | 
 
 
 
 
 | 93 | using (var reader = trta.OpenRead(22)) | 
 
 
 
 
 | 94 | return reader.ReadVector3Array(reader.ReadInt16()); | 
 
 
 
 
 | 95 | } | 
 
 
 
 
 | 96 |  | 
 
 
 
 
 | 97 | private struct NodeIndices | 
 
 
 
 
 | 98 | { | 
 
 
 
 
 | 99 | public byte ParentIndex; | 
 
 
 
 
 | 100 | public byte FirstChildIndex; | 
 
 
 
 
 | 101 | public byte SiblingIndex; | 
 
 
 
 
 | 102 | } | 
 
 
 
 
 | 103 |  | 
 
 
 
 
 | 104 | private static NodeIndices[] ReadTRIA(InstanceDescriptor tria) | 
 
 
 
 
 | 105 | { | 
 
 
 
 
 | 106 | using (var reader = tria.OpenRead(22)) | 
 
 
 
 
 | 107 | { | 
 
 
 
 
 | 108 | var indices = new NodeIndices[reader.ReadInt16()]; | 
 
 
 
 
 | 109 |  | 
 
 
 
 
 | 110 | for (int i = 0; i < indices.Length; i++) | 
 
 
 
 
 | 111 | { | 
 
 
 
 
 | 112 | indices[i].ParentIndex = reader.ReadByte(); | 
 
 
 
 
 | 113 | indices[i].FirstChildIndex = reader.ReadByte(); | 
 
 
 
 
 | 114 | indices[i].SiblingIndex = reader.ReadByte(); | 
 
 
 
 
 | 115 | reader.Skip(1); | 
 
 
 
 
 | 116 | } | 
 
 
 
 
 | 117 |  | 
 
 
 
 
 | 118 | return indices; | 
 
 
 
 
 | 119 | } | 
 
 
 
 
 | 120 | } | 
 
 
 
 
 | 121 | } | 
 
 
 
 
 | 122 | } |