aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SOPVehicle.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SOPVehicle.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SOPVehicle.cs792
1 files changed, 792 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SOPVehicle.cs b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs
new file mode 100644
index 0000000..41e8944
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/SOPVehicle.cs
@@ -0,0 +1,792 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using OpenSim.Framework;
32using OpenSim.Region.Physics.Manager;
33using System.Text;
34using System.IO;
35using System.Xml;
36using OpenSim.Framework.Serialization;
37using OpenSim.Framework.Serialization.External;
38using OpenSim.Region.Framework.Scenes.Serialization;
39using OpenSim.Region.Framework.Scenes.Serialization;
40
41namespace OpenSim.Region.Framework.Scenes
42{
43 public class SOPVehicle
44 {
45 public VehicleData vd;
46
47 public Vehicle Type
48 {
49 get { return vd.m_type; }
50 }
51
52 public SOPVehicle()
53 {
54 vd = new VehicleData();
55 ProcessTypeChange(Vehicle.TYPE_NONE); // is needed?
56 }
57
58 public void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
59 {
60 float len;
61 float timestep = 0.01f;
62 switch (pParam)
63 {
64 case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
65 if (pValue < 0f) pValue = 0f;
66 if (pValue > 1f) pValue = 1f;
67 vd.m_angularDeflectionEfficiency = pValue;
68 break;
69 case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
70 if (pValue < timestep) pValue = timestep;
71 vd.m_angularDeflectionTimescale = pValue;
72 break;
73 case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
74 if (pValue < timestep) pValue = timestep;
75 else if (pValue > 120) pValue = 120;
76 vd.m_angularMotorDecayTimescale = pValue;
77 break;
78 case Vehicle.ANGULAR_MOTOR_TIMESCALE:
79 if (pValue < timestep) pValue = timestep;
80 vd.m_angularMotorTimescale = pValue;
81 break;
82 case Vehicle.BANKING_EFFICIENCY:
83 if (pValue < -1f) pValue = -1f;
84 if (pValue > 1f) pValue = 1f;
85 vd.m_bankingEfficiency = pValue;
86 break;
87 case Vehicle.BANKING_MIX:
88 if (pValue < 0f) pValue = 0f;
89 if (pValue > 1f) pValue = 1f;
90 vd.m_bankingMix = pValue;
91 break;
92 case Vehicle.BANKING_TIMESCALE:
93 if (pValue < timestep) pValue = timestep;
94 vd.m_bankingTimescale = pValue;
95 break;
96 case Vehicle.BUOYANCY:
97 if (pValue < -1f) pValue = -1f;
98 if (pValue > 1f) pValue = 1f;
99 vd.m_VehicleBuoyancy = pValue;
100 break;
101 case Vehicle.HOVER_EFFICIENCY:
102 if (pValue < 0f) pValue = 0f;
103 if (pValue > 1f) pValue = 1f;
104 vd.m_VhoverEfficiency = pValue;
105 break;
106 case Vehicle.HOVER_HEIGHT:
107 vd.m_VhoverHeight = pValue;
108 break;
109 case Vehicle.HOVER_TIMESCALE:
110 if (pValue < timestep) pValue = timestep;
111 vd.m_VhoverTimescale = pValue;
112 break;
113 case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
114 if (pValue < 0f) pValue = 0f;
115 if (pValue > 1f) pValue = 1f;
116 vd.m_linearDeflectionEfficiency = pValue;
117 break;
118 case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
119 if (pValue < timestep) pValue = timestep;
120 vd.m_linearDeflectionTimescale = pValue;
121 break;
122 case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
123 if (pValue < timestep) pValue = timestep;
124 else if (pValue > 120) pValue = 120;
125 vd.m_linearMotorDecayTimescale = pValue;
126 break;
127 case Vehicle.LINEAR_MOTOR_TIMESCALE:
128 if (pValue < timestep) pValue = timestep;
129 vd.m_linearMotorTimescale = pValue;
130 break;
131 case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
132 if (pValue < 0f) pValue = 0f;
133 if (pValue > 1f) pValue = 1f;
134 vd.m_verticalAttractionEfficiency = pValue;
135 break;
136 case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
137 if (pValue < timestep) pValue = timestep;
138 vd.m_verticalAttractionTimescale = pValue;
139 break;
140
141 // These are vector properties but the engine lets you use a single float value to
142 // set all of the components to the same value
143 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
144 if (pValue < timestep) pValue = timestep;
145 vd.m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
146 break;
147 case Vehicle.ANGULAR_MOTOR_DIRECTION:
148 vd.m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
149 len = vd.m_angularMotorDirection.Length();
150 if (len > 12.566f)
151 vd.m_angularMotorDirection *= (12.566f / len);
152 break;
153 case Vehicle.LINEAR_FRICTION_TIMESCALE:
154 if (pValue < timestep) pValue = timestep;
155 vd.m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
156 break;
157 case Vehicle.LINEAR_MOTOR_DIRECTION:
158 vd.m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
159 len = vd.m_linearMotorDirection.Length();
160 if (len > 30.0f)
161 vd.m_linearMotorDirection *= (30.0f / len);
162 break;
163 case Vehicle.LINEAR_MOTOR_OFFSET:
164 vd.m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
165 len = vd.m_linearMotorOffset.Length();
166 if (len > 100.0f)
167 vd.m_linearMotorOffset *= (100.0f / len);
168 break;
169 }
170 }//end ProcessFloatVehicleParam
171
172 public void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
173 {
174 float len;
175 float timestep = 0.01f;
176 switch (pParam)
177 {
178 case Vehicle.ANGULAR_FRICTION_TIMESCALE:
179 if (pValue.X < timestep) pValue.X = timestep;
180 if (pValue.Y < timestep) pValue.Y = timestep;
181 if (pValue.Z < timestep) pValue.Z = timestep;
182
183 vd.m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
184 break;
185 case Vehicle.ANGULAR_MOTOR_DIRECTION:
186 vd.m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
187 // Limit requested angular speed to 2 rps= 4 pi rads/sec
188 len = vd.m_angularMotorDirection.Length();
189 if (len > 12.566f)
190 vd.m_angularMotorDirection *= (12.566f / len);
191 break;
192 case Vehicle.LINEAR_FRICTION_TIMESCALE:
193 if (pValue.X < timestep) pValue.X = timestep;
194 if (pValue.Y < timestep) pValue.Y = timestep;
195 if (pValue.Z < timestep) pValue.Z = timestep;
196 vd.m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
197 break;
198 case Vehicle.LINEAR_MOTOR_DIRECTION:
199 vd.m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
200 len = vd.m_linearMotorDirection.Length();
201 if (len > 30.0f)
202 vd.m_linearMotorDirection *= (30.0f / len);
203 break;
204 case Vehicle.LINEAR_MOTOR_OFFSET:
205 vd.m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
206 len = vd.m_linearMotorOffset.Length();
207 if (len > 100.0f)
208 vd.m_linearMotorOffset *= (100.0f / len);
209 break;
210 }
211 }//end ProcessVectorVehicleParam
212
213 public void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
214 {
215 switch (pParam)
216 {
217 case Vehicle.REFERENCE_FRAME:
218 vd.m_referenceFrame = Quaternion.Inverse(pValue);
219 break;
220 }
221 }//end ProcessRotationVehicleParam
222
223 public void ProcessVehicleFlags(int pParam, bool remove)
224 {
225 if (remove)
226 {
227 vd.m_flags &= ~((VehicleFlag)pParam);
228 }
229 else
230 {
231 vd.m_flags |= (VehicleFlag)pParam;
232 }
233 }//end ProcessVehicleFlags
234
235 public void ProcessTypeChange(Vehicle pType)
236 {
237 vd.m_linearMotorDirection = Vector3.Zero;
238 vd.m_angularMotorDirection = Vector3.Zero;
239 vd.m_linearMotorOffset = Vector3.Zero;
240 vd.m_referenceFrame = Quaternion.Identity;
241
242 // Set Defaults For Type
243 vd.m_type = pType;
244 switch (pType)
245 {
246 case Vehicle.TYPE_NONE:
247 vd.m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
248 vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
249 vd.m_linearMotorTimescale = 1000;
250 vd.m_linearMotorDecayTimescale = 120;
251 vd.m_angularMotorTimescale = 1000;
252 vd.m_angularMotorDecayTimescale = 1000;
253 vd.m_VhoverHeight = 0;
254 vd.m_VhoverEfficiency = 1;
255 vd.m_VhoverTimescale = 1000;
256 vd.m_VehicleBuoyancy = 0;
257 vd.m_linearDeflectionEfficiency = 0;
258 vd.m_linearDeflectionTimescale = 1000;
259 vd.m_angularDeflectionEfficiency = 0;
260 vd.m_angularDeflectionTimescale = 1000;
261 vd.m_bankingEfficiency = 0;
262 vd.m_bankingMix = 1;
263 vd.m_bankingTimescale = 1000;
264 vd.m_verticalAttractionEfficiency = 0;
265 vd.m_verticalAttractionTimescale = 1000;
266
267 vd.m_flags = (VehicleFlag)0;
268 break;
269
270 case Vehicle.TYPE_SLED:
271 vd.m_linearFrictionTimescale = new Vector3(30, 1, 1000);
272 vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
273 vd.m_linearMotorTimescale = 1000;
274 vd.m_linearMotorDecayTimescale = 120;
275 vd.m_angularMotorTimescale = 1000;
276 vd.m_angularMotorDecayTimescale = 120;
277 vd.m_VhoverHeight = 0;
278 vd.m_VhoverEfficiency = 1;
279 vd.m_VhoverTimescale = 10;
280 vd.m_VehicleBuoyancy = 0;
281 vd.m_linearDeflectionEfficiency = 1;
282 vd.m_linearDeflectionTimescale = 1;
283 vd.m_angularDeflectionEfficiency = 0;
284 vd.m_angularDeflectionTimescale = 1000;
285 vd.m_bankingEfficiency = 0;
286 vd.m_bankingMix = 1;
287 vd.m_bankingTimescale = 10;
288 vd.m_flags &=
289 ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
290 VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
291 vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
292 break;
293 case Vehicle.TYPE_CAR:
294 vd.m_linearFrictionTimescale = new Vector3(100, 2, 1000);
295 vd.m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
296 vd.m_linearMotorTimescale = 1;
297 vd.m_linearMotorDecayTimescale = 60;
298 vd.m_angularMotorTimescale = 1;
299 vd.m_angularMotorDecayTimescale = 0.8f;
300 vd.m_VhoverHeight = 0;
301 vd.m_VhoverEfficiency = 0;
302 vd.m_VhoverTimescale = 1000;
303 vd.m_VehicleBuoyancy = 0;
304 vd.m_linearDeflectionEfficiency = 1;
305 vd.m_linearDeflectionTimescale = 2;
306 vd.m_angularDeflectionEfficiency = 0;
307 vd.m_angularDeflectionTimescale = 10;
308 vd.m_verticalAttractionEfficiency = 1f;
309 vd.m_verticalAttractionTimescale = 10f;
310 vd.m_bankingEfficiency = -0.2f;
311 vd.m_bankingMix = 1;
312 vd.m_bankingTimescale = 1;
313 vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
314 vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
315 VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY);
316 break;
317 case Vehicle.TYPE_BOAT:
318 vd.m_linearFrictionTimescale = new Vector3(10, 3, 2);
319 vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
320 vd.m_linearMotorTimescale = 5;
321 vd.m_linearMotorDecayTimescale = 60;
322 vd.m_angularMotorTimescale = 4;
323 vd.m_angularMotorDecayTimescale = 4;
324 vd.m_VhoverHeight = 0;
325 vd.m_VhoverEfficiency = 0.5f;
326 vd.m_VhoverTimescale = 2;
327 vd.m_VehicleBuoyancy = 1;
328 vd.m_linearDeflectionEfficiency = 0.5f;
329 vd.m_linearDeflectionTimescale = 3;
330 vd.m_angularDeflectionEfficiency = 0.5f;
331 vd.m_angularDeflectionTimescale = 5;
332 vd.m_verticalAttractionEfficiency = 0.5f;
333 vd.m_verticalAttractionTimescale = 5f;
334 vd.m_bankingEfficiency = -0.3f;
335 vd.m_bankingMix = 0.8f;
336 vd.m_bankingTimescale = 1;
337 vd.m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
338 VehicleFlag.HOVER_GLOBAL_HEIGHT |
339 VehicleFlag.HOVER_UP_ONLY |
340 VehicleFlag.LIMIT_ROLL_ONLY);
341 vd.m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
342 VehicleFlag.LIMIT_MOTOR_UP |
343 VehicleFlag.HOVER_WATER_ONLY);
344 break;
345 case Vehicle.TYPE_AIRPLANE:
346 vd.m_linearFrictionTimescale = new Vector3(200, 10, 5);
347 vd.m_angularFrictionTimescale = new Vector3(20, 20, 20);
348 vd.m_linearMotorTimescale = 2;
349 vd.m_linearMotorDecayTimescale = 60;
350 vd.m_angularMotorTimescale = 4;
351 vd.m_angularMotorDecayTimescale = 8;
352 vd.m_VhoverHeight = 0;
353 vd.m_VhoverEfficiency = 0.5f;
354 vd.m_VhoverTimescale = 1000;
355 vd.m_VehicleBuoyancy = 0;
356 vd.m_linearDeflectionEfficiency = 0.5f;
357 vd.m_linearDeflectionTimescale = 0.5f;
358 vd.m_angularDeflectionEfficiency = 1;
359 vd.m_angularDeflectionTimescale = 2;
360 vd.m_verticalAttractionEfficiency = 0.9f;
361 vd.m_verticalAttractionTimescale = 2f;
362 vd.m_bankingEfficiency = 1;
363 vd.m_bankingMix = 0.7f;
364 vd.m_bankingTimescale = 2;
365 vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
366 VehicleFlag.HOVER_TERRAIN_ONLY |
367 VehicleFlag.HOVER_GLOBAL_HEIGHT |
368 VehicleFlag.HOVER_UP_ONLY |
369 VehicleFlag.NO_DEFLECTION_UP |
370 VehicleFlag.LIMIT_MOTOR_UP);
371 vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
372 break;
373 case Vehicle.TYPE_BALLOON:
374 vd.m_linearFrictionTimescale = new Vector3(5, 5, 5);
375 vd.m_angularFrictionTimescale = new Vector3(10, 10, 10);
376 vd.m_linearMotorTimescale = 5;
377 vd.m_linearMotorDecayTimescale = 60;
378 vd.m_angularMotorTimescale = 6;
379 vd.m_angularMotorDecayTimescale = 10;
380 vd.m_VhoverHeight = 5;
381 vd.m_VhoverEfficiency = 0.8f;
382 vd.m_VhoverTimescale = 10;
383 vd.m_VehicleBuoyancy = 1;
384 vd.m_linearDeflectionEfficiency = 0;
385 vd.m_linearDeflectionTimescale = 5;
386 vd.m_angularDeflectionEfficiency = 0;
387 vd.m_angularDeflectionTimescale = 5;
388 vd.m_verticalAttractionEfficiency = 0f;
389 vd.m_verticalAttractionTimescale = 1000f;
390 vd.m_bankingEfficiency = 0;
391 vd.m_bankingMix = 0.7f;
392 vd.m_bankingTimescale = 5;
393 vd.m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
394 VehicleFlag.HOVER_TERRAIN_ONLY |
395 VehicleFlag.HOVER_UP_ONLY |
396 VehicleFlag.NO_DEFLECTION_UP |
397 VehicleFlag.LIMIT_MOTOR_UP);
398 vd.m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
399 VehicleFlag.HOVER_GLOBAL_HEIGHT);
400 break;
401 }
402 }
403 public void SetVehicle(PhysicsActor ph)
404 {
405 if (ph == null)
406 return;
407 ph.SetVehicle(vd);
408 }
409
410 private XmlTextWriter writer;
411
412 private void XWint(string name, int i)
413 {
414 writer.WriteElementString(name, i.ToString());
415 }
416
417 private void XWfloat(string name, float f)
418 {
419 writer.WriteElementString(name, f.ToString(Utils.EnUsCulture));
420 }
421
422 private void XWVector(string name, Vector3 vec)
423 {
424 writer.WriteStartElement(name);
425 writer.WriteElementString("X", vec.X.ToString(Utils.EnUsCulture));
426 writer.WriteElementString("Y", vec.Y.ToString(Utils.EnUsCulture));
427 writer.WriteElementString("Z", vec.Z.ToString(Utils.EnUsCulture));
428 writer.WriteEndElement();
429 }
430
431 private void XWQuat(string name, Quaternion quat)
432 {
433 writer.WriteStartElement(name);
434 writer.WriteElementString("X", quat.X.ToString(Utils.EnUsCulture));
435 writer.WriteElementString("Y", quat.Y.ToString(Utils.EnUsCulture));
436 writer.WriteElementString("Z", quat.Z.ToString(Utils.EnUsCulture));
437 writer.WriteElementString("W", quat.W.ToString(Utils.EnUsCulture));
438 writer.WriteEndElement();
439 }
440
441 public void ToXml2(XmlTextWriter twriter)
442 {
443 writer = twriter;
444 writer.WriteStartElement("Vehicle");
445
446 XWint("TYPE", (int)vd.m_type);
447 XWint("FLAGS", (int)vd.m_flags);
448
449 // Linear properties
450 XWVector("LMDIR", vd.m_linearMotorDirection);
451 XWVector("LMFTIME", vd.m_linearFrictionTimescale);
452 XWfloat("LMDTIME", vd.m_linearMotorDecayTimescale);
453 XWfloat("LMTIME", vd.m_linearMotorTimescale);
454 XWVector("LMOFF", vd.m_linearMotorOffset);
455
456 //Angular properties
457 XWVector("AMDIR", vd.m_angularMotorDirection);
458 XWfloat("AMTIME", vd.m_angularMotorTimescale);
459 XWfloat("AMDTIME", vd.m_angularMotorDecayTimescale);
460 XWVector("AMFTIME", vd.m_angularFrictionTimescale);
461
462 //Deflection properties
463 XWfloat("ADEFF", vd.m_angularDeflectionEfficiency);
464 XWfloat("ADTIME", vd.m_angularDeflectionTimescale);
465 XWfloat("LDEFF", vd.m_linearDeflectionEfficiency);
466 XWfloat("LDTIME", vd.m_linearDeflectionTimescale);
467
468 //Banking properties
469 XWfloat("BEFF", vd.m_bankingEfficiency);
470 XWfloat("BMIX", vd.m_bankingMix);
471 XWfloat("BTIME", vd.m_bankingTimescale);
472
473 //Hover and Buoyancy properties
474 XWfloat("HHEI", vd.m_VhoverHeight);
475 XWfloat("HEFF", vd.m_VhoverEfficiency);
476 XWfloat("HTIME", vd.m_VhoverTimescale);
477 XWfloat("VBUO", vd.m_VehicleBuoyancy);
478
479 //Attractor properties
480 XWfloat("VAEFF", vd.m_verticalAttractionEfficiency);
481 XWfloat("VATIME", vd.m_verticalAttractionTimescale);
482
483 XWQuat("REF_FRAME", vd.m_referenceFrame);
484
485 writer.WriteEndElement();
486 writer = null;
487 }
488
489
490
491 XmlTextReader reader;
492
493 private int XRint()
494 {
495 return reader.ReadElementContentAsInt();
496 }
497
498 private float XRfloat()
499 {
500 return reader.ReadElementContentAsFloat();
501 }
502
503 public Vector3 XRvector()
504 {
505 Vector3 vec;
506 reader.ReadStartElement();
507 vec.X = reader.ReadElementContentAsFloat();
508 vec.Y = reader.ReadElementContentAsFloat();
509 vec.Z = reader.ReadElementContentAsFloat();
510 reader.ReadEndElement();
511 return vec;
512 }
513
514 public Quaternion XRquat()
515 {
516 Quaternion q;
517 reader.ReadStartElement();
518 q.X = reader.ReadElementContentAsFloat();
519 q.Y = reader.ReadElementContentAsFloat();
520 q.Z = reader.ReadElementContentAsFloat();
521 q.W = reader.ReadElementContentAsFloat();
522 reader.ReadEndElement();
523 return q;
524 }
525
526 public static bool EReadProcessors(
527 Dictionary<string, Action> processors,
528 XmlTextReader xtr)
529 {
530 bool errors = false;
531
532 string nodeName = string.Empty;
533 while (xtr.NodeType != XmlNodeType.EndElement)
534 {
535 nodeName = xtr.Name;
536
537 // m_log.DebugFormat("[ExternalRepresentationUtils]: Processing: {0}", nodeName);
538
539 Action p = null;
540 if (processors.TryGetValue(xtr.Name, out p))
541 {
542 // m_log.DebugFormat("[ExternalRepresentationUtils]: Found {0} processor, nodeName);
543
544 try
545 {
546 p();
547 }
548 catch (Exception e)
549 {
550 errors = true;
551 if (xtr.NodeType == XmlNodeType.EndElement)
552 xtr.Read();
553 }
554 }
555 else
556 {
557 // m_log.DebugFormat("[LandDataSerializer]: caught unknown element {0}", nodeName);
558 xtr.ReadOuterXml(); // ignore
559 }
560 }
561
562 return errors;
563 }
564
565
566 public string ToXml2()
567 {
568 MemoryStream ms = new MemoryStream(512);
569 UTF8Encoding enc = new UTF8Encoding();
570 XmlTextWriter xwriter = new XmlTextWriter(ms, enc);
571 ToXml2(xwriter);
572 xwriter.Flush();
573 string s = ms.GetStreamString();
574 xwriter.Close();
575 return s;
576 }
577
578 public static SOPVehicle FromXml2(string text)
579 {
580 if (text == String.Empty)
581 return null;
582
583 UTF8Encoding enc = new UTF8Encoding();
584 MemoryStream ms = new MemoryStream(enc.GetBytes(text));
585 XmlTextReader xreader = new XmlTextReader(ms);
586
587 SOPVehicle v = new SOPVehicle();
588 bool error;
589
590 v.FromXml2(xreader, out error);
591
592 xreader.Close();
593
594 if (error)
595 {
596 v = null;
597 return null;
598 }
599 return v;
600 }
601
602 public static SOPVehicle FromXml2(XmlTextReader reader)
603 {
604 SOPVehicle vehicle = new SOPVehicle();
605
606 bool errors = false;
607
608 vehicle.FromXml2(reader, out errors);
609 if (errors)
610 return null;
611
612 return vehicle;
613 }
614
615 private void FromXml2(XmlTextReader _reader, out bool errors)
616 {
617 errors = false;
618 reader = _reader;
619
620 Dictionary<string, Action> m_VehicleXmlProcessors
621 = new Dictionary<string, Action>();
622
623 m_VehicleXmlProcessors.Add("TYPE", ProcessXR_type);
624 m_VehicleXmlProcessors.Add("FLAGS", ProcessXR_flags);
625
626 // Linear properties
627 m_VehicleXmlProcessors.Add("LMDIR", ProcessXR_linearMotorDirection);
628 m_VehicleXmlProcessors.Add("LMFTIME", ProcessXR_linearFrictionTimescale);
629 m_VehicleXmlProcessors.Add("LMDTIME", ProcessXR_linearMotorDecayTimescale);
630 m_VehicleXmlProcessors.Add("LMTIME", ProcessXR_linearMotorTimescale);
631 m_VehicleXmlProcessors.Add("LMOFF", ProcessXR_linearMotorOffset);
632
633 //Angular properties
634 m_VehicleXmlProcessors.Add("AMDIR", ProcessXR_angularMotorDirection);
635 m_VehicleXmlProcessors.Add("AMTIME", ProcessXR_angularMotorTimescale);
636 m_VehicleXmlProcessors.Add("AMDTIME", ProcessXR_angularMotorDecayTimescale);
637 m_VehicleXmlProcessors.Add("AMFTIME", ProcessXR_angularFrictionTimescale);
638
639 //Deflection properties
640 m_VehicleXmlProcessors.Add("ADEFF", ProcessXR_angularDeflectionEfficiency);
641 m_VehicleXmlProcessors.Add("ADTIME", ProcessXR_angularDeflectionTimescale);
642 m_VehicleXmlProcessors.Add("LDEFF", ProcessXR_linearDeflectionEfficiency);
643 m_VehicleXmlProcessors.Add("LDTIME", ProcessXR_linearDeflectionTimescale);
644
645 //Banking properties
646 m_VehicleXmlProcessors.Add("BEFF", ProcessXR_bankingEfficiency);
647 m_VehicleXmlProcessors.Add("BMIX", ProcessXR_bankingMix);
648 m_VehicleXmlProcessors.Add("BTIME", ProcessXR_bankingTimescale);
649
650 //Hover and Buoyancy properties
651 m_VehicleXmlProcessors.Add("HHEI", ProcessXR_VhoverHeight);
652 m_VehicleXmlProcessors.Add("HEFF", ProcessXR_VhoverEfficiency);
653 m_VehicleXmlProcessors.Add("HTIME", ProcessXR_VhoverTimescale);
654
655 m_VehicleXmlProcessors.Add("VBUO", ProcessXR_VehicleBuoyancy);
656
657 //Attractor properties
658 m_VehicleXmlProcessors.Add("VAEFF", ProcessXR_verticalAttractionEfficiency);
659 m_VehicleXmlProcessors.Add("VATIME", ProcessXR_verticalAttractionTimescale);
660
661 m_VehicleXmlProcessors.Add("REF_FRAME", ProcessXR_referenceFrame);
662
663 vd = new VehicleData();
664
665 reader.ReadStartElement("Vehicle", String.Empty);
666
667 errors = EReadProcessors(
668 m_VehicleXmlProcessors,
669 reader);
670
671 reader.ReadEndElement();
672 reader = null;
673 }
674
675 private void ProcessXR_type()
676 {
677 vd.m_type = (Vehicle)XRint();
678 }
679 private void ProcessXR_flags()
680 {
681 vd.m_flags = (VehicleFlag)XRint();
682 }
683 // Linear properties
684 private void ProcessXR_linearMotorDirection()
685 {
686 vd.m_linearMotorDirection = XRvector();
687 }
688
689 private void ProcessXR_linearFrictionTimescale()
690 {
691 vd.m_linearFrictionTimescale = XRvector();
692 }
693
694 private void ProcessXR_linearMotorDecayTimescale()
695 {
696 vd.m_linearMotorDecayTimescale = XRfloat();
697 }
698 private void ProcessXR_linearMotorTimescale()
699 {
700 vd.m_linearMotorTimescale = XRfloat();
701 }
702 private void ProcessXR_linearMotorOffset()
703 {
704 vd.m_linearMotorOffset = XRvector();
705 }
706
707
708 //Angular properties
709 private void ProcessXR_angularMotorDirection()
710 {
711 vd.m_angularMotorDirection = XRvector();
712 }
713 private void ProcessXR_angularMotorTimescale()
714 {
715 vd.m_angularMotorTimescale = XRfloat();
716 }
717 private void ProcessXR_angularMotorDecayTimescale()
718 {
719 vd.m_angularMotorDecayTimescale = XRfloat();
720 }
721 private void ProcessXR_angularFrictionTimescale()
722 {
723 vd.m_angularFrictionTimescale = XRvector();
724 }
725
726 //Deflection properties
727 private void ProcessXR_angularDeflectionEfficiency()
728 {
729 vd.m_angularDeflectionEfficiency = XRfloat();
730 }
731 private void ProcessXR_angularDeflectionTimescale()
732 {
733 vd.m_angularDeflectionTimescale = XRfloat();
734 }
735 private void ProcessXR_linearDeflectionEfficiency()
736 {
737 vd.m_linearDeflectionEfficiency = XRfloat();
738 }
739 private void ProcessXR_linearDeflectionTimescale()
740 {
741 vd.m_linearDeflectionTimescale = XRfloat();
742 }
743
744 //Banking properties
745 private void ProcessXR_bankingEfficiency()
746 {
747 vd.m_bankingEfficiency = XRfloat();
748 }
749 private void ProcessXR_bankingMix()
750 {
751 vd.m_bankingMix = XRfloat();
752 }
753 private void ProcessXR_bankingTimescale()
754 {
755 vd.m_bankingTimescale = XRfloat();
756 }
757
758 //Hover and Buoyancy properties
759 private void ProcessXR_VhoverHeight()
760 {
761 vd.m_VhoverHeight = XRfloat();
762 }
763 private void ProcessXR_VhoverEfficiency()
764 {
765 vd.m_VhoverEfficiency = XRfloat();
766 }
767 private void ProcessXR_VhoverTimescale()
768 {
769 vd.m_VhoverTimescale = XRfloat();
770 }
771
772 private void ProcessXR_VehicleBuoyancy()
773 {
774 vd.m_VehicleBuoyancy = XRfloat();
775 }
776
777 //Attractor properties
778 private void ProcessXR_verticalAttractionEfficiency()
779 {
780 vd.m_verticalAttractionEfficiency = XRfloat();
781 }
782 private void ProcessXR_verticalAttractionTimescale()
783 {
784 vd.m_verticalAttractionTimescale = XRfloat();
785 }
786
787 private void ProcessXR_referenceFrame()
788 {
789 vd.m_referenceFrame = XRquat();
790 }
791 }
792}