1 #include "pch.h"
2 #include "../ogre/common/Def_Str.h"
3 #include "../ogre/common/Gui_Def.h"
4 #include "../ogre/common/GuiCom.h"
5 #include "../ogre/common/CScene.h"
6 #include "settings.h"
7 #include "CApp.h"
8 #include "CGui.h"
9 #include "../road/Road.h"
10 #include "../road/PaceNotes.h"
11 #include "../paged-geom/PagedGeometry.h"
12 #include "../ogre/common/MultiList2.h"
13 #include "../ogre/common/RenderBoxScene.h"
14 #include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
15 //#include <LinearMath/btDefaultMotionState.h>
16 //#include <BulletDynamics/Dynamics/btRigidBody.h>
17 #include "../shiny/Main/Factory.hpp"
18 #include "../sdl4ogre/sdlinputwrapper.hpp"
19 #include "../paged-geom/GrassLoader.h"
20 #include <MyGUI.h>
21 #include <OgreTerrain.h>
22 #include <OgreTerrainGroup.h>
23 #include <OgreParticleEmitter.h>
24 #include <OgreParticleSystem.h>
25 #include <OgreOverlay.h>
26 #include <OgreOverlayElement.h>
27 using namespace Ogre;
28 
29 
30 ///  Mouse
31 //---------------------------------------------------------------------------------------------------------------
processMouse(double fDT)32 void App::processMouse(double fDT)
33 {
34 	//  static vars are smoothed
35 	static Radian sYaw(0), sPth(0);
36 	static Vector3 sMove(0,0,0);
37 	static double time = 0.0;
38 	time += fDT;
39 
40 	const double ivDT = 0.004;  // const interval
41 	while (time > ivDT)
42 	{	time -= ivDT;
43 
44 		Vector3 vInpC(0,0,0),vInp;
45 		Real fSmooth = (powf(1.0f - pSet->cam_inert, 2.2f) * 40.f + 0.1f) * ivDT;
46 
47 		const Real sens = 0.13;
48 		if (bCam())
49 			vInpC = Vector3(mx, my, 0)*sens;
50 		vInp = Vector3(mx, my, 0)*sens;  mx = 0;  my = 0;
51 		vNew += (vInp-vNew) * fSmooth;
52 
53 		if (mbMiddle){	mTrans.z += vInpC.y * 1.6f;  }  //zoom
54 		if (mbRight){	mTrans.x += vInpC.x;  mTrans.y -= vInpC.y;  }  //pan
55 		if (mbLeft){	mRotX -= vInpC.x;  mRotY -= vInpC.y;  }  //rot
56 
57 		Real cs = pSet->cam_speed;  Degree cr(pSet->cam_speed);
58 		Real fMove = 100*cs;  //par speed
59 		Degree fRot = 300*cr, fkRot = 160*cr;
60 
61 		Radian inYaw = rotMul * ivDT * (fRot* mRotX + fkRot* mRotKX);
62 		Radian inPth = rotMul * ivDT * (fRot* mRotY + fkRot* mRotKY);
63 		Vector3 inMove = moveMul * ivDT * (fMove * mTrans);
64 
65 		sYaw += (inYaw - sYaw) * fSmooth;
66 		sPth += (inPth - sPth) * fSmooth;
67 		sMove += (inMove - sMove) * fSmooth;
68 
69 		mCamera->yaw( sYaw );
70 		mCamera->pitch( sPth );
71 		mCamera->moveRelative( sMove );
72 	}
73 }
74 
75 
76 //---------------------------------------------------------------------------------------------------------------
77 //  frame events
78 //---------------------------------------------------------------------------------------------------------------
frameEnded(const FrameEvent & evt)79 bool App::frameEnded(const FrameEvent& evt)
80 {
81 	//  show when in gui on generator subtab
82 	if (ovTerPrv)
83 	if (bGuiFocus && mWndEdit &&
84 		mWndEdit->getVisible() && mWndTabsEdit->getIndexSelected() == TAB_Terrain &&
85 		gui->vSubTabsEdit.size() > TAB_Terrain && gui->vSubTabsEdit[TAB_Terrain]->getIndexSelected() == 2/**/)
86 		ovTerPrv->show();  else  ovTerPrv->hide();
87 
88 	//  track events
89 	if (eTrkEvent != TE_None)
90 	{	switch (eTrkEvent)  {
91 			case TE_Load:	LoadTrackEv();  break;
92 			case TE_Save:	SaveTrackEv();  break;
93 			case TE_Update: UpdateTrackEv();  break;  }
94 		eTrkEvent = TE_None;
95 	}
96 
97 	///  input
98 	mInputWrapper->capture(false);
99 
100 	//  road pick
101 	SplineRoad* road = scn->road;
102 	if (road)
103 	{
104 		const MyGUI::IntPoint& mp = MyGUI::InputManager::getInstance().getMousePosition();
105 		Real mx = Real(mp.left)/mWindow->getWidth(), my = Real(mp.top)/mWindow->getHeight();
106 		bool setpos = edMode >= ED_Road || !brLockPos,
107 			hide = !(edMode == ED_Road && bEdit());
108 		road->Pick(mCamera, mx, my,  setpos, edMode == ED_Road, hide);
109 
110 		if (scn->sc->vdr)  // blt ray hit
111 		{
112 			Ray ray = mCamera->getCameraToViewportRay(mx,my);
113 			const Vector3& pos = mCamera->getDerivedPosition(), dir = ray.getDirection();
114 			btVector3 from(pos.x,-pos.z,pos.y), to(dir.x,-dir.z,dir.y);  to = from + to*10000.f;
115 			btCollisionWorld::ClosestRayResultCallback rayRes(from, to);
116 
117 			world->rayTest(from, to, rayRes);
118 
119 			if (rayRes.hasHit())
120 				road->posHit = Vector3(rayRes.m_hitPointWorld.getX(),rayRes.m_hitPointWorld.getZ(),-rayRes.m_hitPointWorld.getY());
121 			else
122 				road->posHit = Vector3::ZERO;
123 			road->ndHit->setPosition(road->posHit);
124 		}
125 	}
126 
127 	editMouse();  // edit
128 
129 
130 	///<>  Ter upd	- - -
131 	static int tu = 0, bu = 0;
132 	if (tu >= pSet->ter_skip)
133 	if (bTerUpd)
134 	{	bTerUpd = false;  tu = 0;
135 		if (scn->mTerrainGroup)
136 			scn->mTerrainGroup->update();
137 	}	tu++;
138 
139 	if (bu >= pSet->ter_skip)
140 	if (bTerUpdBlend)
141 	{	bTerUpdBlend = false;  bu = 0;
142 		//if (terrain)
143 			scn->UpdBlendmap();
144 	}	bu++;
145 
146 
147 	///<>  Edit Ter
148 	TerCircleUpd();
149 	bool def = false;
150 	static bool defOld = false;
151 	float gd = scn->sc->densGrass;
152 	static float gdOld = scn->sc->densGrass;
153 
154 	if (scn->terrain && road && bEdit() && road->bHitTer)
155 	{
156 		float dt = evt.timeSinceLastFrame;
157 		Real s = shift ? 0.25 : ctrl ? 4.0 :1.0;
158 		switch (edMode)
159 		{
160 		case ED_Deform:
161 			if (mbLeft) {  def = true;  deform(road->posHit, dt, s);  }else
162 			if (mbRight){  def = true;  deform(road->posHit, dt,-s);  }
163 			break;
164 		case ED_Filter:
165 			if (mbLeft) {  def = true;  filter(road->posHit, dt, s);  }
166 			break;
167 		case ED_Smooth:
168 			if (mbLeft) {  def = true;  smooth(road->posHit, dt);  }
169 			break;
170 		case ED_Height:
171 			if (mbLeft) {  def = true;  height(road->posHit, dt, s);  }
172 			break;
173 		}
174 	}
175 
176 #if 0
177 if (pSet->bTrees)
178 {
179 	///  upd grass
180 	if (gd != gdOld)
181 	{
182 		Real fGrass = pSet->grass * scn->sc->densGrass * 3.0f;
183 		for (int i=0; i < scn->sc->ciNumGrLay; ++i)
184 		{
185 			const SGrassLayer* gr = &scn->sc->grLayersAll[i];
186 			if (gr->on)
187 			{
188 				Forests::GrassLayer *l = gr->grl;
189 				if (l)
190 				{	l->setDensity(gr->dens * fGrass);
191 					scn->grass->reloadGeometry();
192 				}
193 			}
194 		}
195 	}
196 
197 	if (!def && defOld)
198 	{
199 		scn->UpdGrassDens();
200 		//if (grd.rnd)
201 		//	grd.rnd->update();
202 
203 		for (int i=0; i < scn->sc->ciNumGrLay; ++i)
204 		{
205 			const SGrassLayer* gr = &scn->sc->grLayersAll[i];
206 			if (gr->on)
207 			{
208 				Forests::GrassLayer *l = gr->grl;
209 				if (l)
210 				{	l->setDensityMap(scn->grassDensRTex, Forests::MapChannel(std::min(3,i)));  // l->chan);
211 					//l->applyShader();
212 					scn->grass->reloadGeometry();
213 				}
214 			}
215 		}
216 	}
217 	defOld = def;
218 	gdOld = gd;
219 }
220 #endif
221 
222 	///  paged  * * *  ? frameStarted
223 	if (road)
224 	{	if (scn->grass)  scn->grass->update();
225 		if (scn->trees)  scn->trees->update();
226 	}
227 
228 
229 	///  paged  Upd  * * *
230 	if (bTrGrUpd)
231 	{	bTrGrUpd = false;
232 		pSet->bTrees = !pSet->bTrees;
233 		scn->RecreateTrees();
234 	}
235 
236 
237 	if (road)  // road
238 	{
239 		road->bCastShadow = pSet->shadow_type >= Sh_Depth;
240 		bool full = road->RebuildRoadInt();
241 
242 		if (full && scn->pace)  // pace
243 		{
244 			scn->pace->SetupTer(scn->terrain);
245 			road->RebuildRoadPace();
246 			scn->pace->Rebuild(road, scn->sc, pSet->trk_reverse);
247 	}	}
248 
249 	///**  Render Targets update
250 	if (edMode == ED_PrvCam)
251 	{
252 		scn->sc->camPos = mCamera->getPosition();
253 		scn->sc->camDir = mCamera->getDirection();
254 		if (rt[RTs-1].tex)
255 			rt[RTs-1].tex->update();
256 	}else{
257 		static int ri = 0;
258 		if (ri >= pSet->mini_skip)
259 		{	ri = 0;
260 			for (int i=0; i < RTs-1/**/; ++i)
261 				if (rt[i].tex)
262 					rt[i].tex->update();
263 		}	ri++;
264 	}
265 	//LogO(toStr(evt.timeSinceLastFrame));
266 
267 	return true;
268 }
269 
270 
271 //---------------------------------------------------------------------------------------------------------------
frameStarted(const Ogre::FrameEvent & evt)272 bool App::frameStarted(const Ogre::FrameEvent& evt)
273 {
274 	BaseApp::frameStarted(evt);
275 
276 	static Real time1 = 0.;
277 	mDTime = evt.timeSinceLastFrame;
278 
279 	//  inc edit time
280 	time1 += mDTime;
281 	if (time1 > 1.)
282 	{	time1 -= 1.;  ++scn->sc->secEdited;
283 
284 		if (bGuiFocus)	//  upd ed info txt
285 			gui->UpdEdInfo();
286 	}
287 
288 	if (mDTime > 0.1f)  mDTime = 0.1f;  //min 5fps
289 
290 
291 	//  update input
292 	mRotX = 0; mRotY = 0;  mRotKX = 0; mRotKY = 0;  mTrans = Vector3::ZERO;
293 	#define  isKey(a)  mInputWrapper->isKeyDown(SDL_SCANCODE_##a)
294 
295 	//  Move,Rot camera
296 	if (bCam())
297 	{
298 		if (isKey(A))  mTrans.x -= 1;	if (isKey(D))  mTrans.x += 1;
299 		if (isKey(W))  mTrans.z -= 1;	if (isKey(S))  mTrans.z += 1;
300 		if (isKey(Q))  mTrans.y -= 1;	if (isKey(E))  mTrans.y += 1;
301 
302 		if (isKey(DOWN) ||isKey(KP_2))  mRotKY -= 1;
303 		if (isKey(UP)   ||isKey(KP_8))  mRotKY += 1;
304 		if (isKey(RIGHT)||isKey(KP_6))  mRotKX -= 1;
305 		if (isKey(LEFT) ||isKey(KP_4))  mRotKX += 1;
306 	}
307 
308 	   // key modifiers
309 	  alt = mInputWrapper->isModifierHeld(SDL_Keymod(KMOD_ALT));
310 	 ctrl = mInputWrapper->isModifierHeld(SDL_Keymod(KMOD_CTRL));
311 	shift = mInputWrapper->isModifierHeld(SDL_Keymod(KMOD_SHIFT));
312 
313 	 // speed multiplers
314 	moveMul = 1;  rotMul = 1;
315 	if(shift){	moveMul *= 0.2;	 rotMul *= 0.4;	}  // 16 8, 4 3, 0.5 0.5
316 	if(ctrl){	moveMul *= 4;	 rotMul *= 2.0;	}
317 	//if(alt)  {	moveMul *= 0.5;	 rotMul *= 0.5;	}
318 	//const Real s = (shift ? 0.05 : ctrl ? 4.0 :1.0)
319 
320 	if (imgCur)  //-
321 	{
322 		const MyGUI::IntPoint& mp = MyGUI::InputManager::getInstance().getMousePosition();
323 		imgCur->setPosition(mp);
324 		imgCur->setVisible(bGuiFocus || !bMoveCam);
325 	}
326 
327 	processMouse(mDTime);
328 
329 
330 	///  gui
331 	gui->GuiUpdate();
332 
333 
334 	if (bRecreateFluids)
335 	{	bRecreateFluids = false;
336 
337 		scn->DestroyFluids();
338 		scn->CreateFluids();
339 		UpdFluidBox();
340 	}
341 
342 
343 	//--  3d view upd  (is global in window)
344 	static bool oldVis = false;
345 	int tab = mWndTabsEdit->getIndexSelected(), st5 = gui->vSubTabsEdit[TAB_Veget]->getIndexSelected();
346 	bool vis = mWndEdit && mWndEdit->getVisible() && (tab == TAB_Objects || tab == TAB_Veget && st5 == 1);
347 
348 	if (oldVis != vis)
349 	{	oldVis = vis;
350 		gui->viewCanvas->setVisible(vis);
351 	}
352 	if (gui->tiViewUpd >= 0.f)
353 		gui->tiViewUpd += evt.timeSinceLastFrame;
354 
355 	if (gui->tiViewUpd > 0.0f)  //par delay 0.1
356 	{	gui->tiViewUpd = -1.f;
357 
358 		gui->viewBox->clearScene();
359 		if (!gui->viewMesh.empty() && ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(gui->viewMesh))
360 		{	gui->viewSc = gui->viewBox->injectObject(gui->viewMesh);
361 			gui->updVegetInfo();
362 	}	}
363 
364 
365 	//  Update rain/snow - depends on camera
366 	scn->UpdateWeather(mCamera, pSet->bWeather ? 0.f : 1.f);
367 
368 	// update shader time
369 	mTimer += evt.timeSinceLastFrame;
370 	mFactory->setSharedParameter("windTimer", sh::makeProperty <sh::FloatValue>(new sh::FloatValue(mTimer)));
371 	mFactory->setSharedParameter("waterTimer", sh::makeProperty <sh::FloatValue>(new sh::FloatValue(mTimer)));
372 
373 	/*if (ndCar && road)  ///()  grass sphere test
374 	{
375 		const Vector3& p = ndCar->getPosition();  Real r = road->vStBoxDim.z/2;  r *= r;
376 		mFactory->setSharedParameter("posSph0", sh::makeProperty <sh::Vector4>(new sh::Vector4(p.x,p.y,p.z,r)));
377 		mFactory->setSharedParameter("posSph1", sh::makeProperty <sh::Vector4>(new sh::Vector4(p.x,p.y,p.z,r)));
378 	}/**/
379 
380 
381 	//  pace vis
382 	if (scn->pace)
383 		scn->pace->UpdVis(Vector3::ZERO, edMode == ED_PrvCam);
384 
385 
386 	//  upd terrain generator preview
387 	if (bUpdTerPrv)
388 	{	bUpdTerPrv = false;
389 		updateTerPrv();
390 	}
391 
392 
393 	///  simulate objects
394 	if (edMode == ED_Objects && objSim /*&& bEdit()*/)
395 		BltUpdate(evt.timeSinceLastFrame);
396 
397 	UpdObjNewNode();
398 
399 
400 	bFirstRenderFrame = false;
401 
402 	return true;
403 }
404