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