source: OniSplit/Xml/ParticleXmlExporter.cs

Last change on this file 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: 18.4 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Globalization;
4using System.Xml;
5using Oni.Imaging;
6
7namespace Oni.Xml
8{
9 using Oni.Particles;
10
11 internal class ParticleXmlExporter : ParticleXml
12 {
13 #region Private data
14 private Particle particle;
15 private XmlWriter xml;
16 #endregion
17
18 private ParticleXmlExporter(Particle particle, XmlWriter writer)
19 {
20 this.particle = particle;
21 this.xml = writer;
22 }
23
24 public static void Export(string name, BinaryReader rawReader, XmlWriter xml)
25 {
26 var particle = new Oni.Particles.Particle(rawReader);
27
28 xml.WriteStartElement("Particle");
29 xml.WriteAttributeString("Name", name);
30
31 var exporter = new ParticleXmlExporter(particle, xml);
32 exporter.Write();
33
34 xml.WriteEndElement();
35 }
36
37 public void Write()
38 {
39 WriteOptions();
40 WriteProperties();
41 WriteAppearance();
42 WriteAttractor();
43 WriteVariables();
44 WriteEmitters();
45 WriteEvents();
46 }
47
48 private void WriteProperties()
49 {
50 xml.WriteStartElement("Properties");
51
52 int flagValue = 0x00001000;
53
54 for (int i = 0; i < 13; i++, flagValue <<= 1)
55 WriteFlag1((ParticleFlags1)flagValue);
56
57 xml.WriteEndElement();
58 }
59
60 private void WriteOptions()
61 {
62 xml.WriteStartElement("Options");
63
64 WriteValue(particle.Lifetime, "Lifetime");
65 xml.WriteElementString("DisableDetailLevel", particle.DisableDetailLevel.ToString());
66
67 foreach (ParticleFlags1 flag in optionFlags1)
68 WriteFlag1(flag);
69
70 foreach (ParticleFlags2 flag in optionFlags2)
71 WriteFlag2(flag);
72
73 WriteValue(particle.CollisionRadius, "CollisionRadius");
74 xml.WriteElementString("AIDodgeRadius", XmlConvert.ToString(particle.AIDodgeRadius));
75 xml.WriteElementString("AIAlertRadius", XmlConvert.ToString(particle.AIAlertRadius));
76 xml.WriteElementString("FlyBySoundName", particle.FlyBySoundName);
77
78 xml.WriteEndElement();
79 }
80
81 private void WriteAttractor()
82 {
83 var attractor = particle.Attractor;
84
85 xml.WriteStartElement("Attractor");
86
87 xml.WriteElementString("Target", attractor.Target.ToString());
88 xml.WriteElementString("Selector", attractor.Selector.ToString());
89
90 xml.WriteElementString("Class", attractor.ClassName);
91 WriteValue(attractor.MaxDistance, "MaxDistance");
92 WriteValue(attractor.MaxAngle, "MaxAngle");
93 WriteValue(attractor.AngleSelectMin, "AngleSelectMin");
94 WriteValue(attractor.AngleSelectMax, "AngleSelectMax");
95 WriteValue(attractor.AngleSelectWeight, "AngleSelectWeight");
96
97 xml.WriteEndElement();
98 }
99
100 private void WriteAppearance()
101 {
102 var appearance = particle.Appearance;
103
104 xml.WriteStartElement("Appearance");
105
106 if ((particle.Flags1 & ParticleFlags1.Geometry) != 0)
107 {
108 xml.WriteElementString("DisplayType", "Geometry");
109 xml.WriteElementString("TexGeom", appearance.TextureName);
110 }
111 else if ((particle.Flags2 & ParticleFlags2.Vector) != 0)
112 {
113 xml.WriteElementString("DisplayType", "Vector");
114 }
115 else if ((particle.Flags2 & ParticleFlags2.Decal) != 0)
116 {
117 xml.WriteElementString("DisplayType", "Decal");
118 xml.WriteElementString("TexGeom", appearance.TextureName);
119 }
120 else
121 {
122 xml.WriteElementString("DisplayType", particle.SpriteType.ToString());
123 xml.WriteElementString("TexGeom", appearance.TextureName);
124 }
125
126 foreach (ParticleFlags1 flag in appearanceFlags1)
127 WriteFlag1(flag);
128
129 foreach (ParticleFlags2 flag in appearanceFlags2)
130 WriteFlag2(flag);
131
132 WriteFlag1(ParticleFlags1.ScaleToVelocity);
133 WriteValue(appearance.Scale, "Scale");
134 WriteFlag1(ParticleFlags1.UseSeparateYScale);
135 WriteValue(appearance.YScale, "YScale");
136 WriteValue(appearance.Rotation, "Rotation");
137 WriteValue(appearance.Alpha, "Alpha");
138 WriteValue(appearance.XOffset, "XOffset");
139 WriteValue(appearance.XShorten, "XShorten");
140
141 WriteFlag2(ParticleFlags2.UseSpecialTint);
142 WriteValue(appearance.Tint, "Tint");
143
144 WriteFlag2(ParticleFlags2.FadeOutOnEdge);
145 WriteFlag2(ParticleFlags2.OneSidedEdgeFade);
146 WriteValue(appearance.EdgeFadeMin, "EdgeFadeMin");
147 WriteValue(appearance.EdgeFadeMax, "EdgeFadeMax");
148
149 WriteValue(appearance.MaxContrail, "MaxContrailDistance");
150
151 WriteFlag2(ParticleFlags2.LensFlare);
152 WriteValue(appearance.LensFlareDistance, "LensFlareDistance");
153
154 xml.WriteElementString("LensFlareFadeInFrames", XmlConvert.ToString(appearance.LensFlareFadeInFrames));
155 xml.WriteElementString("LensFlareFadeOutFrames", XmlConvert.ToString(appearance.LensFlareFadeOutFrames));
156
157 WriteFlag2(ParticleFlags2.DecalFullBrightness);
158 xml.WriteElementString("MaxDecals", XmlConvert.ToString(appearance.MaxDecals));
159 xml.WriteElementString("DecalFadeFrames", XmlConvert.ToString(appearance.DecalFadeFrames));
160 WriteValue(appearance.DecalWrapAngle, "DecalWrapAngle");
161
162 xml.WriteEndElement();
163 }
164
165 private void WriteFlag1(ParticleFlags1 flag)
166 {
167 xml.WriteElementString(flag.ToString(), ((particle.Flags1 & flag) != 0) ? "true" : "false");
168 }
169
170 private void WriteFlag2(ParticleFlags2 flag)
171 {
172 xml.WriteElementString(flag.ToString(), ((particle.Flags2 & flag) != 0) ? "true" : "false");
173 }
174
175 private void WriteVariables()
176 {
177 xml.WriteStartElement("Variables");
178
179 foreach (Variable variable in particle.Variables)
180 WriteVariable(variable);
181
182 xml.WriteEndElement();
183 }
184
185 private void WriteVariable(Variable variable)
186 {
187 switch (variable.StorageType)
188 {
189 case StorageType.Float:
190 xml.WriteStartElement("Float");
191 break;
192 case StorageType.Color:
193 xml.WriteStartElement("Color");
194 break;
195 case StorageType.PingPongState:
196 xml.WriteStartElement("PingPongState");
197 break;
198 }
199
200 xml.WriteAttributeString("Name", variable.Name);
201 WriteValue(variable.Value);
202 xml.WriteEndElement();
203 }
204
205 private void WriteEmitters()
206 {
207 xml.WriteStartElement("Emitters");
208
209 foreach (Emitter e in particle.Emitters)
210 WriteEmitter(e);
211
212 xml.WriteEndElement();
213 }
214
215 private void WriteEmitter(Emitter emitter)
216 {
217 xml.WriteStartElement("Emitter");
218 xml.WriteElementString("Class", emitter.ParticleClass);
219 xml.WriteElementString("Flags", (emitter.Flags == EmitterFlags.None) ? string.Empty : emitter.Flags.ToString().Replace(",", string.Empty));
220 xml.WriteElementString("TurnOffTreshold", XmlConvert.ToString(emitter.TurnOffTreshold));
221 xml.WriteElementString("Probability", XmlConvert.ToString(emitter.Probability / 65535.0f));
222 xml.WriteElementString("Copies", XmlConvert.ToString(emitter.Copies));
223
224 switch (emitter.LinkTo)
225 {
226 case 0:
227 xml.WriteElementString("LinkTo", string.Empty);
228 break;
229 case 1:
230 xml.WriteElementString("LinkTo", "this");
231 break;
232 case 10:
233 xml.WriteElementString("LinkTo", "link");
234 break;
235 default:
236 xml.WriteElementString("LinkTo", XmlConvert.ToString(emitter.LinkTo - 2));
237 break;
238 }
239
240 WriteEmitterRate(emitter);
241 WriteEmitterPosition(emitter);
242 WriteEmitterDirection(emitter);
243 WriteEmitterSpeed(emitter);
244
245 xml.WriteElementString("Orientation", emitter.OrientationDir.ToString());
246 xml.WriteElementString("OrientationUp", emitter.OrientationUp.ToString());
247
248 xml.WriteEndElement();
249 }
250
251 private void WriteEmitterRate(Emitter emitter)
252 {
253 xml.WriteStartElement("Rate");
254 xml.WriteStartElement(emitter.Rate.ToString());
255
256 switch (emitter.Rate)
257 {
258 case EmitterRate.Continous:
259 WriteValue(emitter.Parameters[0], "Interval");
260 break;
261 case EmitterRate.Random:
262 WriteValue(emitter.Parameters[0], "MinInterval");
263 WriteValue(emitter.Parameters[1], "MaxInterval");
264 break;
265 case EmitterRate.Distance:
266 WriteValue(emitter.Parameters[0], "Distance");
267 break;
268 case EmitterRate.Attractor:
269 WriteValue(emitter.Parameters[0], "RechargeTime");
270 WriteValue(emitter.Parameters[1], "CheckInterval");
271 break;
272 }
273
274 xml.WriteEndElement();
275 xml.WriteEndElement();
276 }
277
278 private void WriteEmitterPosition(Emitter emitter)
279 {
280 xml.WriteStartElement("Position");
281 xml.WriteStartElement(emitter.Position.ToString());
282
283 switch (emitter.Position)
284 {
285 case EmitterPosition.Line:
286 WriteValue(emitter.Parameters[2], "Radius");
287 break;
288 case EmitterPosition.Circle:
289 case EmitterPosition.Sphere:
290 WriteValue(emitter.Parameters[2], "InnerRadius");
291 WriteValue(emitter.Parameters[3], "OuterRadius");
292 break;
293 case EmitterPosition.Offset:
294 WriteValue(emitter.Parameters[2], "X");
295 WriteValue(emitter.Parameters[3], "Y");
296 WriteValue(emitter.Parameters[4], "Z");
297 break;
298 case EmitterPosition.Cylinder:
299 WriteValue(emitter.Parameters[2], "Height");
300 WriteValue(emitter.Parameters[3], "InnerRadius");
301 WriteValue(emitter.Parameters[4], "OuterRadius");
302 break;
303 case EmitterPosition.BodySurface:
304 case EmitterPosition.BodyBones:
305 WriteValue(emitter.Parameters[2], "OffsetRadius");
306 break;
307 }
308
309 xml.WriteEndElement();
310 xml.WriteEndElement();
311 }
312
313 private void WriteEmitterDirection(Emitter emitter)
314 {
315 xml.WriteStartElement("Direction");
316 xml.WriteStartElement(emitter.Direction.ToString());
317
318 switch (emitter.Direction)
319 {
320 case EmitterDirection.Cone:
321 WriteValue(emitter.Parameters[5], "Angle");
322 WriteValue(emitter.Parameters[6], "CenterBias");
323 break;
324 case EmitterDirection.Ring:
325 WriteValue(emitter.Parameters[5], "Angle");
326 WriteValue(emitter.Parameters[6], "Offset");
327 break;
328 case EmitterDirection.Offset:
329 WriteValue(emitter.Parameters[5], "X");
330 WriteValue(emitter.Parameters[6], "Y");
331 WriteValue(emitter.Parameters[7], "Z");
332 break;
333 case EmitterDirection.Inaccurate:
334 WriteValue(emitter.Parameters[5], "BaseAngle");
335 WriteValue(emitter.Parameters[6], "Inaccuracy");
336 WriteValue(emitter.Parameters[7], "CenterBias");
337 break;
338 }
339
340 xml.WriteEndElement();
341 xml.WriteEndElement();
342 }
343
344 private void WriteEmitterSpeed(Emitter emitter)
345 {
346 xml.WriteStartElement("Speed");
347 xml.WriteStartElement(emitter.Speed.ToString());
348
349 switch (emitter.Speed)
350 {
351 case EmitterSpeed.Uniform:
352 WriteValue(emitter.Parameters[8], "Speed");
353 break;
354 case EmitterSpeed.Stratified:
355 WriteValue(emitter.Parameters[8], "Speed1");
356 WriteValue(emitter.Parameters[9], "Speed2");
357 break;
358 }
359
360 xml.WriteEndElement();
361 xml.WriteEndElement();
362 }
363
364 private void WriteEvents()
365 {
366 xml.WriteStartElement("Events");
367
368 foreach (Event e in particle.Events)
369 WriteEvent(e);
370
371 xml.WriteEndElement();
372 }
373
374 private void WriteEvent(Event e)
375 {
376 if (e.Actions.Count == 0)
377 return;
378
379 xml.WriteStartElement(e.Type.ToString());
380
381 foreach (EventAction action in e.Actions)
382 WriteAction(action);
383
384 xml.WriteEndElement();
385 }
386
387 private void WriteAction(EventAction action)
388 {
389 int actionTypeIndex = (int)action.Type;
390
391 if (actionTypeIndex >= eventActionInfoTable.Length || eventActionInfoTable[actionTypeIndex] == null)
392 {
393 Console.Error.WriteLine("ParticleXmlExporter: Unknown event action type {0}, ignoring", actionTypeIndex);
394 return;
395 }
396
397 xml.WriteStartElement(action.Type.ToString());
398
399 EventActionInfo info = eventActionInfoTable[actionTypeIndex];
400 int i = 0;
401
402 foreach (VariableReference variable in action.Variables)
403 {
404 if (i < info.Parameters.Length)
405 {
406 xml.WriteElementString(info.Parameters[i++].Name, variable.Name);
407 }
408 }
409
410 foreach (Value value in action.Parameters)
411 {
412 if (i < info.Parameters.Length)
413 {
414 xml.WriteStartElement(info.Parameters[i++].Name);
415 WriteValue(value);
416 xml.WriteEndElement();
417 }
418 }
419
420 xml.WriteEndElement();
421 }
422
423 private void WriteValue(Value value, string name)
424 {
425 xml.WriteStartElement(name);
426 WriteValue(value);
427 xml.WriteEndElement();
428 }
429
430 private void WriteValue(Value value)
431 {
432 if (value == null)
433 return;
434
435 switch (value.Type)
436 {
437 case ValueType.Variable:
438 case ValueType.InstanceName:
439 xml.WriteString(value.Name);
440 break;
441
442 case ValueType.Float:
443 xml.WriteString(XmlConvert.ToString(value.Float1));
444 break;
445
446 case ValueType.FloatRandom:
447 xml.WriteStartElement("Random");
448 xml.WriteAttributeString("Min", XmlConvert.ToString(value.Float1));
449 xml.WriteAttributeString("Max", XmlConvert.ToString(value.Float2));
450 xml.WriteEndElement();
451 break;
452
453 case ValueType.FloatBellCurve:
454 xml.WriteStartElement("BellCurve");
455 xml.WriteAttributeString("Mean", XmlConvert.ToString(value.Float1));
456 xml.WriteAttributeString("StdDev", XmlConvert.ToString(value.Float2));
457 xml.WriteEndElement();
458 break;
459
460 case ValueType.Color:
461 WriteColor(value.Color1);
462 break;
463
464 case ValueType.ColorRandom:
465 xml.WriteStartElement("Random");
466 WriteColorAttribute("Min", value.Color1);
467 WriteColorAttribute("Max", value.Color2);
468 xml.WriteEndElement();
469 break;
470
471 case ValueType.ColorBellCurve:
472 xml.WriteStartElement("BellCurve");
473 WriteColorAttribute("Mean", value.Color1);
474 WriteColorAttribute("StdDev", value.Color2);
475 xml.WriteEndElement();
476 break;
477
478 case ValueType.Int32:
479 xml.WriteString(XmlConvert.ToString(value.Int));
480 break;
481
482 case ValueType.TimeCycle:
483 xml.WriteStartElement("TimeCycle");
484 xml.WriteAttributeString("Length", XmlConvert.ToString(value.Float1));
485 xml.WriteAttributeString("Scale", XmlConvert.ToString(value.Float2));
486 xml.WriteEndElement();
487 break;
488 }
489 }
490
491 private void WriteColor(Color color)
492 {
493 if (color.A == 255)
494 xml.WriteValue(string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", color.R, color.G, color.B));
495 else
496 xml.WriteValue(string.Format(CultureInfo.InvariantCulture, "{0} {1} {2} {3}", color.R, color.G, color.B, color.A));
497 }
498
499 private void WriteColorAttribute(string name, Color color)
500 {
501 if (color.A == 255)
502 xml.WriteAttributeString(name, string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", color.R, color.G, color.B));
503 else
504 xml.WriteAttributeString(name, string.Format(CultureInfo.InvariantCulture, "{0} {1} {2} {3}", color.R, color.G, color.B, color.A));
505 }
506 }
507}
Note: See TracBrowser for help on using the repository browser.