1 #include "pch.h"
2 #include "Road.h"
3 #include "../ogre/common/Def_Str.h"
4 #include "../ogre/common/RenderConst.h"
5 
6 #include <OgreSceneManager.h>
7 #include <OgreTerrain.h>
8 #include <OgreSceneNode.h>
9 #include <OgreEntity.h>
10 using namespace Ogre;
11 
12 
13 //  Setup
14 //---------------------------------------------------------------------------------------------------------------
SplineMarkEd()15 SplineMarkEd::SplineMarkEd()
16 	:mSceneMgr(0),mCamera(0)
17 	,ndSel(0), ndChosen(0), ndRot(0), ndHit(0), ndChk(0)
18 	,entSel(0), entChs(0), entRot(0), entHit(0), entChk(0)
19 	,lastNdSel(-2),lastNdChosen(-2)
20 	,fMarkerScale(1.f), fScRot(1.8f),fScHit(0.8f)
21 {	}
22 
createMarker(String name,String mat,Entity * & ent,SceneNode * & nd)23 void SplineMarkEd::createMarker(String name, String mat, Entity*& ent, SceneNode*& nd)
24 {
25 	ent = mSceneMgr->createEntity(name, sMarkerMesh);
26 	ent->setMaterialName(mat);  ent->setCastShadows(false);  ent->setVisibilityFlags(RV_Hud);
27 	nd = mSceneMgr->getRootSceneNode()->createChildSceneNode(name);
28 	nd->attachObject(ent);  nd->setVisible(false);
29 }
30 
Setup(String sMarkerMeshFile,Real scale,Terrain * terrain,SceneManager * sceneMgr,Camera * camera)31 void SplineMarkEd::Setup(
32 	String sMarkerMeshFile, Real scale,
33 	Terrain* terrain, SceneManager* sceneMgr, Camera* camera)
34 {
35 	sMarkerMesh = sMarkerMeshFile;
36 	fMarkerScale = scale;
37 	mTerrain = terrain;  mSceneMgr = sceneMgr;  mCamera = camera;
38 
39 	if (sMarkerMesh == "")  return;
40 
41 	String name;
42 	createMarker("sphereSel",   "sphere_sel",   entSel, ndSel);
43 	createMarker("sphereChosen","sphere_chosen",entChs, ndChosen);
44 	createMarker("sphereHit",   "sphere_hit",   entHit, ndHit);
45 	createMarker("sphereRot",   "sphere_rot",   entRot, ndRot);
46 	createMarker("sphereCheck", "sphere_check", entChk, ndChk);
47 
48 	ndHit->setScale(/*fMarkerScale **/ fScHit * Vector3::UNIT_SCALE);
49 	ndRot->setScale(fMarkerScale * fScRot * Vector3::UNIT_SCALE);
50 	entChk->setRenderQueueGroup(RQG_RoadMarkers);  // after road
51 }
52 
53 
setPos(Vector3 pos)54 void SplineEdit::Mark::setPos(Vector3 pos)
55 {
56 	nd->setPosition(pos);
57 	//ndC->setPosition(pos);
58 }
setVis(bool vis)59 void SplineEdit::Mark::setVis(bool vis)
60 {
61 	nd->setVisible(vis);
62 	//ndC->setVisible(vis);
63 }
64 
65 
66 //  add marker
67 //-------------------------------------------------------------------------------------
AddMarker(Vector3 pos)68 void SplineMarkEd::AddMarker(Vector3 pos)
69 {
70 	if (sMarkerMesh == "")  return;
71 	Entity* ent;//, *entC;
72 	SceneNode* nd;//, *ndC;
73 
74 	ent = mSceneMgr->createEntity(sMarkerMesh);
75 	ent->setMaterialName("sphere_norm");  ent->setCastShadows(false);
76 	ent->setVisibilityFlags(RV_Hud);
77 
78 	nd = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos);
79 	nd->attachObject(ent);  nd->scale(fMarkerScale * Vector3::UNIT_SCALE);
80 
81 	//entC = mSceneMgr->createEntity(sMarkerMesh);
82 	//entC->setMaterialName("sphere_norm");  entC->setCastShadows(false);
83 	//entC->setVisibilityFlags(RV_Hud/*RQG_RoadMarkers*/);
84 
85 	//ndC = mSceneMgr->getRootSceneNode()->createChildSceneNode(pos);
86 	//ndC->attachObject(entC);  //ndC->setVisible(true);
87 
88 	Mark m;
89 	m.nd = nd;  m.ent = ent;
90 	//m.ndC = ndC;  m.entC = entC;
91 	vMarks.push_back(m);
92 }
93 
DestroyMarker(int id)94 void SplineMarkEd::DestroyMarker(int id)
95 {
96 	Mark& m = vMarks[id];
97 	mSceneMgr->destroyEntity(m.ent);
98 	//mSceneMgr->destroyEntity(m.entC);
99 	mSceneMgr->destroySceneNode(m.nd);
100 	//mSceneMgr->destroySceneNode(m.ndC);
101 }
102 
103 //  del last marker
DelLastMarker()104 void SplineMarkEd::DelLastMarker()
105 {
106 	if (sMarkerMesh == "")  return;
107 	int last = vMarks.size()-1;
108 	if (lastNdChosen == last)
109 		lastNdChosen = -2;
110 	if (lastNdSel == last)
111 		lastNdSel = -2;
112 
113 	DestroyMarker(getNumPoints()-1);
114 	vMarks.pop_back();
115 }
116 
117 //  destroy all
DestroyMarkers()118 void SplineMarkEd::DestroyMarkers()
119 {
120 	if (sMarkerMesh == "")  return;
121 	for (size_t i=0; i < vMarks.size(); ++i)
122 		DestroyMarker(i);
123 
124 	vMarks.clear();
125 	lastNdChosen = -2;
126 	lastNdSel = -2;
127 }
128 
129 
130 //  Select
131 //-------------------------------------------------------------------------------------
SelectMarker(bool bHide)132 void SplineRoad::SelectMarker(bool bHide)  // Mr Melect Sarker
133 {
134 	if (vMarks.empty())
135 	{
136 		ndChosen->setVisible(false);
137 		ndRot->setVisible(false);
138 		ndChk->setVisible(false);
139 		ndSel->setVisible(false);
140 		return;
141 	}
142 
143 	if (lastNdSel >= 0)
144 		vMarks[lastNdSel].setVis(true);
145 	if (lastNdChosen >= 0)
146 		vMarks[lastNdChosen].setVis(true);
147 
148 	int i = iChosen;
149 	if (i == -1 || bHide)
150 	{	ndChosen->setVisible(false);
151 		ndRot->setVisible(false);
152 		ndChk->setVisible(false);
153 	}else  // chosen
154 	{
155 		Mark& m = vMarks[i];
156 		m.setVis(false);
157 		ndChosen->setPosition(m.nd->getPosition());
158 		ndChosen->setScale(m.nd->getScale());
159 		ndChosen->setVisible(true);
160 		ndRot->setVisible(true);
161 		lastNdChosen = i;
162 
163 		Vector3 pc = m.nd->getPosition();
164 		//  move checks in pipe to center (half normal up)
165 		if (mP[i].pipe > 0.f && mP[i].onPipe==0)
166 			pc += 0.5f * mP[i].width * DL0.v0_N[i];
167 		ndChk->setPosition(pc);
168 
169 		ndChk->setScale(mP[i].chkR * 2.f * mP[i].width * Vector3::UNIT_SCALE);
170 		ndChk->setVisible(true);
171 	}
172 
173 	if (iSelPoint == -1 || bHide)
174 		ndSel->setVisible(false);
175 	else  // sel
176 	{
177 		Mark& m = vMarks[iSelPoint];
178 		m.setVis(false);
179 		ndSel->setPosition(m.nd->getPosition());
180 		ndSel->setScale(m.nd->getScale());
181 		ndSel->setVisible(true);
182 		lastNdSel = iSelPoint;
183 	}
184 	UpdRot();
185 }
186 
187 //  Update all
UpdAllMarkers()188 void SplineMarkEd::UpdAllMarkers()
189 {
190 	if (sMarkerMesh == "")  return;
191 	for (int i=0; i < getNumPoints(); ++i)
192 		Move1(i, Vector3::ZERO);  //-
193 
194 	int si = std::min(getNumPoints(), (int)vMarks.size());  //=
195 	for (int i=0; i < si; ++i)
196 	{
197 		Vector3& pos = mP[i].pos;  //- update on ter pos (move 0)
198 		if (mP[i].onTer)
199 			pos.y = getTerH(pos) + g_Height;
200 
201 		Mark& m = vMarks[i];
202 		m.setPos(pos/*getPos(i)*/);
203 		m.nd->setScale(fMarkerScale * Vector3::UNIT_SCALE);
204 		//m.ndC->setScale(mP[i].chkR * 2.f * mP[i].width * Vector3::UNIT_SCALE);
205 	}
206 	UpdRot();
207 }
208 
209 
210 //  util
211 //------------------------------------------------
UpdRot()212 void SplineMarkEd::UpdRot()
213 {
214 	if (!ndRot)  return;
215 	int i = iChosen;	//ndRot->setVisible(mP[i].onTer);
216 	if (i == -1)  return;
217 
218 	Vector3 vr = GetRot(mP[i].aYaw, mP[i].aRoll);
219 	Vector3 rpos = mP[i].pos + vr * mP[i].width * 0.54f;
220 	ndRot->setPosition(rpos);  //vr.normalise();
221 	ndRot->setScale(fMarkerScale * fScRot * Vector3::UNIT_SCALE);
222 
223 	//Quaternion q;  q.FromAngleAxis(Degree(0), vr);
224 	//ndRot->setOrientation(q);  //.. box
225 }
226 
227 
SetTerHitVis(bool visible)228 void SplineMarkEd::SetTerHitVis(bool visible)
229 {
230 	if (ndHit)
231 		ndHit->setVisible(visible);
232 }
233 
234 
235 
236 //  Checkpoints
237 //--------------------------------------------------------------------------------------
AddChkR(Real relR,bool dontCheckR)238 void SplineEditChk::AddChkR(Real relR, bool dontCheckR)    ///  ChkR
239 {
240 	int seg = iChosen;
241 	if (seg == -1)  return;
242 	mP[seg].chkR = std::max(0.f, mP[seg].chkR + relR);
243 	if (dontCheckR)  return;
244 
245 	//  disallow between 0..1
246 	if (relR < 0.f && mP[seg].chkR < 1.f)  mP[seg].chkR = 0.f;  else
247 	if (relR > 0.f && mP[seg].chkR < 1.f)  mP[seg].chkR = 1.f;
248 
249 	//  max radius  (or const on bridges or pipes)
250 	int all = getNumPoints();
251 	if (all < 2)  return;
252 
253 	int next = (seg+1) % all, prev = (seg-1+all) % all;
254 	bool bridge = !mP[seg].onTer || !mP[next].onTer || !mP[prev].onTer;
255 	bool pipe = mP[seg].pipe > 0.5f;
256 
257 	Real maxR = pipe || bridge ? 1.f : 2.5f;
258 	if (bridge || pipe)
259 	{	if (relR > 0.f)  mP[seg].chkR = maxR;  else
260 		if (relR < 0.f)  mP[seg].chkR = 0.f;
261 	}
262 	else if (relR > 0.f && mP[seg].chkR > maxR)
263 		mP[seg].chkR = maxR;
264 }
265 
266 
AddBoxW(Real rel)267 void SplineEditChk::AddBoxW(Real rel)
268 {
269 	vStBoxDim.z = std::max(6.f, vStBoxDim.z + rel);
270 }
AddBoxH(Real rel)271 void SplineEditChk::AddBoxH(Real rel)
272 {
273 	vStBoxDim.y = std::max(5.f, vStBoxDim.y + rel);
274 }
275 
Set1stChk()276 void SplineEditChk::Set1stChk()
277 {
278 	if (iChosen < 0 || iChosen >= getNumPoints())  return;
279 	if (mP[iChosen].chkR < 0.5f)  return;
280 
281 	for (int i=0; i < getNumPoints(); ++i)  // clear from all
282 		mP[i].chk1st = false;
283 	mP[iChosen].chk1st = true;  // set this
284 }
285 
286 
287 //  Set Checkpoints
288 //--------------------------------------------------------------------------------------
SetChecks()289 void SplineRoad::SetChecks()
290 {
291 	///  add checkpoints  * * *
292 	mChks.clear();  iChkId1 = 0;
293 	for (int i=0; i < mP.size(); ++i)  //=getNumPoints
294 	{
295 		if (mP[i].chkR > 0.f)
296 		{
297 			CheckSphere cs;
298 			cs.pos = mP[i].pos;
299 			cs.r = mP[i].chkR * mP[i].width;
300 
301 			//  move checks in pipe to center (half normal up)
302 			if (!DL0.v0_N.empty())
303 			if (mP[i].pipe > 0.f && mP[i].onPipe==0)
304 			{	cs.pos += 0.5f * mP[i].width * DL0.v0_N[i];
305 				cs.r *= 0.5f;  }  // exact-
306 
307 			cs.r2 = cs.r * cs.r;
308 			cs.loop = mP[i].loop > 0;
309 
310 			if (mP[i].chk1st)  //1st checkpoint
311 				iChkId1 = mChks.size();
312 
313 			mChks.push_back(cs);
314 		}
315 	}
316 	int num = (int)mChks.size();
317 	if (num == 0)  return;
318 
319 	//  1st checkpoint for reverse (= last chk)
320 	iChkId1Rev = (iChkId1 - iDir + num) % num;
321 
322 
323 	//  dist between checks
324 	if (num == 1)  {
325 		mChks[0].dist[0] = 10.f;  mChks[0].dist[1] = 10.f;  }
326 
327 	//LogO("----  chks norm  ----");
328 	int i = iChkId1;  Real sum = 0.f;
329 	for (int n=0; n < num; ++n)
330 	{
331 		int i1 = (i + iDir + num) % num;
332 		Vector3 vd = mChks[i].pos - mChks[i1].pos;
333 		Real dist = (n == num-1) ? 0.f :  vd.length() + mChks[n].r;  // not last pair
334 		sum += dist;  mChks[n].dist[0] = sum;
335 		//LogO("Chk " + toStr(i) +"-"+ toStr(i1) + " dist:" + toStr(dist) + " sum:" + toStr(mChks[n].dist[0]));
336 		i = i1;
337 	}
338 	chksRoadLen = sum;
339 
340 	//LogO("----  chks rev  ----");
341 	i = iChkId1Rev;  sum = 0.f;
342 	for (int n=0; n < num; ++n)
343 	{
344 		int i1 = (i - iDir + num) % num;
345 		Vector3 vd = mChks[i].pos - mChks[i1].pos;
346 		Real dist = (n == num-1) ? 0.f :  vd.length() + mChks[n].r;  // not last pair
347 		sum += dist;  mChks[n].dist[1] = sum;
348 		//LogO("Chk " + toStr(i) +"-"+ toStr(i1) + " dist:" + toStr(dist) + " sum:" + toStr(mChks[n].dist[1]));
349 		i = i1;
350 	}
351 	//LogO("----");
352 	//LogO("chksRoadLen: "+toStr(sum));
353 	//LogO("chk 1st: "+toStr(iChkId1) + " last: "+toStr(iChkId1Rev) + " dir: "+toStr(iDir));
354 	//LogO("----");
355 }
356