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