1 #include "pch.h"
2 #include "../Def_Str.h"
3 #include "SceneXml.h"
4 #include "FluidsXml.h"
5 #include "tinyxml.h"
6 #include "tinyxml2.h"
7 #include <OgreSceneNode.h>
8 #include "../vdrift/game.h" // for surfaces map
9 using namespace std;
10 using namespace Ogre;
11 using namespace tinyxml2;
12
13
14 // old
LoadStartPos(String file)15 bool Scene::LoadStartPos(String file)
16 {
17 CONFIGFILE param;
18 if (!param.Load(file))
19 return false;
20
21 float f3[3], f1;
22 QUATERNION <float> fixer; fixer.Rotate(3.141593, 0,0,1);
23
24 param.GetParam("start position 0", f3);
25 MATHVECTOR <float, 3> pos(f3[2], f3[0], f3[1]);
26
27 if (!param.GetParam("start orientation-xyz 0", f3))
28 return false;
29
30 if (!param.GetParam("start orientation-w 0", f1))
31 return false;
32
33 QUATERNION <float> rot(f3[2], f3[0], f3[1], f1);
34 rot = fixer * rot;
35
36 startPos = pos;
37 startRot = rot;
38 return true;
39 }
40
41
42 /// Color . . . . . . . .
SColor()43 SColor::SColor()
44 :h(0.f), s(0.f), v(0.f), a(0.f), n(0.f)
45 { }
SColor(float h1,float s1,float v1,float a1,float n1)46 SColor::SColor(float h1, float s1, float v1, float a1, float n1)
47 :h(h1), s(s1), v(v1), a(a1), n(n1)
48 { }
49
50 // tool check err
Check(string t)51 string SColor::Check(string t)
52 {
53 string e;
54 if (h > 1.f) e += " h>1"; if (h < 0.f) e += " h<0";
55 if (s > 1.f) e += " s>1"; if (s < 0.f) e += " s<0";
56 if (v > 3.f) e += " v>3"; if (v < 0.f) e += " v<0";
57 if (a > 2.f) e += " a>2"; if (a < 0.f) e += " a<0";
58 if (n > 1.f) e += " n>1"; if (n < 0.f) e += " n<0";
59 if (!e.empty()) e += " " + t + " " + Save();
60 return e;
61 }
62
63 // load from old rgb
LoadRGB(Vector3 rgb)64 void SColor::LoadRGB(Vector3 rgb)
65 {
66 Vector3 u = rgb;
67 float vMin = std::min(u.x, std::min(u.y, u.z));
68 n = vMin < 0.f ? -vMin : 0.f; // neg = minimum only for negative colors
69 if (vMin < 0.f) u += Vector3(n,n,n); // cancel, normalize to 0
70
71 float vMax = std::max(u.x, std::max(u.y, u.z)); // get max for above 1 colors
72 v = vMax;
73 if (vMax > 1.f) u /= v; // above, normalize to 1
74
75 ColourValue cl(u.x, u.y, u.z); // get hue and sat
76 float vv; // not important or 1
77 cl.getHSB(&h, &s, &vv);
78 }
79
80 // get clr
GetRGB1() const81 Vector3 SColor::GetRGB1() const
82 {
83 ColourValue cl;
84 cl.setHSB(h, s, 1.f);
85 float vv = std::min(1.f, v); // * (1.f - n)
86 return Vector3(
87 cl.r * vv,
88 cl.g * vv,
89 cl.b * vv);
90 }
GetRGB() const91 Vector3 SColor::GetRGB() const
92 {
93 ColourValue cl;
94 cl.setHSB(h, s, 1.f);
95 return Vector3(
96 cl.r * v -n,
97 cl.g * v -n,
98 cl.b * v -n);
99 }
GetClr() const100 ColourValue SColor::GetClr() const
101 {
102 Vector3 c = SColor::GetRGB();
103 return ColourValue(c.x, c.y, c.z);
104 }
GetRGBA() const105 Vector4 SColor::GetRGBA() const
106 {
107 Vector3 c = GetRGB();
108 return Vector4(c.x, c.y, c.z, a);
109 }
110
111 // string
Load(const char * ss)112 void SColor::Load(const char* ss)
113 {
114 h=0.f; s=1.f; v=1.f; a=1.f; n=0.f;
115 int i = sscanf(ss, "%f %f %f %f %f", &h,&s,&v,&a,&n);
116 if (i == 5)
117 return; // new
118
119 if (i < 3 || i > 5)
120 { LogO("NOT 3..5 components color!"); }
121
122 // rgb old < 2.4
123 //float r=h,g=s,b=v,u=a;
124 LoadRGB(Vector3(h,s,v));
125
126 // test back
127 /*Vector4 c = GetRGBA();
128 float d = fabs(c.x-r) + fabs(c.y-g) + fabs(c.z-b) + fabs(c.w-u);
129 LogO(String("CLR CHK ")+ss);
130 LogO("CLR CHK r "+fToStr(c.x-r,2,5)+" g "+fToStr(c.y-g,2,5)+" b "+fToStr(c.z-b,2,5)+" a "+fToStr(c.w-u,2,5)
131 +" d "+fToStr(d,2,4) + (d > 0.01f ? " !!! BAD " : " ok"));/**/
132 }
133
Save() const134 string SColor::Save() const
135 {
136 string ss = fToStr(h,3,5)+" "+fToStr(s,3,5)+" "+fToStr(v,3,5)+" "+fToStr(std::min(3.f,a),3,5)+" "+fToStr(n,3,5);
137 return ss;
138 }
139
140
141 // Load
142 //--------------------------------------------------------------------------------------------------------------------------------------
143
LoadXml(String file,bool bTer)144 bool Scene::LoadXml(String file, bool bTer)
145 {
146 XMLDocument doc;
147 XMLError er = doc.LoadFile(file.c_str());
148 if (er != XML_SUCCESS)
149 { LogO("!Error: Can't load scene.xml: "+file); return false; }
150
151 XMLElement* root = doc.RootElement();
152 if (!root) return false;
153
154 // clear --
155 Default();
156
157 // terrain, asphalt set, vdr outside
158 asphalt = !bTer;
159 ter = bTer;
160
161 //td.layers.clear();
162 //pgLayers.clear();
163
164 // read
165 XMLElement* e, *u;
166 const char* a;
167
168
169 /// ed version
170 int ver = 2300; // old
171 e = root->FirstChildElement("ver");
172 if (e)
173 { a = e->Attribute("num"); if (a) ver = s2i(a);
174 a = e->Attribute("baseTrk"); if (a) baseTrk = string(a);
175 a = e->Attribute("secEd"); if (a) secEdited = s2i(a);
176 }
177
178 /// car setup
179 e = root->FirstChildElement("car");
180 if (e)
181 { a = e->Attribute("tires"); if (a) asphalt = s2i(a) > 0;
182 a = e->Attribute("damage"); if (a) damageMul = s2r(a);
183 a = e->Attribute("road1mtr"); if (a) td.road1mtr = s2i(a) > 0;
184
185 a = e->Attribute("denyRev"); if (a) denyReversed = s2i(a) > 0;
186 a = e->Attribute("gravity"); if (a) gravity = s2r(a);
187 a = e->Attribute("noWrongChks"); if (a) noWrongChks = s2i(a) > 0;
188 }
189
190 /// car start
191 e = root->FirstChildElement("start");
192 if (e)
193 { a = e->Attribute("pos"); if (a) { Vector3 v = s2v(a); startPos = MATHVECTOR<float,3>(v.x,v.y,v.z); }
194 a = e->Attribute("rot"); if (a) { Vector4 v = s2v4(a); startRot = QUATERNION<float>(v.x,v.y,v.z,v.w); }
195 }else
196 { LogO("!Old, loading start from track.txt");
197 String s = StringUtil::replaceAll(file,"scene.xml","track.txt");
198 if (!LoadStartPos(s))
199 LogO("!Error: Can't load start from "+s);
200 }
201
202 /// sound
203 e = root->FirstChildElement("sound");
204 if (e)
205 { a = e->Attribute("ambient"); if (a) sAmbient = string(a);
206 a = e->Attribute("reverbs"); if (a) sReverbs = string(a);
207 UpdRevSet();
208 }
209
210 /// sky
211 e = root->FirstChildElement("sky");
212 if (e)
213 { a = e->Attribute("material"); if (a) skyMtr = String(a);
214 a = e->Attribute("rainEmit"); if (a) rainEmit = s2i(a);
215 a = e->Attribute("rainName"); if (a) rainName = String(a);
216 a = e->Attribute("rain2Emit"); if (a) rain2Emit = s2i(a);
217 a = e->Attribute("rain2Name"); if (a) rain2Name = String(a);
218 a = e->Attribute("windAmt"); if (a) windAmt = s2r(a);
219 a = e->Attribute("skyYaw"); if (a) skyYaw = s2r(a);
220 }
221 /// fog
222 e = root->FirstChildElement("fog");
223 if (e)
224 { a = e->Attribute("linStart"); if (a) fogStart = s2r(a);
225 a = e->Attribute("linEnd"); if (a) fogEnd = s2r(a);
226 a = e->Attribute("color"); if (a) fogClr.Load(a);
227 a = e->Attribute("color2"); if (a) fogClr2.Load(a); else fogClr2 = fogClr;
228 }
229 /// fog H
230 e = root->FirstChildElement("fogH");
231 if (e)
232 { a = e->Attribute("color"); if (a) fogClrH.Load(a);
233 a = e->Attribute("height"); if (a) fogHeight = s2r(a);
234 a = e->Attribute("dens"); if (a) fogHDensity = s2r(a);
235 a = e->Attribute("linStart"); if (a) fogHStart = s2r(a);
236 a = e->Attribute("linEnd"); if (a) fogHEnd = s2r(a);
237 a = e->Attribute("dmg"); if (a) fHDamage = s2r(a);
238 }
239
240 /// light
241 e = root->FirstChildElement("light");
242 if (e)
243 { a = e->Attribute("pitch"); if (a) ldPitch = s2r(a);
244 a = e->Attribute("yaw"); if (a) ldYaw = s2r(a);
245
246 a = e->Attribute("ambient"); if (a) lAmb.Load(a);
247 a = e->Attribute("diffuse"); if (a) lDiff.Load(a);
248 a = e->Attribute("specular"); if (a) lSpec.Load(a);
249 }
250
251
252 /// fluids
253 e = root->FirstChildElement("fluids");
254 if (e)
255 { u = e->FirstChildElement("fluid");
256 while (u)
257 {
258 FluidBox fb;
259 a = u->Attribute("name"); if (a) fb.name = string(a);
260
261 a = u->Attribute("pos"); if (a) fb.pos = s2v(a);
262 a = u->Attribute("rot"); if (a) fb.rot = s2v(a);
263 a = u->Attribute("size"); if (a) fb.size = s2v(a);
264 a = u->Attribute("tile"); if (a) fb.tile = s2v2(a);
265
266 fluids.push_back(fb);
267 u = u->NextSiblingElement("fluid");
268 }
269 }
270
271 /// terrain
272 e = root->FirstChildElement("terrain");
273 if (e)
274 { a = e->Attribute("size"); if (a) td.iVertsX = s2i(a);
275 a = e->Attribute("triangle"); if (a) td.fTriangleSize = s2r(a);
276 a = e->Attribute("errNorm"); if (a) td.errorNorm = s2r(a);
277
278 a = e->Attribute("normSc"); if (a) td.normScale = s2r(a);
279 a = e->Attribute("emissive"); if (a) td.emissive = s2i(a)>0;
280 a = e->Attribute("specPow"); if (a) td.specularPow = s2r(a);
281 a = e->Attribute("specPowEm"); if (a) td.specularPowEm = s2r(a);
282 td.UpdVals();
283
284 int il = 0;
285 u = e->FirstChildElement("texture");
286 while (u)
287 {
288 int road = -1;
289 a = u->Attribute("road"); if (a) road = s2i(a)-1;
290 bool ter = road == -1;
291
292 TerLayer lay, *l = ter ? &lay : &td.layerRoad[road];
293 lay.nFreq[0] += (il-0.7f) * 4.f; // default, can't be same, needs variation
294 lay.nFreq[1] += (il-0.5f) * 3.f;
295
296 a = u->Attribute("on"); if (a) l->on = s2i(a)>0; else l->on = true;
297 a = u->Attribute("file"); if (a) l->texFile = String(a);
298 a = u->Attribute("fnorm"); if (a) l->texNorm = String(a);
299 a = u->Attribute("scale"); if (a) l->tiling = s2r(a);
300 a = u->Attribute("surf"); if (a) l->surfName = String(a);
301
302 a = u->Attribute("dust"); if (a) l->dust = s2r(a);
303 a = u->Attribute("dustS"); if (a) l->dustS = s2r(a);
304 a = u->Attribute("mud"); if (a) l->mud = s2r(a);
305 a = u->Attribute("smoke"); if (a) l->smoke = s2r(a);
306 a = u->Attribute("tclr"); if (a){ l->tclr.Load(a); l->tcl = l->tclr.GetRGBA(); }
307 a = u->Attribute("dmg"); if (a) l->fDamage = s2r(a);
308
309 a = u->Attribute("angMin"); if (a) l->angMin = s2r(a);
310 a = u->Attribute("angMax"); if (a) l->angMax = s2r(a);
311 a = u->Attribute("angSm"); if (a) l->angSm = s2r(a);
312 a = u->Attribute("hMin"); if (a) l->hMin = s2r(a);
313 a = u->Attribute("hMax"); if (a) l->hMax = s2r(a);
314 a = u->Attribute("hSm"); if (a) l->hSm = s2r(a);
315
316 a = u->Attribute("nOn"); if (a) l->nOnly = s2i(a)>0;
317 a = u->Attribute("triplanar"); if (a) l->triplanar = true; else l->triplanar = false;
318
319 a = u->Attribute("noise"); if (a) l->noise = s2r(a);
320 a = u->Attribute("n_1"); if (a) l->nprev = s2r(a);
321 a = u->Attribute("n2"); if (a) l->nnext2 = s2r(a);
322
323 XMLElement* eNoi = u->FirstChildElement("noise");
324 if (eNoi)
325 for (int n=0; n < 2; ++n)
326 { string sn = toStr(n), s;
327 s = "frq"+sn; a = eNoi->Attribute(s.c_str()); if (a) l->nFreq[n]= s2r(a);
328 s = "oct"+sn; a = eNoi->Attribute(s.c_str()); if (a) l->nOct[n] = s2i(a);
329 s = "prs"+sn; a = eNoi->Attribute(s.c_str()); if (a) l->nPers[n]= s2r(a);
330 s = "pow"+sn; a = eNoi->Attribute(s.c_str()); if (a) l->nPow[n] = s2r(a);
331 }
332 if (ter && il < td.ciNumLay)
333 td.layersAll[il++] = lay;
334 u = u->NextSiblingElement("texture");
335 }
336 td.UpdLayers();
337
338 u = e->FirstChildElement("par");
339 if (u)
340 { a = u->Attribute("dust"); if (a) sParDust = String(a);
341 a = u->Attribute("mud"); if (a) sParMud = String(a);
342 a = u->Attribute("smoke"); if (a) sParSmoke = String(a);
343 }
344 }
345
346 /// paged
347 e = root->FirstChildElement("paged");
348 if (e)
349 { a = e->Attribute("densTrees"); if (a) densTrees = s2r(a);
350 a = e->Attribute("densGrass"); if (a) densGrass = s2r(a);
351 // grass
352 a = e->Attribute("grPage"); if (a) grPage = s2r(a);
353 a = e->Attribute("grDist"); if (a) grDist = s2r(a);
354 a = e->Attribute("grDensSmooth"); if (a) grDensSmooth = s2i(a);
355 // trees
356 a = e->Attribute("trPage"); if (a) trPage = s2r(a);
357 a = e->Attribute("trDist"); if (a) trDist = s2r(a);
358 a = e->Attribute("trDistImp"); if (a) trDistImp = s2r(a);
359 a = e->Attribute("trRdDist"); if (a) trRdDist = s2i(a);
360
361 int grl = 0;
362 u = e->FirstChildElement("grass");
363 while (u)
364 {
365 SGrassLayer g;
366 a = u->Attribute("on"); if (a) g.on = s2i(a); else g.on = 1;
367 a = u->Attribute("mtr"); if (a) g.material = String(a);
368 a = u->Attribute("clr"); if (a) g.colorMap = String(a);
369 a = u->Attribute("dens"); if (a) g.dens = s2r(a);
370 a = u->Attribute("chan"); if (a) g.iChan = s2i(a);
371
372 a = u->Attribute("minSx"); if (a) g.minSx = s2r(a);
373 a = u->Attribute("maxSx"); if (a) g.maxSx = s2r(a);
374 a = u->Attribute("minSy"); if (a) g.minSy = s2r(a);
375 a = u->Attribute("maxSy"); if (a) g.maxSy = s2r(a);
376
377 a = u->Attribute("swayDistr"); if (a) g.swayDistr = s2r(a);
378 a = u->Attribute("swayLen"); if (a) g.swayLen = s2r(a);
379 a = u->Attribute("swaySpeed"); if (a) g.swaySpeed = s2r(a);
380
381 #if 1 // old < 2.3 (no channels)
382 if (grl == 0) {
383 a = u->Attribute("terMaxAng"); if (a) grChan[0].angMax = s2r(a);
384 a = u->Attribute("terAngSm"); if (a) grChan[0].angSm = s2r(a);
385
386 a = u->Attribute("terMinH"); if (a) grChan[0].hMin = s2r(a);
387 a = u->Attribute("terMaxH"); if (a) grChan[0].hMax = s2r(a);
388 a = u->Attribute("terHSm"); if (a) grChan[0].hSm = s2r(a); }
389 #endif
390 grLayersAll[grl++] = g;
391 u = u->NextSiblingElement("grass");
392 }
393
394 int c;
395 for (c=0; c < 4; c++)
396 grChan[c].nFreq += c * 3.f; // default variation
397 c = 0;
398
399 u = e->FirstChildElement("gchan");
400 while (u && c < 4)
401 {
402 SGrassChannel& g = grChan[c++];
403 TiXmlElement gch("gchan");
404
405 a = u->Attribute("amin"); if (a) g.angMin = s2r(a);
406 a = u->Attribute("amax"); if (a) g.angMax = s2r(a);
407 a = u->Attribute("asm"); if (a) g.angSm = s2r(a);
408
409 a = u->Attribute("hmin"); if (a) g.hMin = s2r(a);
410 a = u->Attribute("hmax"); if (a) g.hMax = s2r(a);
411 a = u->Attribute("hsm"); if (a) g.hSm = s2r(a);
412
413 a = u->Attribute("ns"); if (a) g.noise = s2r(a);
414 a = u->Attribute("frq"); if (a) g.nFreq = s2r(a);
415 a = u->Attribute("oct"); if (a) g.nOct = s2i(a);
416 a = u->Attribute("prs"); if (a) g.nPers = s2r(a);
417 a = u->Attribute("pow"); if (a) g.nPow = s2r(a);
418
419 a = u->Attribute("rd"); if (a) g.rdPow = s2r(a);
420 u = u->NextSiblingElement("gchan");
421 }
422
423 /// veget
424 int pgl = 0;
425 u = e->FirstChildElement("layer");
426 while (u)
427 {
428 PagedLayer l;
429 a = u->Attribute("on"); if (a) l.on = s2i(a); else l.on = 1;
430 a = u->Attribute("name"); if (a) l.name = String(a);
431 a = u->Attribute("dens"); if (a) l.dens = s2r(a);
432 a = u->Attribute("minScale"); if (a) l.minScale = s2r(a);
433 a = u->Attribute("maxScale"); if (a) l.maxScale = s2r(a);
434
435 a = u->Attribute("ofsY"); if (a) l.ofsY = s2r(a);
436 a = u->Attribute("addTrRdDist");if (a) l.addRdist = s2i(a);
437 a = u->Attribute("maxRdist"); if (a) l.maxRdist = s2i(a);
438 a = u->Attribute("windFx"); if (a) l.windFx = s2r(a);
439 a = u->Attribute("windFy"); if (a) l.windFy = s2r(a);
440
441 a = u->Attribute("maxTerAng"); if (a) l.maxTerAng = s2r(a);
442 a = u->Attribute("minTerH"); if (a) l.minTerH = s2r(a);
443 a = u->Attribute("maxTerH"); if (a) l.maxTerH = s2r(a);
444 a = u->Attribute("maxDepth"); if (a) l.maxDepth = s2r(a);
445
446 pgLayersAll[pgl++] = l;
447 u = u->NextSiblingElement("layer");
448 }
449 UpdPgLayers();
450 }
451
452 /// camera
453 e = root->FirstChildElement("cam");
454 if (e)
455 { a = e->Attribute("pos"); if (a) camPos = s2v(a);
456 a = e->Attribute("dir"); if (a) camDir = s2v(a);
457 }
458
459 /// objects
460 e = root->FirstChildElement("objects");
461 if (e)
462 { u = e->FirstChildElement("o");
463 while (u)
464 {
465 Object o;
466 a = u->Attribute("name"); if (a) o.name = string(a);
467
468 a = u->Attribute("pos"); if (a) { Vector3 v = s2v(a); o.pos = MATHVECTOR<float,3>(v.x,v.y,v.z); }
469 a = u->Attribute("rot"); if (a) { Vector4 v = s2v4(a); o.rot = QUATERNION<float>(v.x,v.y,v.z,v.w); }
470 a = u->Attribute("sc"); if (a) o.scale = s2v(a);
471
472 objects.push_back(o);
473 u = u->NextSiblingElement("o");
474 } }
475
476 UpdateFluidsId();
477
478 UpdateSurfId();
479
480 return true;
481 }
482
483
484 // Save
485 //--------------------------------------------------------------------------------------------------------------------------------------
486
SaveXml(String file)487 bool Scene::SaveXml(String file)
488 {
489 TiXmlDocument xml; TiXmlElement root("scene");
490
491 TiXmlElement ver("ver");
492 int v = SET_VER;
493 ver.SetAttribute("num", toStrC( v ));
494 ver.SetAttribute("baseTrk", baseTrk.c_str());
495 ver.SetAttribute("secEd", toStrC( secEdited ));
496 root.InsertEndChild(ver);
497
498
499 TiXmlElement car("car");
500 car.SetAttribute("tires", asphalt ? "1":"0");
501 if (damageMul != 1.f)
502 car.SetAttribute("damage", toStrC( damageMul ));
503 if (!td.road1mtr)
504 car.SetAttribute("road1mtr", td.road1mtr ? "1":"0");
505 if (noWrongChks)
506 car.SetAttribute("noWrongChks", noWrongChks ? "1":"0");
507
508 if (denyReversed)
509 car.SetAttribute("denyRev", "1");
510 if (gravity != 9.81f)
511 car.SetAttribute("gravity", toStrC( gravity ));
512 root.InsertEndChild(car);
513
514
515 TiXmlElement st("start");
516 string s = toStr(startPos[0])+" "+toStr(startPos[1])+" "+toStr(startPos[2]);
517 st.SetAttribute("pos", s.c_str());
518
519 s = toStr(startRot[0])+" "+toStr(startRot[1])+" "+toStr(startRot[2])+" "+toStr(startRot[3]);
520 st.SetAttribute("rot", s.c_str());
521 root.InsertEndChild(st);
522
523
524 TiXmlElement snd("sound");
525 snd.SetAttribute("ambient", sAmbient.c_str());
526 snd.SetAttribute("reverbs", sReverbs.c_str());
527 root.InsertEndChild(snd);
528
529
530 TiXmlElement sky("sky");
531 sky.SetAttribute("material", skyMtr.c_str());
532 if (rainEmit > 0 && rainName != "")
533 { sky.SetAttribute("rainName", rainName.c_str());
534 sky.SetAttribute("rainEmit", toStrC( rainEmit ));
535 }
536 if (rain2Emit > 0 && rain2Name != "")
537 { sky.SetAttribute("rain2Name", rain2Name.c_str());
538 sky.SetAttribute("rain2Emit", toStrC( rain2Emit ));
539 }
540 if (windAmt != 0.f)
541 sky.SetAttribute("windAmt", toStrC( windAmt ));
542 if (skyYaw != 0.f)
543 sky.SetAttribute("skyYaw", toStrC( skyYaw ));
544 root.InsertEndChild(sky);
545
546 TiXmlElement fog("fog");
547 fog.SetAttribute("color", fogClr.Save().c_str() );
548 fog.SetAttribute("color2", fogClr2.Save().c_str() );
549 fog.SetAttribute("linStart", toStrC( fogStart ));
550 fog.SetAttribute("linEnd", toStrC( fogEnd ));
551 root.InsertEndChild(fog);
552
553 TiXmlElement fogH("fogH");
554 fogH.SetAttribute("color", fogClrH.Save().c_str() );
555 fogH.SetAttribute("height", toStrC( fogHeight ));
556 fogH.SetAttribute("dens", toStrC( fogHDensity ));
557 fogH.SetAttribute("linStart", toStrC( fogHStart ));
558 fogH.SetAttribute("linEnd", toStrC( fogHEnd ));
559 if (fHDamage > 0.f)
560 fogH.SetAttribute("dmg", toStrC( fHDamage ));
561 root.InsertEndChild(fogH);
562
563 TiXmlElement li("light");
564 li.SetAttribute("pitch", toStrC( ldPitch ));
565 li.SetAttribute("yaw", toStrC( ldYaw ));
566 li.SetAttribute("ambient", lAmb.Save().c_str() );
567 li.SetAttribute("diffuse", lDiff.Save().c_str() );
568 li.SetAttribute("specular", lSpec.Save().c_str() );
569 root.InsertEndChild(li);
570
571
572 TiXmlElement fls("fluids");
573 for (int i=0; i < fluids.size(); ++i)
574 {
575 const FluidBox* fb = &fluids[i];
576 TiXmlElement fe("fluid");
577 fe.SetAttribute("name", fb->name.c_str() );
578 fe.SetAttribute("pos", toStrC( fb->pos ));
579 fe.SetAttribute("rot", toStrC( fb->rot ));
580 fe.SetAttribute("size", toStrC( fb->size ));
581 fe.SetAttribute("tile", toStrC( fb->tile ));
582 fls.InsertEndChild(fe);
583 }
584 root.InsertEndChild(fls);
585
586
587 TiXmlElement ter("terrain");
588 ter.SetAttribute("size", toStrC( td.iVertsX ));
589 ter.SetAttribute("triangle", toStrC( td.fTriangleSize ));
590 ter.SetAttribute("errNorm", fToStr( td.errorNorm, 2,4 ).c_str());
591 if (td.normScale != 1.f)
592 ter.SetAttribute("normSc", toStrC( td.normScale ));
593 if (td.emissive)
594 ter.SetAttribute("emissive", td.emissive ? 1 : 0);
595 if (td.specularPow != 32.f)
596 ter.SetAttribute("specPow", toStrC( td.specularPow ));
597 if (td.specularPowEm != 2.f)
598 ter.SetAttribute("specPowEm", toStrC( td.specularPowEm ));
599
600 const TerLayer* l;
601 for (int i=0; i < 6; ++i)
602 {
603 l = &td.layersAll[i];
604 TiXmlElement tex("texture");
605 tex.SetAttribute("on", l->on ? 1 : 0);
606 tex.SetAttribute("file", l->texFile.c_str());
607 tex.SetAttribute("fnorm", l->texNorm.c_str());
608 tex.SetAttribute("scale", toStrC( l->tiling ));
609 tex.SetAttribute("surf", l->surfName.c_str());
610 #define setDmst() \
611 tex.SetAttribute("dust", toStrC( l->dust )); \
612 tex.SetAttribute("dustS", toStrC( l->dustS )); \
613 tex.SetAttribute("mud", toStrC( l->mud )); \
614 tex.SetAttribute("smoke", toStrC( l->smoke )); \
615 tex.SetAttribute("tclr", l->tclr.Save().c_str() );
616 setDmst();
617 if (l->fDamage > 0.f)
618 tex.SetAttribute("dmg", toStrC( l->fDamage ));
619
620 tex.SetAttribute("angMin", toStrC( l->angMin ));
621 tex.SetAttribute("angMax", toStrC( l->angMax ));
622 tex.SetAttribute("angSm", toStrC( l->angSm ));
623 tex.SetAttribute("hMin", toStrC( l->hMin ));
624 tex.SetAttribute("hMax", toStrC( l->hMax ));
625 tex.SetAttribute("hSm", toStrC( l->hSm ));
626
627 tex.SetAttribute("nOn", l->nOnly ? 1 : 0);
628 if (l->triplanar) tex.SetAttribute("triplanar", 1);
629
630 tex.SetAttribute("noise", toStrC( l->noise ));
631 tex.SetAttribute("n_1", toStrC( l->nprev ));
632 tex.SetAttribute("n2", toStrC( l->nnext2 ));
633
634 TiXmlElement noi("noise");
635 for (int n=0; n < 2; ++n)
636 { string sn = toStr(n), s;
637 s = "frq"+sn; noi.SetAttribute(s.c_str(), toStrC( l->nFreq[n] ));
638 s = "oct"+sn; noi.SetAttribute(s.c_str(), toStrC( l->nOct[n] ));
639 s = "prs"+sn; noi.SetAttribute(s.c_str(), toStrC( l->nPers[n] ));
640 s = "pow"+sn; noi.SetAttribute(s.c_str(), toStrC( l->nPow[n] ));
641 }
642 tex.InsertEndChild(noi);
643 ter.InsertEndChild(tex);
644 }
645 for (int i=0; i < 4; ++i)
646 {
647 l = &td.layerRoad[i];
648 TiXmlElement tex("texture");
649 tex.SetAttribute("road", toStrC(i+1));
650 tex.SetAttribute("surf", l->surfName.c_str());
651 setDmst();
652 ter.InsertEndChild(tex);
653 }
654
655 TiXmlElement par("par");
656 par.SetAttribute("dust", sParDust.c_str());
657 par.SetAttribute("mud", sParMud.c_str());
658 par.SetAttribute("smoke", sParSmoke.c_str());
659 ter.InsertEndChild(par);
660
661 root.InsertEndChild(ter);
662
663
664 TiXmlElement pgd("paged");
665 pgd.SetAttribute("densGrass", toStrC( densGrass ));
666 pgd.SetAttribute("densTrees", toStrC( densTrees ));
667 // grass
668 pgd.SetAttribute("grPage", toStrC( grPage ));
669 pgd.SetAttribute("grDist", toStrC( grDist ));
670 pgd.SetAttribute("grDensSmooth",toStrC( grDensSmooth ));
671
672 // trees
673 pgd.SetAttribute("trPage", toStrC( trPage ));
674 pgd.SetAttribute("trDist", toStrC( trDist ));
675 pgd.SetAttribute("trDistImp", toStrC( trDistImp ));
676 pgd.SetAttribute("trRdDist", toStrC( trRdDist ));
677
678 int i;
679 for (int i=0; i < ciNumGrLay; ++i)
680 {
681 const SGrassLayer& g = grLayersAll[i];
682 TiXmlElement grl("grass");
683 grl.SetAttribute("on", g.on ? 1 : 0);
684 grl.SetAttribute("mtr", g.material.c_str());
685 grl.SetAttribute("clr", g.colorMap.c_str());
686 grl.SetAttribute("dens", toStrC( g.dens ));
687 grl.SetAttribute("chan", toStrC( g.iChan ));
688
689 grl.SetAttribute("minSx", toStrC( g.minSx ));
690 grl.SetAttribute("maxSx", toStrC( g.maxSx ));
691 grl.SetAttribute("minSy", toStrC( g.minSy ));
692 grl.SetAttribute("maxSy", toStrC( g.maxSy ));
693
694 grl.SetAttribute("swayDistr", toStrC( g.swayDistr ));
695 grl.SetAttribute("swayLen", toStrC( g.swayLen ));
696 grl.SetAttribute("swaySpeed", toStrC( g.swaySpeed ));
697 pgd.InsertEndChild(grl);
698 }
699
700 for (i=0; i < 4; ++i)
701 {
702 const SGrassChannel& g = grChan[i];
703 TiXmlElement gch("gchan");
704 gch.SetAttribute("amin", toStrC( g.angMin ));
705 gch.SetAttribute("amax", toStrC( g.angMax ));
706 gch.SetAttribute("asm", toStrC( g.angSm ));
707
708 gch.SetAttribute("hmin", toStrC( g.hMin ));
709 gch.SetAttribute("hmax", toStrC( g.hMax ));
710 gch.SetAttribute("hsm", toStrC( g.hSm ));
711
712 gch.SetAttribute("ns", toStrC( g.noise ));
713 gch.SetAttribute("frq", toStrC( g.nFreq ));
714 gch.SetAttribute("oct", toStrC( g.nOct ));
715 gch.SetAttribute("prs", toStrC( g.nPers ));
716 gch.SetAttribute("pow", toStrC( g.nPow ));
717
718 gch.SetAttribute("rd", toStrC( g.rdPow ));
719 pgd.InsertEndChild(gch);
720 }
721
722 for (i=0; i < ciNumPgLay; ++i)
723 {
724 const PagedLayer& l = pgLayersAll[i];
725 TiXmlElement pgl("layer");
726 pgl.SetAttribute("on", l.on ? 1 : 0);
727 pgl.SetAttribute("name", l.name.c_str());
728 pgl.SetAttribute("dens", toStrC( l.dens ));
729 pgl.SetAttribute("minScale", toStrC( l.minScale ));
730 pgl.SetAttribute("maxScale", toStrC( l.maxScale ));
731
732 pgl.SetAttribute("ofsY", toStrC( l.ofsY ));
733 pgl.SetAttribute("addTrRdDist", toStrC( l.addRdist ));
734 pgl.SetAttribute("maxRdist", toStrC( l.maxRdist ));
735 pgl.SetAttribute("windFx", toStrC( l.windFx ));
736 pgl.SetAttribute("windFy", toStrC( l.windFy ));
737
738 pgl.SetAttribute("maxTerAng", toStrC( l.maxTerAng ));
739 pgl.SetAttribute("minTerH", toStrC( l.minTerH ));
740 pgl.SetAttribute("maxTerH", toStrC( l.maxTerH ));
741 pgl.SetAttribute("maxDepth", toStrC( l.maxDepth ));
742 pgd.InsertEndChild(pgl);
743 }
744 root.InsertEndChild(pgd);
745
746
747 TiXmlElement cam("cam");
748 cam.SetAttribute("pos", toStrC( camPos ));
749 cam.SetAttribute("dir", toStrC( camDir ));
750 root.InsertEndChild(cam);
751
752
753 TiXmlElement objs("objects");
754 for (i=0; i < objects.size(); ++i)
755 {
756 const Object* o = &objects[i];
757 TiXmlElement oe("o");
758 oe.SetAttribute("name", o->name.c_str() );
759
760 string s = toStr(o->pos[0])+" "+toStr(o->pos[1])+" "+toStr(o->pos[2]);
761 oe.SetAttribute("pos", s.c_str());
762
763 s = toStr(o->rot[0])+" "+toStr(o->rot[1])+" "+toStr(o->rot[2])+" "+toStr(o->rot[3]);
764 oe.SetAttribute("rot", s.c_str());
765
766 if (o->scale != Vector3::UNIT_SCALE) // dont save default
767 oe.SetAttribute("sc", toStrC( o->scale ));
768 objs.InsertEndChild(oe);
769 }
770 root.InsertEndChild(objs);
771
772
773 xml.InsertEndChild(root);
774 return xml.SaveFile(file.c_str());
775 }
776
777
778 /// Load Presets
779 //--------------------------------------------------------------------------------------------------------------------------------------
780
LoadXml(string file)781 bool Presets::LoadXml(string file)
782 {
783 XMLDocument doc;
784 XMLError e = doc.LoadFile(file.c_str());
785 if (e != XML_SUCCESS)
786 { LogO("!Can't load presets.xml: "+file); return false; }
787
788 XMLElement* root = doc.RootElement();
789 if (!root) return false;
790
791 // clear
792 ter.clear(); iter.clear();
793 rd.clear(); ird.clear();
794 gr.clear(); igr.clear();
795 veg.clear(); iveg.clear();
796
797 // read
798 XMLElement* eSky,*eTex,*eRd,*eVeg,*eGr;
799 const char* a;
800
801 /// sky
802 eSky = root->FirstChildElement("s");
803 while (eSky)
804 {
805 PSky s;
806 a = eSky->Attribute("m"); if (a) s.mtr = String(a);
807 a = eSky->Attribute("c"); if (a) s.clr = String(a);
808
809 a = eSky->Attribute("y"); if (a) s.ldYaw = s2r(a);
810 a = eSky->Attribute("p"); if (a) s.ldPitch = s2r(a);
811
812 sky.push_back(s); isky[s.mtr] = sky.size();
813 eSky = eSky->NextSiblingElement("s");
814 }
815
816 /// terrain
817 eTex = root->FirstChildElement("t");
818 while (eTex)
819 {
820 PTer l;
821 a = eTex->Attribute("t"); if (a) l.texFile = String(a);
822 a = eTex->Attribute("n"); if (a) l.texNorm = String(a);
823 a = eTex->Attribute("s"); if (a) l.tiling = s2r(a);
824 a = eTex->Attribute("su"); if (a) l.surfName = string(a);
825
826 a = eTex->Attribute("sc"); if (a) l.sc = String(a);
827 a = eTex->Attribute("z"); if (a) l.scn = string(a);
828
829 a = eTex->Attribute("du"); if (a) l.dust = s2r(a);
830 a = eTex->Attribute("ds"); if (a) l.dustS = s2r(a);
831 a = eTex->Attribute("md"); if (a) l.mud = s2r(a);
832 a = eTex->Attribute("tr"); if (a) l.tclr.Load(a);
833 a = eTex->Attribute("d"); if (a) l.dmg = s2r(a);
834
835 a = eTex->Attribute("aa"); if (a) l.angMin = s2r(a);
836 a = eTex->Attribute("ab"); if (a) l.angMax = s2r(a);
837 a = eTex->Attribute("tp"); if (a) l.triplanar = s2i(a)>0;
838
839 ter.push_back(l); iter[l.texFile] = ter.size();
840 eTex = eTex->NextSiblingElement("t");
841 }
842
843 /// road
844 eRd = root->FirstChildElement("r");
845 while (eRd)
846 {
847 PRoad l;
848 a = eRd->Attribute("m"); if (a) l.mtr = String(a);
849 a = eRd->Attribute("su"); if (a) l.surfName = string(a);
850
851 a = eRd->Attribute("sc"); if (a) l.sc = String(a);
852 a = eRd->Attribute("z"); if (a) l.scn = string(a);
853
854 a = eRd->Attribute("du"); if (a) l.dust = s2r(a);
855 a = eRd->Attribute("ds"); if (a) l.dustS = s2r(a);
856 a = eRd->Attribute("md"); if (a) l.mud = s2r(a);
857 a = eRd->Attribute("tr"); if (a) l.tclr.Load(a);
858
859 rd.push_back(l); ird[l.mtr] = rd.size();
860 eRd = eRd->NextSiblingElement("r");
861 }
862
863 /// grass
864 eGr = root->FirstChildElement("g");
865 while (eGr)
866 {
867 PGrass g;
868 a = eGr->Attribute("g"); if (a) g.mtr = String(a);
869 a = eGr->Attribute("c"); if (a) g.clr = String(a);
870
871 a = eGr->Attribute("sc"); if (a) g.sc = String(a);
872 a = eGr->Attribute("z"); if (a) g.scn = string(a);
873
874 a = eGr->Attribute("xa"); if (a) g.minSx = s2r(a);
875 a = eGr->Attribute("xb"); if (a) g.maxSx = s2r(a);
876 a = eGr->Attribute("ya"); if (a) g.minSy = s2r(a);
877 a = eGr->Attribute("yb"); if (a) g.maxSy = s2r(a);
878
879 gr.push_back(g); igr[g.mtr] = gr.size();
880 eGr = eGr->NextSiblingElement("g");
881 }
882
883 /// veget
884 eVeg = root->FirstChildElement("v");
885 while (eVeg)
886 {
887 PVeget l;
888 a = eVeg->Attribute("p"); if (a) l.name = String(a);
889 a = eVeg->Attribute("sa"); if (a) l.minScale = s2r(a);
890 a = eVeg->Attribute("sb"); if (a) l.maxScale = s2r(a);
891
892 a = eVeg->Attribute("sc"); if (a) l.sc = String(a);
893 a = eVeg->Attribute("z"); if (a) l.scn = string(a);
894
895 a = eVeg->Attribute("wx"); if (a) l.windFx = s2r(a);
896 a = eVeg->Attribute("wy"); if (a) l.windFy = s2r(a);
897
898 a = eVeg->Attribute("ab"); if (a) l.maxTerAng = s2r(a);
899 a = eVeg->Attribute("rd"); if (a) l.addRdist = s2i(a);
900 a = eVeg->Attribute("fd"); if (a) l.maxDepth = s2r(a);
901
902 veg.push_back(l); iveg[l.name] = veg.size();
903 eVeg = eVeg->NextSiblingElement("v");
904 }
905
906 return true;
907 }
908