source: OniSplit/Xml/OnieXmlImporter.cs@ 1194

Last change on this file since 1194 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: 8.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Xml;
4using Oni.Metadata;
5using Oni.Particles;
6
7namespace Oni.Xml
8{
9 internal class OnieXmlImporter : RawXmlImporter
10 {
11 #region Private data
12 private List<ImpactEffect> impactEffects = new List<ImpactEffect>();
13 private List<ImpactEffectSound> sounds = new List<ImpactEffectSound>();
14 private List<ImpactEffectParticle> particles = new List<ImpactEffectParticle>();
15 private Dictionary<string, int> materials = new Dictionary<string, int>();
16 private List<KeyValuePair<string, int>> impactList;
17 private List<KeyValuePair<string, int>> materialList;
18 private List<ImpactNode> impactNodes;
19 private List<MaterialNode> materialNodes;
20 #endregion
21
22 private OnieXmlImporter(XmlReader xml, BinaryWriter writer)
23 : base(xml, writer)
24 {
25 }
26
27 public static void Import(XmlReader xml, BinaryWriter writer)
28 {
29 var importer = new OnieXmlImporter(xml, writer);
30 importer.Read();
31 importer.Write();
32 }
33
34 #region private class ImpactLookupNode
35
36 private class ImpactNode
37 {
38 private int impactIndex;
39 private List<MaterialNode> materialNodes;
40
41 public ImpactNode(int impactIndex)
42 {
43 this.impactIndex = impactIndex;
44 this.materialNodes = new List<MaterialNode>();
45 }
46
47 public int ImpactIndex
48 {
49 get
50 {
51 return impactIndex;
52 }
53 }
54
55 public List<MaterialNode> MaterialNodes
56 {
57 get
58 {
59 return materialNodes;
60 }
61 }
62 }
63
64 #endregion
65 #region private class MaterialLookupNode
66
67 private class MaterialNode
68 {
69 private int materialIndex;
70 private List<ImpactEffect> impactEffects;
71
72 public MaterialNode(int materialIndex)
73 {
74 this.materialIndex = materialIndex;
75 this.impactEffects = new List<ImpactEffect>();
76 }
77
78 public int MaterialIndex
79 {
80 get
81 {
82 return materialIndex;
83 }
84 }
85
86 public List<ImpactEffect> ImpactEffects
87 {
88 get
89 {
90 return impactEffects;
91 }
92 }
93 }
94
95 #endregion
96
97 private void Read()
98 {
99 impactList = new List<KeyValuePair<string, int>>();
100
101 while (Xml.IsStartElement("Impact"))
102 {
103 int impactIndex = impactList.Count;
104 var impactName = Xml.GetAttribute("Name");
105 impactList.Add(new KeyValuePair<string, int>(impactName, impactIndex));
106
107 if (Xml.IsEmptyElement)
108 {
109 Xml.ReadStartElement();
110 continue;
111 }
112
113 Xml.ReadStartElement();
114
115 while (Xml.IsStartElement("Material"))
116 {
117 var materialName = Xml.GetAttribute("Name");
118 int materialIndex;
119
120 if (!materials.TryGetValue(materialName, out materialIndex))
121 {
122 materialIndex = materials.Count;
123 materials.Add(materialName, materialIndex);
124 }
125
126 if (Xml.IsEmptyElement)
127 {
128 Xml.ReadStartElement();
129 continue;
130 }
131
132 Xml.ReadStartElement();
133
134 while (Xml.IsStartElement("ImpactEffect"))
135 {
136 Xml.ReadStartElement();
137
138 var impactEffect = new ImpactEffect(Xml, impactName, materialName)
139 {
140 ImpactIndex = impactIndex,
141 MaterialIndex = materialIndex
142 };
143
144 if (impactEffect.Sound != null)
145 {
146 impactEffect.SoundIndex = sounds.Count;
147 sounds.Add(impactEffect.Sound);
148 }
149 else
150 {
151 impactEffect.SoundIndex = -1;
152 }
153
154 if (impactEffect.Particles != null && impactEffect.Particles.Length > 0)
155 {
156 impactEffect.ParticleIndex = particles.Count;
157 particles.AddRange(impactEffect.Particles);
158 }
159 else
160 {
161 impactEffect.ParticleIndex = -1;
162 }
163
164 impactEffects.Add(impactEffect);
165
166 Xml.ReadEndElement();
167 }
168
169 Xml.ReadEndElement();
170 }
171
172 Xml.ReadEndElement();
173 }
174
175 materialList = new List<KeyValuePair<string, int>>(materials);
176 materialList.Sort((x, y) => x.Value.CompareTo(y.Value));
177
178 impactNodes = new List<ImpactNode>();
179 materialNodes = new List<MaterialNode>();
180
181 foreach (var impact in impactList)
182 {
183 var impactNode = new ImpactNode(impact.Value);
184 impactNodes.Add(impactNode);
185
186 foreach (var material in materialList)
187 {
188 var materialNode = new MaterialNode(material.Value);
189
190 foreach (var effect in impactEffects)
191 {
192 if (effect.MaterialIndex == material.Value && effect.ImpactIndex == impact.Value)
193 materialNode.ImpactEffects.Add(effect);
194 }
195
196 if (materialNode.ImpactEffects.Count > 0)
197 {
198 impactNode.MaterialNodes.Add(materialNode);
199 materialNodes.Add(materialNode);
200 }
201 }
202 }
203 }
204
205 private void Write()
206 {
207 Writer.Write(2);
208 Writer.Write(impactList.Count);
209 Writer.Write(materialList.Count);
210 Writer.Write(particles.Count);
211 Writer.Write(sounds.Count);
212 Writer.Write(impactEffects.Count);
213 Writer.Write(materialNodes.Count);
214
215 foreach (KeyValuePair<string, int> impact in impactList)
216 {
217 Writer.Write(impact.Key, 128);
218 Writer.Write(0);
219 }
220
221 foreach (KeyValuePair<string, int> material in materialList)
222 {
223 Writer.Write(material.Key, 128);
224 Writer.Write(0);
225 }
226
227 int currentMaterialIndex = 0;
228
229 foreach (var impactNode in impactNodes)
230 {
231 Writer.WriteInt16(impactNode.ImpactIndex);
232 Writer.WriteInt16(impactNode.MaterialNodes.Count);
233 Writer.Write(currentMaterialIndex);
234
235 currentMaterialIndex += impactNode.MaterialNodes.Count;
236 }
237
238 foreach (var particle in particles)
239 {
240 particle.Write(Writer);
241 }
242
243 foreach (var sound in sounds)
244 {
245 sound.Write(Writer);
246 }
247
248 foreach (var materialNode in materialNodes)
249 {
250 foreach (var effect in materialNode.ImpactEffects)
251 effect.Write(Writer);
252 }
253
254 int currentImpactEffectIndex = 0;
255
256 foreach (var materialNode in materialNodes)
257 {
258 Writer.WriteInt16(materialNode.MaterialIndex);
259 Writer.WriteInt16(materialNode.ImpactEffects.Count);
260 Writer.Write(currentImpactEffectIndex);
261
262 currentImpactEffectIndex += materialNode.ImpactEffects.Count;
263 }
264 }
265 }
266}
Note: See TracBrowser for help on using the repository browser.