1 #include "pch.h"
2 #include "../ogre/common/Def_Str.h"
3 #include "settings.h"
4 #include "CApp.h"
5 #include "CGui.h"
6 #include "../ogre/common/CScene.h"
7 #include "../ogre/common/data/CData.h"
8 #include "../road/Road.h"
9 #include <fstream>
10 #include "../ogre/common/Gui_Def.h"
11 #include "../ogre/common/Slider.h"
12 #include "../ogre/common/MultiList2.h"
13 #include <OgreOverlay.h>
14 #include <OgreOverlayElement.h>
15 #include <OgreRectangle2D.h>
16 #include <OgreSceneNode.h>
17 #include <OgreCamera.h>
18 #include <OgreRenderWindow.h>
19 #include <MyGUI.h>
20 using namespace MyGUI;
21 using namespace Ogre;
22 using namespace std;
23 
24 
25 ///  used value colors  blue,green,yellow,orange,red,black  ..
26 const Colour CGui::sUsedClr[8] = {
27 	Colour(0.2,0.6,1), Colour(0,1,0.6), Colour(0,1,0), Colour(0.5,1,0),
28 	Colour(1,1,0), Colour(1,0.5,0), Colour(1,0,0), Colour(0.9,0.2,0.2)};
29 
SetUsedStr(Txt valUsed,int cnt,int yellowAt)30 void CGui::SetUsedStr(Txt valUsed, int cnt, int yellowAt)
31 {
32 	if (!valUsed)  return;
33 	valUsed->setCaption(TR("#{Used}") + ": " + toStr(cnt));
34 	valUsed->setTextColour(sUsedClr[ (int)( std::min(7.f, 4.f*float(cnt)/yellowAt )) ]);
35 }
36 
37 
38 ///  Gui Events
39 
40 //  [Sky]
41 //-----------------------------------------------------------------------------------------------------------
42 
comboSky(Cmb cmb,size_t val)43 void CGui::comboSky(Cmb cmb, size_t val)  // sky materials
44 {
45 	String s = cmb->getItemNameAt(val);
46 	sc->skyMtr = s;  app->UpdateTrack();
47 }
48 
comboRain1(Cmb cmb,size_t val)49 void CGui::comboRain1(Cmb cmb, size_t val)  // rain types
50 {
51 	String s = cmb->getItemNameAt(val);  sc->rainName = s;
52 	app->scn->DestroyWeather();  app->scn->CreateWeather();
53 }
comboRain2(Cmb cmb,size_t val)54 void CGui::comboRain2(Cmb cmb, size_t val)
55 {
56 	String s = cmb->getItemNameAt(val);  sc->rain2Name = s;
57 	app->scn->DestroyWeather();  app->scn->CreateWeather();
58 }
59 
slUpdSky(SV *)60 void CGui::slUpdSky(SV*){	scn->UpdSky();	}
slUpdSun(SV *)61 void CGui::slUpdSun(SV*){	scn->UpdSun();	}
62 
63 //  fog
slUpdFog(SV *)64 void CGui::slUpdFog(SV*)
65 {
66 	scn->UpdFog();
67 }
68 
69 //  chk disable
chkFog(Ck *)70 void CGui::chkFog(Ck*)
71 {
72 	scn->UpdFog();
73 }
74 
75 
76 //  [Vegetation]
77 //-----------------------------------------------------------------------------------------------------------
78 
editTrGr(Ed ed)79 void CGui::editTrGr(Ed ed)
80 {
81 	Real r = s2r(ed->getCaption());
82 	String n = ed->getName();
83 	SGrassLayer* gr = &sc->grLayersAll[idGrLay], *g0 = &sc->grLayersAll[0];
84 
85 	     if (n=="GrPage")  sc->grPage = r;   else if (n=="GrDist")  sc->grDist = r;
86 	else if (n=="TrPage")  sc->trPage = r;   else if (n=="TrDist")  sc->trDist = r;
87 	else if (n=="TrImpDist")  sc->trDistImp = r;
88 
89 	else if (n=="GrSwayDistr")  g0->swayDistr = r;
90 	else if (n=="GrSwayLen")  g0->swayLen = r;
91 	else if (n=="GrSwaySpd")  g0->swaySpeed = r;
92 }
93 
comboGrassClr(Cmb cmb,size_t val)94 void CGui::comboGrassClr(Cmb cmb, size_t val)
95 {
96 	String s = cmb->getItemNameAt(val);
97 	SGrassLayer* gr = &sc->grLayersAll[idGrLay];
98 	gr->colorMap = s;
99 	imgGrClr->setImageTexture(gr->colorMap);
100 }
101 
102 
103 ///  Grass layers  ----------------------------------------------------------
104 
tabGrLayers(Tab wp,size_t id)105 void CGui::tabGrLayers(Tab wp, size_t id)
106 {
107 	idGrLay = id;  // help var
108 	SldUpd_GrL();
109 	SldUpd_GrChan();
110 	const SGrassLayer* gr = &sc->grLayersAll[idGrLay], *g0 = &sc->grLayersAll[0];
111 
112 	imgGrass->setImageTexture(gr->material + ".png");  // same mtr name as tex
113 	imgGrClr->setImageTexture(gr->colorMap);
114 
115 	int used=0;
116 	for (int i=0; i < sc->ciNumGrLay; ++i)
117 		if (sc->grLayersAll[i].on)  ++used;
118 	SetUsedStr(valLGrAll, used, 4);
119 
120 	#define _Ed(name, val)  ed##name->setCaption(toStr(val));
121 	#define _Cmb(cmb, str)  cmb->setIndexSelected( cmb->findItemIndexWith(str) );
122 
123 	btnGrassMtr->setCaption(gr->material);
124 	for (int i=0; i < liGrs->getItemCount(); ++i)  // upd pick
125 		if (liGrs->getSubItemNameAt(1,i).substr(7) == gr->material)
126 			liGrs->setIndexSelected(i);
127 	_Cmb(cmbGrassClr, gr->colorMap);
128 
129 	_Ed(GrSwayDistr, g0->swayDistr);
130 	_Ed(GrSwayLen, g0->swayLen);
131 	_Ed(GrSwaySpd, g0->swaySpeed);  //g0-
132 }
133 
134 //  tab changed, set slider pointer values, and update
SldUpd_GrL()135 void CGui::SldUpd_GrL()
136 {
137 	SGrassLayer& gr =  sc->grLayersAll[idGrLay];
138 	ckGrLayOn.Upd(&gr.on);
139 	svGrChan.UpdI(&gr.iChan);
140 	svLGrDens.UpdF(&gr.dens);
141 
142 	svGrMinX.UpdF(&gr.minSx);  svGrMaxX.UpdF(&gr.maxSx);
143 	svGrMinY.UpdF(&gr.minSy);  svGrMaxY.UpdF(&gr.maxSy);
144 }
145 
146 ///  channels
tabGrChan(Tab wp,size_t id)147 void CGui::tabGrChan(Tab wp, size_t id)
148 {
149 	idGrChan = id;  // help var
150 	SldUpd_GrChan();
151 }
152 
SldUpd_GrChan()153 void CGui::SldUpd_GrChan()
154 {
155 	SGrassChannel& gr =  sc->grChan[idGrChan];
156 	svGrChAngMin.UpdF(&gr.angMin);  svGrChAngMax.UpdF(&gr.angMax);  svGrChAngSm.UpdF(&gr.angSm);
157 	svGrChHMin.UpdF(&gr.hMin);  svGrChHMax.UpdF(&gr.hMax);  svGrChHSm.UpdF(&gr.hSm);
158 	svGrChRdPow.UpdF(&gr.rdPow);
159 	svGrChNoise.UpdF(&gr.noise);  svGrChNfreq.UpdF(&gr.nFreq);
160 	svGrChNoct.UpdI(&gr.nOct);  svGrChNpers.UpdF(&gr.nPers);  svGrChNpow.UpdF(&gr.nPow);
161 }
162 
chkGrLayOn(Ck *)163 void CGui::chkGrLayOn(Ck*)
164 {
165 	int used=0;
166 	for (int i=0; i < sc->ciNumGrLay; ++i)
167 		if (sc->grLayersAll[i].on)  ++used;
168 	SetUsedStr(valLGrAll, used, 4);
169 }
170 
171 
172 ///  Vegetation layers  -----------------------------------------------------
173 
tabPgLayers(Tab wp,size_t id)174 void CGui::tabPgLayers(Tab wp, size_t id)
175 {
176 	idPgLay = id;  // help var
177 	SldUpd_PgL();
178 
179 	const PagedLayer& lay = sc->pgLayersAll[idPgLay];
180 	string s = lay.name.substr(0, lay.name.length()-5);
181 
182 	btnVeget->setCaption(s);
183 	for (int i=0; i < liVeg->getItemCount(); ++i)  // upd pick
184 		if (liVeg->getSubItemNameAt(1,i).substr(7) == s)
185 			liVeg->setIndexSelected(i);
186 
187 	Upd3DView(lay.name);
188 	SetUsedStr(valLTrAll, sc->pgLayers.size(), 5);
189 	txVCnt->setCaption(toStr(lay.cnt));
190 }
191 
updVegetInfo()192 void CGui::updVegetInfo()
193 {
194 	Vector3 va = viewSc * svLTrMinSc.getF(),
195 			vb = viewSc * svLTrMaxSc.getF();
196 	float wa = std::max(va.x, va.z), wb = std::max(vb.x, vb.z);
197 	txVHmin->setCaption(fToStr(va.y, 1,4));
198 	txVHmax->setCaption(fToStr(vb.y, 1,4));
199 	txVWmin->setCaption(fToStr(wa, 1,4));
200 	txVWmax->setCaption(fToStr(wb, 1,4));
201 }
202 
slLTrSc(SV *)203 void CGui::slLTrSc(SV*)
204 {
205 	updVegetInfo();
206 }
207 
208 //  tab changed
SldUpd_PgL()209 void CGui::SldUpd_PgL()
210 {
211 	PagedLayer& lay = sc->pgLayersAll[idPgLay];
212 	ckPgLayOn.Upd(&lay.on);
213 	svLTrDens.UpdF(&lay.dens);
214 
215 	svLTrRdDist.UpdI(&lay.addRdist);
216 	svLTrRdDistMax.UpdI(&lay.maxRdist);
217 
218 	svLTrMinSc.UpdF(&lay.minScale);
219 	svLTrMaxSc.UpdF(&lay.maxScale);
220 
221 	svLTrWindFx.UpdF(&lay.windFx);
222 	svLTrWindFy.UpdF(&lay.windFy);
223 
224 	svLTrMaxTerAng.UpdF(&lay.maxTerAng);
225 	svLTrMinTerH.UpdF(&lay.minTerH);
226 	svLTrMaxTerH.UpdF(&lay.maxTerH);
227 	svLTrFlDepth.UpdF(&lay.maxDepth);
228 }
229 
chkPgLayOn(Ck *)230 void CGui::chkPgLayOn(Ck*)
231 {
232 	sc->UpdPgLayers();
233 	SetUsedStr(valLTrAll, sc->pgLayers.size(), 5);
234 }
235 
Upd3DView(String mesh)236 void CGui::Upd3DView(String mesh)
237 {
238 	viewMesh = mesh;
239 	tiViewUpd = 0.f;
240 }
241 
242 
243 //  [Road]
244 //-----------------------------------------------------------------------------------------------------------
245 
editTrkDesc(Ed ed)246 void CGui::editTrkDesc(Ed ed)
247 {
248 	app->scn->road->sTxtDesc = ed->getCaption();
249 }
250 
comboPipeMtr(Cmb cmb,size_t val)251 void CGui::comboPipeMtr(Cmb cmb, size_t val)
252 {
253 	String sn = cmb->getName().substr(String("RdMtrP").length(), cmb->getName().length());
254 	int id = atoi(sn.c_str())-1;  if (id < 0 || id >= MTRs)  return;
255 
256 	String s = cmb->getItemNameAt(val);
257 	app->scn->road->SetMtrPipe(id, s);  app->scn->road->Rebuild(true);  scn->UpdPSSMMaterials();
258 	UpdSurfList();
259 }
260 
comboRoadWMtr(Cmb cmb,size_t val)261 void CGui::comboRoadWMtr(Cmb cmb, size_t val)
262 {
263 	String s = cmb->getItemNameAt(val);
264 	app->scn->road->sMtrWall = s;  app->scn->road->Rebuild(true);  scn->UpdPSSMMaterials();
265 }
comboPipeWMtr(Cmb cmb,size_t val)266 void CGui::comboPipeWMtr(Cmb cmb, size_t val)
267 {
268 	String s = cmb->getItemNameAt(val);
269 	app->scn->road->sMtrWallPipe = s;  app->scn->road->Rebuild(true);  scn->UpdPSSMMaterials();
270 }
comboRoadColMtr(Cmb cmb,size_t val)271 void CGui::comboRoadColMtr(Cmb cmb, size_t val)
272 {
273 	String s = cmb->getItemNameAt(val);
274 	app->scn->road->sMtrCol = s;  app->scn->road->Rebuild(true);  scn->UpdPSSMMaterials();
275 }
276 
editRoad(Ed ed)277 void CGui::editRoad(Ed ed)
278 {
279 	if (!app->scn->road)  return;
280 	Real r = s2r(ed->getCaption());
281 	String n = ed->getName();
282 
283 		 if (n=="RdHeightOfs")	app->scn->road->g_Height = r;
284 	else if (n=="RdSkirtLen")	app->scn->road->g_SkirtLen = r;
285 	else if (n=="RdSkirtH")		app->scn->road->g_SkirtH = r;
286 	//app->scn->road->RebuildRoad(true);  //on Enter ?..
287 }
288 
289 //  set slider pointer values, and update
SldUpd_Road()290 void CGui::SldUpd_Road()
291 {
292 	if (!app->scn->road)  return;
293 	SplineRoad& r = *app->scn->road;
294 
295 	svRdTcMul.UpdF(&r.g_tcMul);       svRdTcMulW.UpdF(&r.g_tcMulW);
296 	svRdTcMulP.UpdF(&r.g_tcMulP);     svRdTcMulPW.UpdF(&r.g_tcMulPW);
297 	svRdTcMulC.UpdF(&r.g_tcMulC);
298 	svRdLenDim.UpdF(&r.g_LenDim0);    svRdWidthSteps.UpdI(&r.g_iWidthDiv0);
299 	svRdPwsM.UpdF(&r.g_P_iw_mul);     svRdPlsM.UpdF(&r.g_P_il_mul);
300 	svRdMergeLen.UpdF(&r.g_MergeLen); svRdLodPLen.UpdF(&r.g_LodPntLen);
301 	svRdColN.UpdI(&r.g_ColNSides);    svRdColR.UpdF(&r.g_ColRadius);
302 }
303 
304 
305 //  [Game]
306 //-----------------------------------------------------------------------------------------------------------
SldUpd_Game()307 void CGui::SldUpd_Game()
308 {
309 	svDamage.UpdF(&sc->damageMul);
310 	svWind.UpdF(&sc->windAmt);
311 	svGravity.UpdF(&sc->gravity);
312 }
comboReverbs(Cmb cmb,size_t val)313 void CGui::comboReverbs(Cmb cmb, size_t val)  // reverb sets
314 {
315 	String s = cmb->getItemNameAt(val);
316 	sc->sReverbs = s;
317 	UpdRevDescr();
318 }
UpdRevDescr()319 void CGui::UpdRevDescr()
320 {
321 	sc->UpdRevSet();
322 	txtRevebDescr->setCaption(sc->revSet.descr);
323 }
324 
325 //  Pacenotes
slUpd_Pace(SV *)326 void CGui::slUpd_Pace(SV*)
327 {
328 	scn->UpdPaceParams();
329 }
330 
chkTrkReverse(Ck *)331 void CGui::chkTrkReverse(Ck*)
332 {
333 	scn->road->Rebuild(true);
334 }
335 
336 
337 //  [Settings]  . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
338 
chkCamPos(Ck *)339 void CGui::chkCamPos(Ck*){     app->txCamPos->setVisible(pSet->camPos);  }
chkInputBar(Ck *)340 void CGui::chkInputBar(Ck*){   app->bckInput->setVisible(pSet->inputBar);  }
341 
chkFps(Ck *)342 void CGui::chkFps(Ck*){        app->bckFps->setVisible(pSet->show_fps);  }
chkWireframe(Ck *)343 void CGui::chkWireframe(Ck*){  app->UpdWireframe();  }
344 
slSizeRoadP(SV *)345 void CGui::slSizeRoadP(SV*)
346 {
347 	if (app->scn->road)
348 	{	app->scn->road->fMarkerScale = pSet->road_sphr;
349 		app->scn->road->UpdAllMarkers();  }
350 }
351 
slSizeMinimap(SV *)352 void CGui::slSizeMinimap(SV*)
353 {
354 	Real sz = pSet->size_minimap;  //int all = 0;
355 	app->asp = float(app->mWindow->getWidth()) / float(app->mWindow->getHeight());
356 	app->xm1 = 1-sz/app->asp;  app->ym1 = -1+sz;  app->xm2 = 1.0;  app->ym2 = -1.0;
357 	for (int i=0; i < app->RTs+1; ++i)  if (i != app->RTs)
358 		if (app->rt[i].mini)
359 			app->rt[i].mini->setCorners(app->xm1, app->ym1, app->xm2, app->ym2);
360 }
361 
chkMinimap(Ck *)362 void CGui::chkMinimap(Ck*)
363 {
364 	app->UpdMiniVis();
365 	if (app->ndPos)
366 		app->ndPos->setVisible(pSet->trackmap);
367 }
368 
369 
370 //  set camera in settings at exit
SaveCam()371 void App::SaveCam()
372 {
373 	if (!mCamera)  return;
374 	Vector3 p = mCamera->getPosition(), d = mCamera->getDirection();
375 	if (gui->bTopView)  {  p = gui->oldPos;  d = gui->oldRot;  }
376 	pSet->cam_x  = p.x;  pSet->cam_y  = p.y;  pSet->cam_z  = p.z;
377 	pSet->cam_dx = d.x;  pSet->cam_dy = d.y;  pSet->cam_dz = d.z;
378 }
379 
380 //  set predefined camera view
btnSetCam(WP wp)381 void CGui::btnSetCam(WP wp)
382 {
383 	String s = wp->getName();
384 	Real y0 = 20, xz = sc->td.fTerWorldSize*0.5f, r = 45.f * 0.5f*PI_d/180.f, yt = xz / Math::Tan(r);
385 	Camera* cam = app->mCamera;
386 
387 		 if (s=="CamView1")	{	cam->setPosition(xz*0.8,60,0);  cam->setDirection(-1,-0.3,0);  }
388 	else if (s=="CamView2")	{	cam->setPosition(xz*0.6,80,xz*0.6);  cam->setDirection(-1,-0.5,-1);  }
389 	else if (s=="CamView3")	{	cam->setPosition(-xz*0.7,80,-xz*0.5);  cam->setDirection(0.8,-0.5,0.5);  }
390 	else if (s=="CamView4")	{
391 		Vector3 cp = app->ndCar->getPosition();  float cy = app->ndCar->getOrientation().getYaw().valueRadians();
392 		Vector3 cd = Vector3(cosf(cy),0,-sinf(cy));
393 		cam->setPosition(cp - cd * 15 + Vector3(0,7,0));  cd.y = -0.3f;
394 		cam->setDirection(cd);  }
395 
396 	else if (s=="CamTop")	{	cam->setPosition(0,yt,0);  cam->setDirection(-0.0001,-1,0);  }
397 	else if (s=="CamLeft")	{	cam->setPosition(0,y0, xz);  cam->setDirection(0,0,-1);  }
398 	else if (s=="CamRight")	{	cam->setPosition(0,y0,-xz);  cam->setDirection(0,0, 1);  }
399 	else if (s=="CamFront")	{	cam->setPosition( xz,y0,0);  cam->setDirection(-1,0,0);  }
400 	else if (s=="CamBack")	{	cam->setPosition(-xz,y0,0);  cam->setDirection( 1,0,0);  }
401 }
402 
403 //  toggle top view camera
toggleTopView()404 void CGui::toggleTopView()
405 {
406 	bTopView = !bTopView;
407 	Camera* cam = app->mCamera;
408 
409 	if (bTopView)
410 	{	// store old
411 		oldPos = cam->getPosition();
412 		oldRot = cam->getDirection();
413 
414 		Real xz = sc->td.fTerWorldSize*0.5f, r = 45.f * 0.5f*PI_d/180.f, yt = xz / Math::Tan(r);
415 		cam->setPosition(0,yt,0);  cam->setDirection(-0.0001,-1,0);
416 
417 		oldFog = pSet->bFog;
418 		pSet->bFog = true;  ckFog.Upd();  scn->UpdFog();
419 	}else
420 	{	// restore
421 		cam->setPosition(oldPos);
422 		cam->setDirection(oldRot);
423 
424 		pSet->bFog = oldFog;  ckFog.Upd();  scn->UpdFog();
425 	}
426 }
427 
428 
429 //  [Surface]
430 //-----------------------------------------------------------------------------------------------------------
431 
GetTerRdLay()432 TerLayer* CGui::GetTerRdLay()
433 {
434 	if (idSurf < 4)  //  terrain
435 	{	if (idSurf >= sc->td.layers.size())  // could change by on/off ter layers
436 		{	idSurf = 0;  if (surfList)  surfList->setIndexSelected(idSurf);  }
437 		return &sc->td.layersAll[sc->td.layers[idSurf]];
438 	}
439 	//  road
440 	return  &sc->td.layerRoad[sc->td.road1mtr ? 0 : idSurf-4];
441 }
442 
listSurf(Li,size_t id)443 void CGui::listSurf(Li, size_t id)
444 {
445 	if (id == ITEM_NONE) {  id = 0;  surfList->setIndexSelected(0);  }
446 	if (id < 4 && id >= sc->td.layers.size()) {  id = 0;  surfList->setIndexSelected(id);  }  // more than used
447 	if (id >= 8) {  id = 4;  surfList->setIndexSelected(id);  }
448 	//TODO: own pipe mtrs..
449 
450 	idSurf = id;  // help var
451 	TerLayer* l = GetTerRdLay();
452 	SldUpd_Surf();
453 
454 	Vector3 c;  c = l->tclr.GetRGB1();
455 	clrTrail->setColour(Colour(c.x, c.y, c.z));
456 
457 	//  Surface
458 	cmbSurface->setIndexSelected( cmbSurface->findItemIndexWith(l->surfName));
459 	UpdSurfInfo();
460 }
461 
SldUpd_Surf()462 void CGui::SldUpd_Surf()
463 {
464 	TerLayer* l = GetTerRdLay();
465 
466 	svLDust.UpdF(&l->dust);  svLDustS.UpdF(&l->dustS);
467 	svLMud.UpdF(&l->mud);    svLSmoke.UpdF(&l->smoke);
468 }
469 
UpdSurfList()470 void CGui::UpdSurfList()
471 {
472 	if (!surfList || surfList->getItemCount() != 12)  return;
473 
474 	for (int n=0; n < 4; ++n)
475 	{
476 		String s = n >= app->scn->sc->td.layers.size() ? "" : StringUtil::replaceAll(
477 			app->scn->sc->td.layersAll[app->scn->sc->td.layers[n]].texFile, "_d.jpg","");
478 		surfList->setItemNameAt(n  , "#80FF00"+TR("#{Layer} ")+toStr(n+1)+"  "+ s);
479 		surfList->setItemNameAt(n+4, "#FFB020"+TR("#{Road} ") +toStr(n+1)+"  "+ app->scn->road->sMtrRoad[n]);
480 		surfList->setItemNameAt(n+8, "#FFFF80"+TR("#{Pipe} ") +toStr(n+1)+"  "+ app->scn->road->sMtrPipe[n]);
481 	}
482 	GetTerRdLay();  // fix list pos if cur gone
483 }
484 
485 //  upd ed info txt
UpdEdInfo()486 void CGui::UpdEdInfo()
487 {
488 	int t = scn->sc->secEdited;
489 	ostringstream s;  s.fill('0');
490 	s << fixed << "#C0F0F8" << t/3600 << ":#A0D8E0" << setw(2) << t/60%60 << ":#70A8B0" << setw(2) << t%60;
491 	txtEdInfo->setCaption(
492 		TR("#A0C0D0#{Time} [h:m:s]: ") + s.str()+"\n"+
493 		TR("#808080Base track: ") + scn->sc->baseTrk);
494 }
495 
496 
497 //-----------------------------------------------------------------------------------------------------------
498 ///  [Pick window]
499 //-----------------------------------------------------------------------------------------------------------
liNext(Mli2 li,int rel)500 int CGui::liNext(Mli2 li, int rel)
501 {
502 	int cnt = li->getItemCount()-1;
503 	if (cnt < 0)  return 0;
504 	int i = li->getIndexSelected();
505 	if (i == ITEM_NONE)  i = 0;
506 	i += rel;  if (i<0) i=0;  if (i>cnt) i=cnt;
507 	li->setIndexSelected(i);
508 	li->beginToItemAt(std::min(cnt, std::max(0, i-20)));
509 	return i;
510 }
511 
keyPickNext(int r)512 void CGui::keyPickNext(int r)
513 {
514 	if (liSky->getVisible())  listPickSky(liSky, liNext(liSky, r));  else
515 	if (liTex->getVisible())  listPickTex(liTex, liNext(liTex, r));	 else
516 	if (liGrs->getVisible())  listPickGrs(liGrs, liNext(liGrs, r));  else
517 	if (liVeg->getVisible())  listPickVeg(liVeg, liNext(liVeg, r));  else
518 	if (liRd->getVisible())   listPickRd(liRd, liNext(liRd, r));
519 }
520 
wheelSky(WP wp,int rel)521 void CGui::wheelSky(WP wp, int rel){  int r = rel < 0 ? 1 : -1;  listPickSky(liSky, liNext(liSky, r));  }
wheelTex(WP wp,int rel)522 void CGui::wheelTex(WP wp, int rel){  int r = rel < 0 ? 1 : -1;  listPickTex(liTex, liNext(liTex, r));  }
wheelGrs(WP wp,int rel)523 void CGui::wheelGrs(WP wp, int rel){  int r = rel < 0 ? 1 : -1;  listPickGrs(liGrs, liNext(liGrs, r));  }
wheelVeg(WP wp,int rel)524 void CGui::wheelVeg(WP wp, int rel){  int r = rel < 0 ? 1 : -1;  listPickVeg(liVeg, liNext(liVeg, r));  }
wheelRd(WP wp,int rel)525 void CGui::wheelRd(WP wp, int rel)
526 {
527 	String sn = wp->getName().substr(String("RdMtr").length(), wp->getName().length());
528 	idRdPick = atoi(sn.c_str())-1;
529 	int r = rel < 0 ? 1 : -1;  listPickRd(liRd, liNext(liRd, r));
530 }
531 
btnPickSky(WP)532 void CGui::btnPickSky(WP){    PickShow(P_Sky);  }
btnPickTex(WP)533 void CGui::btnPickTex(WP){    PickShow(P_Tex);  }
btnPickGrass(WP)534 void CGui::btnPickGrass(WP){  PickShow(P_Grs);  }
btnPickVeget(WP)535 void CGui::btnPickVeget(WP){  PickShow(P_Veg);  }
btnPickRoad(WP wp)536 void CGui::btnPickRoad(WP wp)
537 {	if (!wp) {
538 		PickShow(P_Rd, true);  return;  }
539 	String sn = wp->getName().substr(String("RdMtr").length(), wp->getName().length());
540 	int idRdOld = idRdPick;  idRdPick = atoi(sn.c_str())-1;
541 	PickShow(P_Rd, idRdOld==idRdPick);
542 }
543 
544 //  show Pick window
PickShow(EPick n,bool toggleVis)545 void CGui::PickShow(EPick n, bool toggleVis)
546 {
547 	liSky->setVisible(n==P_Sky);  liTex->setVisible(n==P_Tex);
548 	liGrs->setVisible(n==P_Grs);  liVeg->setVisible(n==P_Veg);  liRd->setVisible(n==P_Rd);
549 	panPick->setPosition(liPickW[n], 36);
550 
551 	const int wx = pSet->windowx, wy = pSet->windowy;
552 	//if (pSet->pick_center
553 	switch (n)  ///pick dim
554 	{
555 		case P_Sky:  app->mWndPick->setCoord(wx*0.45f, 0.04f*wy, 300, 0.95f*wy);  break;
556 		case P_Tex:  app->mWndPick->setCoord(wx*0.45f, 0.04f*wy, 300, 0.95f*wy);  break;
557 		case P_Grs:  app->mWndPick->setCoord(wx*0.36f, 0.04f*wy, 280, 0.95f*wy);  break;
558 		case P_Veg:  app->mWndPick->setCoord(wx*0.36f, 0.04f*wy, 300, 0.95f*wy);  break;
559 		case P_Rd:   app->mWndPick->setCoord(wx*0.36f, 0.04f*wy, 300, 0.95f*wy);  break;
560 	}
561 	if (n==P_Rd)  // upd pick road
562 	{	UString s = btnRoad[idRdPick]->getCaption();
563 		for (int i=0; i < liRd->getItemCount(); ++i)
564 			if (liRd->getSubItemNameAt(1,i).substr(7) == s)
565 				liRd->setIndexSelected(i);
566 	}
567 
568 	bool vis = app->mWndPick->getVisible();
569 	if (n != P_Rd || toggleVis || !vis)
570 		app->mWndPick->setVisible(!vis);
571 }
572 
573 
574 ///  Sky Mtr  ----------------------------------------------------
listPickSky(Mli2 li,size_t pos)575 void CGui::listPickSky(Mli2 li, size_t pos)
576 {
577 	if (pos==ITEM_NONE || pos >= data->pre->sky.size())
578 	{	liSky->setIndexSelected(0);  pos = 0;  }
579 
580 	string s = liSky->getSubItemNameAt(1,pos);
581 	s = "sky/" + s.substr(7);
582 	const PSky* p = data->pre->GetSky(s);  if (!p)  return;
583 
584 	//  set
585 	sc->skyMtr = p->mtr;
586 	if (pSet->pick_setpar)
587 	{	sc->ldPitch = p->ldPitch;  svSunPitch.Upd();
588 		sc->ldYaw = p->ldYaw;  svSunYaw.Upd();
589 		scn->UpdSun();
590 	}
591 	//  upd img
592 	btnSky->setCaption(s);
593 	app->UpdateTrack();
594 }
595 
596 ///  Tex Diff  ----------------------------------------------------
listPickTex(Mli2 li,size_t pos)597 void CGui::listPickTex(Mli2 li, size_t pos)
598 {
599 	if (pos==ITEM_NONE || pos >= data->pre->ter.size())
600 	{	liTex->setIndexSelected(0);  pos = 0;  }
601 
602 	string s = liTex->getSubItemNameAt(1,pos);
603 	s = s.substr(7) + "_d";  // rem #clr
604 	const PTer* p = data->pre->GetTer(s);  if (!p)  return;
605 	s += ".jpg";
606 
607 	//  set
608 	TerLayer& l = sc->td.layersAll[idTerLay];
609 	l.texFile = s;
610 
611 	//  auto norm
612 	{	String sNorm; //old = StringUtil::replaceAll(s,"_d.","_n.");  //_T
613 		sNorm = p->texNorm+".jpg";
614 
615 		//  preset
616 		if (pSet->pick_setpar)
617 		{	l.tiling = p->tiling;  svTerLScale.Upd();
618 			l.triplanar = p->triplanar;  ckTerLayTripl.Upd();
619 			//angMin angMax
620 			l.surfName = p->surfName;
621 			l.dust = p->dust;  l.dustS = p->dustS;
622 			l.mud = p->mud;  l.tclr = p->tclr;
623 			l.fDamage = p->dmg;  svTerLDmg.Upd();
624 			listSurf(surfList, idSurf);
625 		}
626 
627 		size_t id = cmbTexNorm->findItemIndexWith(sNorm);
628 		if (id != ITEM_NONE)  // set only if found
629 		{
630 			cmbTexNorm->setIndexSelected(id);
631 			l.texNorm = sNorm;
632 	}	}
633 
634 	//  upd img
635 	btnTexDiff->setCaption(s.substr(0, s.length()-6));  // rem _d.jpg
636     imgTexDiff->setImageTexture(s);
637 	UpdSurfList();
638 }
639 
640 ///  Grass  -------------------------------------------------------
listPickGrs(Mli2 li,size_t pos)641 void CGui::listPickGrs(Mli2 li, size_t pos)
642 {
643 	if (pos==ITEM_NONE || pos >= data->pre->gr.size())
644 	{	liGrs->setIndexSelected(0);  pos = 0;  }
645 
646 	string s = liGrs->getSubItemNameAt(1,pos);
647 	s = s.substr(7);
648 	const PGrass* p = data->pre->GetGrass(s);
649 
650 	//  set
651 	SGrassLayer& l = sc->grLayersAll[idGrLay];
652 	l.material = s;
653 
654 	//  preset
655 	if (pSet->pick_setpar && p)
656 	{	l.minSx = p->minSx;  svGrMinX.Upd();
657 		l.maxSx = p->maxSx;  svGrMaxX.Upd();
658 		l.minSy = p->minSy;  svGrMinY.Upd();
659 		l.maxSy = p->maxSy;  svGrMaxY.Upd();
660 	}
661 	//  upd img
662 	btnGrassMtr->setCaption(s);
663 	imgGrass->setImageTexture(s + ".png");  // same mtr name as tex
664 }
665 
666 ///  Veget Model  -------------------------------------------------
listPickVeg(Mli2 li,size_t pos)667 void CGui::listPickVeg(Mli2 li, size_t pos)
668 {
669 	if (pos==ITEM_NONE || pos >= data->pre->veg.size())
670 	{	liVeg->setIndexSelected(0);  pos = 0;  }
671 
672 	string s = liVeg->getSubItemNameAt(1,pos);
673 	s = s.substr(7);
674 	const PVeget* p = data->pre->GetVeget(s);
675 
676 	//  upd
677 	btnVeget->setCaption(s);
678 	s += ".mesh";
679 
680 	//  set
681 	PagedLayer& l = sc->pgLayersAll[idPgLay];
682 	l.name = s;
683 
684 	//  preset
685 	if (pSet->pick_setpar && p)
686 	{	l.minScale = p->minScale;  svLTrMinSc.Upd();
687 		l.maxScale = p->maxScale;  svLTrMaxSc.Upd();
688 		l.windFx = p->windFx;  svLTrWindFx.Upd();
689 		l.windFy = p->windFy;  svLTrWindFy.Upd();
690 		l.maxTerAng = p->maxTerAng;  svLTrMaxTerAng.Upd();
691 		l.maxDepth = p->maxDepth;  svLTrFlDepth.Upd();
692 		l.addRdist = p->addRdist;  svLTrRdDist.Upd();
693 	}
694 	Upd3DView(s);
695 }
696 
697 ///  Road  -------------------------------------------------
listPickRd(Mli2 li,size_t pos)698 void CGui::listPickRd(Mli2 li, size_t pos)
699 {
700 	if (pos==ITEM_NONE || pos > data->pre->rd.size())
701 	{	liRd->setIndexSelected(0);  pos = 0;  }
702 
703 	string s = liRd->getSubItemNameAt(1,pos);
704 	s = s.substr(7);
705 	const PRoad* p = data->pre->GetRoad(s);
706 
707 	//  set
708 	scn->road->sMtrRoad[idRdPick] = s;
709 	//  preset
710 	if (pSet->pick_setpar && p)
711 	{	TerLayer& l = scn->sc->td.layerRoad[idRdPick];
712 		l.surfName = p->surfName;
713 		l.dust = p->dust;  l.dustS = p->dustS;
714 		l.mud = p->mud;  l.tclr = p->tclr;
715 		listSurf(surfList, idSurf);
716 	}
717 	//  upd
718 	btnRoad[idRdPick]->setCaption(s);
719 	app->scn->road->Rebuild(true);  scn->UpdPSSMMaterials();
720 	UpdSurfList();
721 }
722