source: OniSplit/Totoro/BodyDatReader.cs@ 1192

Last change on this file since 1192 was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 3.8 KB
Line 
1using System;
2using Oni.Motoko;
3
4namespace 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}
Note: See TracBrowser for help on using the repository browser.