1 #include "pch.h"
2 #include "../ogre/common/Def_Str.h"
3 #include "../ogre/common/data/CData.h"
4 #include "../ogre/common/ShapeData.h"
5 #include "../ogre/common/GuiCom.h"
6 #include "../ogre/common/CScene.h"
7 #include "settings.h"
8 #include "CApp.h"
9 #include "CGui.h"
10 #include "../road/Road.h"
11 #include "../road/PaceNotes.h"
12 #include "../paged-geom/PagedGeometry.h"
13 #include "../vdrift/pathmanager.h"
14 #include "../ogre/common/RenderConst.h"
15 #include "btBulletCollisionCommon.h"
16 #include "btBulletDynamicsCommon.h"
17 #include "../shiny/Main/Factory.hpp"
18 
19 #include <OgreTimer.h>
20 #include <OgreTerrain.h>
21 #include <OgreTerrainGroup.h>
22 #include <OgreRenderWindow.h>
23 #include <OgreOverlay.h>
24 #include <OgreOverlayElement.h>
25 #include <OgreMeshManager.h>
26 #include <OgreParticleSystem.h>
27 #include <OgreParticleEmitter.h>
28 #include <OgreManualObject.h>
29 #include <OgreViewport.h>
30 #include <OgreMaterialManager.h>
31 #include <OgreTextureManager.h>
32 #include <OgreSceneNode.h>
33 #include "../ogre/common/MessageBox/MessageBox.h"
34 #include "../ogre/common/Instancing.h"
35 using namespace Ogre;
36 
37 
38 //  Create Scene
39 //-------------------------------------------------------------------------------------
createScene()40 void App::createScene()  // once, init
41 {
42 	//  prv tex
43 	int k=1024;
44 	prvView.Create(k,k,"PrvView");
45 	prvRoad.Create(k,k,"PrvRoad");
46 	 prvTer.Create(k,k,"PrvTer");
47 
48 	scn->roadDens.Create(k+1,k+1,"RoadDens");
49 
50 	///  ter lay tex
51 	for (int i=0; i < 6; ++i)
52 	{	String si = toStr(i);
53 		scn->texLayD[i].SetName("layD"+si);
54 		scn->texLayN[i].SetName("layN"+si);
55 	}
56 
57 
58 	//  camera
59 	asp = float(mWindow->getWidth())/float(mWindow->getHeight());
60 	mCamera->setFarClipDistance(pSet->view_distance*1.1f);
61 	mCamera->setNearClipDistance(0.1f);
62 
63 	//  cam pos from last set
64 	mCamera->setPosition(Vector3(pSet->cam_x,pSet->cam_y,pSet->cam_z));
65 	mCamera->setDirection(Vector3(pSet->cam_dx,pSet->cam_dy,pSet->cam_dz).normalisedCopy());
66 	mViewport->setVisibilityMask(RV_MaskAll);  // hide prv cam rect
67 
68 	//  tex fil
69 	MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC);
70 	MaterialManager::getSingleton().setDefaultAnisotropy(pSet->anisotropy);
71 
72 	Ogre::Timer ti;
73 
74 
75 	//  data load xml
76 	scn->data->Load();
77 	scn->sc->pFluidsXml = scn->data->fluids;
78 	scn->sc->pReverbsXml = scn->data->reverbs;
79 
80 	//  surfaces.cfg
81 	LoadAllSurfaces();
82 
83 	LogO(String("::: Time load xmls: ") + fToStr(ti.getMilliseconds(),0,3) + " ms");
84 
85 
86 	postInit();  // material factory
87 
88 	//  gui  * * *
89 	if (pSet->startInMain)
90 		pSet->isMain = true;
91 
92 	bGuiFocus = false/*true*/;  bMoveCam = true;  //*--
93 
94 	gui->InitGui();
95 
96 
97 	///__  All  #if 0  in Release !!!
98 
99 	///  _Tool_ scene  ...................
100 	#if 0
101 	gui->ToolSceneXml();
102 	exit(0);
103 	#endif
104 
105 	///  _Tool_	warnings  ................
106 	///  takes some time
107 	#if 0
108 	gui->ToolTracksWarnings();
109 	exit(0);
110 	#endif
111 
112 
113 	TerCircleInit();
114 	createBrushPrv();
115 
116 	///  _Tool_ brushes prv  .............
117 	#if 0
118 	gui->ToolBrushesPrv();
119 	#endif
120 
121 
122 	//  load
123 	if (pSet->autostart)
124 		LoadTrack();
125 
126 	if (!pSet->autostart)
127 	{	bGuiFocus = true;  UpdVisGui();	}
128 
129 	iObjTNew = 0;
130 	//SetObjNewType(0);  //?white
131 
132 
133 	gui->chkInputBar(0);  // upd vis
134 	gui->chkCamPos(0);
135 	gui->chkFps(0);
136 }
137 
destroyScene()138 void App::destroyScene()
139 {
140 	scn->destroyScene();
141 }
142 
143 
144 //---------------------------------------------------------------------------------------------------------------
145 ///  Load Track
146 //---------------------------------------------------------------------------------------------------------------
147 
148 //  destroy
NewCommon(bool onlyTerVeget)149 void App::NewCommon(bool onlyTerVeget)
150 {
151 	//  destroy all
152 	if (ndSky)
153 		mSceneMgr->destroySceneNode(ndSky);
154 
155 	if (inst) {  delete inst;  inst=0;  }
156 
157 	scn->DestroyTrees();
158 
159 	if (!onlyTerVeget)
160 		scn->DestroyWeather();
161 
162 	mSceneMgr->destroyAllStaticGeometry();
163 	mStaticGeom = 0;
164 	DestroyVdrTrackBlt();
165 
166 	if (!onlyTerVeget)
167 	{
168 		DestroyObjects(true);
169 		scn->DestroyFluids();
170 	}
171 
172 	scn->DestroyTerrain();
173 
174 	//world.Clear();
175 	if (track)  track->Clear();
176 
177 	if (resTrk != "")  mRoot->removeResourceLocation(resTrk);
178 	LogO("------  Loading track: "+pSet->gui.track);
179 	resTrk = gcom->TrkDir() + "objects";
180 	mRoot->addResourceLocation(resTrk, "FileSystem");
181 
182 	MeshManager::getSingleton().unloadUnreferencedResources();
183 	sh::Factory::getInstance().unloadUnreferencedMaterials();
184 	TextureManager::getSingleton().unloadUnreferencedResources();
185 }
186 
187 ///  Load
188 //---------------------------------------------------------------------------------------------------------------
LoadTrack()189 void App::LoadTrack()
190 {
191 	eTrkEvent = TE_Load;
192 	gui->Status("#{Loading}...", 0.3,0.6,1.0);
193 }
LoadTrackEv()194 void App::LoadTrackEv()
195 {
196 	Ogre::Timer ti;
197 	NewCommon(false);  // full destroy
198 	iObjCur = -1;
199 
200 	scn->DestroyRoad();
201 	scn->DestroyPace();
202 
203 
204 	// load scene
205 	scn->sc->LoadXml(gcom->TrkDir()+"scene.xml");
206 	scn->sc->vdr = IsVdrTrack();
207 	if (scn->sc->vdr)  scn->sc->ter = false;
208 
209 	//  water RTT recreate
210 	scn->UpdateWaterRTT(mCamera);
211 
212 	BltWorldInit();
213 
214 	UpdWndTitle();
215 
216 	scn->CreateFluids();
217 
218 	scn->CreateWeather();
219 
220 
221 	//  set sky tex name for water
222 	sh::MaterialInstance* m = mFactory->getMaterialInstance(scn->sc->skyMtr);
223 	std::string skyTex = sh::retrieveValue<sh::StringValue>(m->getProperty("texture"), 0).get();
224 	sh::Factory::getInstance().setTextureAlias("SkyReflection", skyTex);
225 	sh::Factory::getInstance().setTextureAlias("CubeReflection", "ReflectionCube");
226 
227 
228 	bNewHmap = false;/**/
229 	scn->CreateTerrain(bNewHmap, scn->sc->ter);
230 
231 	if (track)
232 	if (scn->sc->vdr)  // vdrift track
233 	{
234 		if (!LoadTrackVdr(pSet->gui.track))
235 			LogO("Error during track loading: " + pSet->gui.track);
236 
237 		CreateVdrTrack(pSet->gui.track, track);
238 		CreateVdrTrackBlt();
239 	}
240 
241 
242 	//  road ~
243 	scn->road = new SplineRoad(this);
244 	scn->road->Setup("sphere.mesh", pSet->road_sphr, scn->terrain, mSceneMgr, mCamera);
245 	scn->road->LoadFile(gcom->TrkDir()+"road.xml");
246 	scn->UpdPSSMMaterials();
247 
248 	//  pace ~ ~
249 	scn->pace = new PaceNotes(pSet);
250 	scn->pace->Setup(mSceneMgr, mCamera, scn->terrain, gui->mGui, mWindow);
251 
252 
253 	/// HW_Inst Test  * * *
254 	//inst = new Instanced();
255 	//inst->Create(mSceneMgr,"sphere_inst.mesh");
256 
257 
258 	CreateObjects();
259 
260 	if (pSet->bTrees && scn->sc->ter)
261 		scn->CreateTrees();  // trees after objects so they aren't inside them
262 
263 
264 	//  updates after load
265 	//--------------------------
266 	gcom->ReadTrkStats();
267 	gui->SetGuiFromXmls();  ///
268 
269 	Rnd2TexSetup();
270 	//UpdVisGui();
271 	//UpdStartPos();
272 	UpdEditWnds();  //
273 
274 	try {
275 	TexturePtr tex = TextureManager::getSingleton().getByName("waterDepth.png");
276 	if (!tex.isNull())
277 		tex->reload();
278 	} catch(...) {  }
279 
280 	gui->Status("#{Loaded}", 0.5,0.7,1.0);
281 
282 	if (pSet->check_load)
283 		gui->WarningsCheck(scn->sc, scn->road);
284 
285 	LogO(String("::: Time Load Track: ") + fToStr(ti.getMilliseconds(),0,3) + " ms");
286 }
287 
288 
289 ///  Update
290 //---------------------------------------------------------------------------------------------------------------
UpdateTrack()291 void App::UpdateTrack()
292 {
293 	eTrkEvent = TE_Update;
294 	gui->Status("#{Updating}...", 0.2,1.0,0.5);
295 }
UpdateTrackEv()296 void App::UpdateTrackEv()
297 {
298 	if (!bNewHmap)
299 		scn->copyTerHmap();
300 
301 	NewCommon(true);  // destroy only terrain and veget
302 
303 	//CreateFluids();
304 	scn->CreateTerrain(bNewHmap,true,false);/**/
305 
306 	//  road ~
307 	scn->road->mTerrain = scn->terrain;
308 	scn->road->Rebuild(true);
309 	scn->UpdPSSMMaterials();
310 
311 	//CreateObjects();
312 
313 	if (pSet->bTrees)
314 		scn->CreateTrees();
315 
316 	Rnd2TexSetup();
317 
318 	gui->Status("#{Updated}", 0.5,1.0,0.7);
319 }
320 
321 //  Update btns  ---
btnUpdateLayers(WP)322 void CGui::btnUpdateLayers(WP)
323 {
324 	if (!app->bNewHmap)
325 		app->scn->copyTerHmap();
326 	if (app->ndSky)
327 		app->mSceneMgr->destroySceneNode(app->ndSky);
328 	app->scn->DestroyTerrain();
329 
330 	app->scn->CreateTerrain(app->bNewHmap,true,false);
331 	scn->road->mTerrain = scn->terrain;
332 	app->scn->updGrsTer();
333 }
334 
btnUpdateGrass(WP)335 void CGui::btnUpdateGrass(WP)  // TODO: grass only ...
336 {
337 	scn->DestroyTrees();
338 	if (pSet->bTrees)
339 		scn->CreateTrees();
340 }
341 
btnUpdateVeget(WP)342 void CGui::btnUpdateVeget(WP)
343 {
344 	scn->DestroyTrees();
345 	if (pSet->bTrees)
346 		scn->CreateTrees();
347 }
348 
349 
350 ///  Save
351 //---------------------------------------------------------------------------------------------------------------
SaveTrack()352 void App::SaveTrack()
353 {
354 	if (!pSet->allow_save)  // can force it when in writable location
355 	if (!pSet->gui.track_user)
356 	{	MyGUI::Message::createMessageBox(
357 			"Message", TR("#{Track} - #{RplSave}"), TR("#{CantSaveOrgTrack}"),
358 			MyGUI::MessageBoxStyle::IconWarning | MyGUI::MessageBoxStyle::Ok);
359 		return;
360 	}
361 	eTrkEvent = TE_Save;
362 	gui->Status("#{Saving}...", 1,0.4,0.1);
363 
364 	if (pSet->check_save)
365 		gui->WarningsCheck(scn->sc, scn->road);
366 }
SaveTrackEv()367 void App::SaveTrackEv()
368 {
369 	String dir = gcom->TrkDir();
370 	//  track dir in user
371 	gui->CreateDir(dir);
372 	gui->CreateDir(dir+"/objects");
373 
374 	//  todo: save only what changed ...
375 	if (scn->terrain)
376 	{	float *fHmap = scn->terrain->getHeightData();
377 		int size = scn->sc->td.iVertsX * scn->sc->td.iVertsY * sizeof(float);
378 
379 		String file = dir+"heightmap.f32";
380 		std::ofstream of;
381 		of.open(file.c_str(), std::ios_base::binary);
382 		of.write((const char*)fHmap, size);
383 		of.close();
384 	}
385 	if (scn->road)
386 		scn->road->SaveFile(dir+"road.xml");
387 
388 	scn->sc->SaveXml(dir+"scene.xml");
389 
390 	bool vdr = IsVdrTrack();
391 	/*if (!vdr)*/  SaveGrassDens();
392 	if (!vdr)  SaveWaterDepth();  //?-
393 
394 	gui->Delete(gui->getHMapNew());
395 	gui->Status("#{Saved}", 1,0.6,0.2);
396 }
397 
398 
399 ///  Ter Circle mesh   o
400 //-------------------------------------------------------------------------------------
401 const int divs = 90;
402 const Real aAdd = 2 * 2*PI_d / divs, dTc = 2.f/(divs+1) *4;
403 static Real fTcos[divs+4], fTsin[divs+4];
404 
405 
TerCircleInit()406 void App::TerCircleInit()
407 {
408 	moTerC = mSceneMgr->createManualObject();
409 	moTerC->setDynamic(true);
410 	moTerC->setCastShadows(false);
411 
412 	moTerC->estimateVertexCount(divs+2);
413 	moTerC->estimateIndexCount(divs+2);
414 	moTerC->begin("circle_deform", RenderOperation::OT_TRIANGLE_STRIP);
415 
416 	for (int d = 0; d < divs+2; ++d)
417 	{
418 		Real a = d/2 * aAdd;	fTcos[d] = cosf(a);  fTsin[d] = sinf(a);
419 		Real r = (d % 2 == 0) ? 1.f : 0.9f;
420 		Real x = r * fTcos[d], z = r * fTsin[d];
421 		moTerC->position(x,0,z);  //moTerC->normal(0,1,0);
422 		moTerC->textureCoord(d/2*dTc, d%2);
423 	}
424 	moTerC->end();
425 
426 	AxisAlignedBox aab;  aab.setInfinite();
427 	moTerC->setBoundingBox(aab);  // always visible
428 	moTerC->setRenderQueueGroup(RQG_Hud2);
429 	moTerC->setVisibilityFlags(RV_Hud);
430 	ndTerC = mSceneMgr->getRootSceneNode()->createChildSceneNode(Vector3(0,0,0));
431 	ndTerC->attachObject(moTerC);  ndTerC->setVisible(false);
432 }
433 
434 
TerCircleUpd()435 void App::TerCircleUpd()
436 {
437 	if (!moTerC || !scn->terrain || !scn->road)  return;
438 
439 	bool edTer = bEdit() && (edMode < ED_Road) && scn->road->bHitTer;
440 	ndTerC->setVisible(edTer);
441 	if (!edTer)  return;
442 
443 	Real rbr = mBrSize[curBr] * 0.5f * scn->sc->td.fTriangleSize * 0.8f/*?par*/;
444 
445 	static ED_MODE edOld = ED_ALL;
446 	if (edOld != edMode)
447 	{	edOld = edMode;
448 		switch(edMode)
449 		{
450 		case ED_Deform: moTerC->setMaterialName(0, "circle_deform");  break;
451 		case ED_Filter: moTerC->setMaterialName(0, "circle_filter");  break;
452 		case ED_Smooth: moTerC->setMaterialName(0, "circle_smooth");  break;
453 		case ED_Height: moTerC->setMaterialName(0, "circle_height");  break;
454 		}
455 	}
456 	moTerC->beginUpdate(0);
457 	for (int d = 0; d < divs+2; ++d)
458 	{
459 		Real a = d/2 * aAdd;
460 		Real r = ((d % 2 == 0) ? 1.0f : 0.95f) * rbr;
461 		Real x = r * fTcos[d], z = r * fTsin[d];
462 		Vector3 p(x,0,z);  p += scn->road->posHit;
463 		p.y = scn->terrain->getHeightAtWorldPosition(p) + 0.3f;
464 		moTerC->position(p);  //moTerC->normal(0,1,0);
465 		moTerC->textureCoord(d/2*dTc, d%2);
466 	}
467 	moTerC->end();
468 }
469 
470 
471 //  vdrift track load
472 //-------------------------------------------------------------------------------------
LoadTrackVdr(const std::string & trackname)473 bool App::LoadTrackVdr(const std::string & trackname)
474 {
475 	if (!track->DeferredLoad(
476 		(pSet->gui.track_user ? PATHMANAGER::TracksUser() : PATHMANAGER::Tracks()) + "/" + trackname,
477 		false/*trackreverse*/,
478 		/**/0, "large", true, false))
479 	{
480 		LogO("Error loading vdrift track: "+trackname);
481 		return false;
482 	}
483 	bool success = true;
484 	while (!track->Loaded() && success)
485 	{
486 		success = track->ContinueDeferredLoad();
487 	}
488 
489 	if (!success)
490 	{
491 		LogO("Error loading vdrift track: "+trackname);
492 		return false;
493 	}
494 	return true;
495 }
496 
497 
498 //---------------------------------------------------------------------------------------------------------------
499 ///  Bullet world
500 //---------------------------------------------------------------------------------------------------------------
BltWorldInit()501 void App::BltWorldInit()
502 {
503 	if (world)  // create world once
504 		return;
505 		//BltWorldDestroy();
506 
507 	//  setup bullet world
508 	config = new btDefaultCollisionConfiguration();
509 	dispatcher = new btCollisionDispatcher(config);
510 
511 	btScalar ws = 5000;  // world size
512 	broadphase = new bt32BitAxisSweep3(btVector3(-ws,-ws,-ws), btVector3(ws,ws,ws));
513 	solver = new btSequentialImpulseConstraintSolver();
514 	world = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, config);
515 
516 	world->setGravity(btVector3(0.0, 0.0, -9.81)); ///~
517 	world->getSolverInfo().m_restitution = 0.0f;
518 	world->getDispatchInfo().m_enableSPU = true;
519 	world->setForceUpdateAllAabbs(false);  //+
520 }
521 
BltWorldDestroy()522 void App::BltWorldDestroy()
523 {
524 	BltClear();
525 
526 	delete world;  delete solver;
527 	delete broadphase;  delete dispatcher;  delete config;
528 }
529 
530 //  Clear - delete bullet pointers
BltClear()531 void App::BltClear()
532 {
533 	//track = NULL;
534 	DestroyVdrTrackBlt();
535 
536 	if (world)
537 	for(int i = world->getNumCollisionObjects() - 1; i >= 0; i--)
538 	{
539 		btCollisionObject* obj = world->getCollisionObjectArray()[i];
540 		btRigidBody* body = btRigidBody::upcast(obj);
541 		if (body && body->getMotionState())
542 		{
543 			delete body->getMotionState();
544 		}
545 		world->removeCollisionObject(obj);
546 
547 		ShapeData* sd = (ShapeData*)obj->getUserPointer();
548 		delete sd;  delete obj;
549 	}
550 
551 	/*for (int i = 0; i < shapes.size(); i++)
552 	{
553 		btCollisionShape * shape = shapes[i];
554 		if (shape->isCompound())
555 		{
556 			btCompoundShape * cs = (btCompoundShape *)shape;
557 			for (int i = 0; i < cs->getNumChildShapes(); i++)
558 			{
559 				delete cs->getChildShape(i);
560 			}
561 		}
562 		delete shape;
563 	}
564 	shapes.resize(0);
565 
566 	for(int i = 0; i < meshes.size(); i++)
567 	{
568 		delete meshes[i];
569 	}
570 	meshes.resize(0);
571 
572 	for(int i = 0; i < actions.size(); i++)
573 	{
574 		world->removeAction(actions[i]);
575 	}
576 	actions.resize(0);*/
577 }
578 
579 
580 //  update (simulate)
581 //-------------------------------------------------------------------------------------
BltUpdate(float dt)582 void App::BltUpdate(float dt)
583 {
584 	if (!world)  return;
585 
586 	///  Simulate
587 	//double fixedTimestep(1.0/60.0);  int maxSubsteps(7);
588 	double fixedTimestep(1.0/160.0);  int maxSubsteps(24);  // same in game
589 	world->stepSimulation(dt, maxSubsteps, fixedTimestep);
590 
591 	///  objects - dynamic (props)  -------------------------------------------------------------
592 	for (int i=0; i < scn->sc->objects.size(); ++i)
593 	{
594 		Object& o = scn->sc->objects[i];
595 		if (o.ms)
596 		{
597 			btTransform tr, ofs;
598 			o.ms->getWorldTransform(tr);
599 			/*const*/ btVector3& p = tr.getOrigin();
600 			const btQuaternion& q = tr.getRotation();
601 			o.pos[0] = p.x();  o.pos[1] = p.y();  o.pos[2] = p.z();
602 			o.rot[0] = q.x();  o.rot[1] = q.y();  o.rot[2] = q.z();  o.rot[3] = q.w();
603 			o.SetFromBlt();
604 
605 			//p.setX(p.getX()+0.01f);  // move test-
606 			//tr.setOrigin(p);
607 			//o.ms->setWorldTransform(tr);
608 		}
609 	}
610  }
611 
612