1 #pragma once
2 #include <OgreVector3.h>
3 
4 namespace Ogre {  class Terrain;  class SceneNode;  }
5 
6 
7 class TerUtil  //  helper
8 {
9 public:
10 	static float GetAngle(float x, float y);  // atan(y/x)
11 	//  terrain
12 	static float         GetAngleAt(Ogre::Terrain* terrain, float x, float z, float s);
13 	static Ogre::Vector3 GetNormalAt(Ogre::Terrain* terrain, float x, float z, float s);
14 };
15 
16 
17 enum AngType {  AT_Manual=0, AT_Auto, AT_Both, AT_ALL  };
18 const static std::string csAngType[AT_ALL] = {"Manual", "Auto", "Both"};
19 
20 
21 
22 //  point,  variables
23 //------------------------------------------------------
24 class SplinePoint
25 {
26 public:
27 	Ogre::Vector3 pos, tan;  // position, tangent (computed)
28 	Ogre::Real width, wtan;  // road width
29 
30 	Ogre::Real mYaw,mRoll;  // manual angles, if not auto
31 	AngType aType;
32 	Ogre::Real aYaw,aRoll;  // working angles (from auto)
33 	Ogre::Real tYaw,tRoll;  //- angles+tan interp, not used yet
34 	Ogre::Real aY,aR;   // after prepass+
35 
36 	//  on/off
37 	bool onTer;   // sticked on terrain
38 	int cols;     // has column
39 
40 	int onPipe;   // driven on pipe  0 off, 1 mark for stats only, 2 inverse normal too
41 	int loop;	// loop type: 0 none, 1 straight, 2 side, 3 barrel, 4 double  max LoopTypes-1
42 				// if > 0, chk is start or end of loop (for auto camera change)
43 
44 	//  next
45 	Ogre::Real pipe;    // pipe amount 0..1
46 	int idMtr;    // material id road/pipe
47 
48 	Ogre::Real chkR;    // checkpoint sphere radius (0-none)
49 	bool chk1st;  // 1st checkpoint (1), just once on road
50 
51 	bool notReal;  // true means only for decoration, or point move, not real driven road
isnt()52 	inline bool isnt() {  return idMtr == -1 && !notReal;  }  // real hidden
53 
54 	SplinePoint();
55 	void SetDefault();
56 };
57 
58 
59 //  checkpoint
60 //  for car checking
61 class CheckSphere
62 {
63 public:
64 	Ogre::Vector3 pos;
65 	Ogre::Real r,r2;  // radius, r*r
66 	bool loop;  // for car camera change
67 
68 	//  for drive progress %
69 	Ogre::Real dist[2];  // summed distances (cur to next)
70 		// [0] normal, [1] reversed track
71 };
72 
73 
74 
75 //------------------------------------------------------
76 //  Spline Base,  only interpolation
77 //------------------------------------------------------
78 class SplineBase
79 {
80 public:
81 	SplineBase();
82 	~SplineBase();
83 	friend class CGui;
84 
85 
86 	//  points
87 	void clear();
getNumPoints()88 	inline int getNumPoints() const {  return (int)mP.size();  }
89 
90 	//  get next, prev points
getPrev(int id)91 	inline int getPrev(int id) const
92 	{	int s = (int)mP.size();  return isLooped ?  (id-1+s) % s : std::max(0,   id-1);  }
getNext(int id)93 	inline int getNext(int id) const
94 	{	int s = (int)mP.size();  return isLooped ?  (id+1) % s   : std::min(s-1, id+1);  }
getAdd(int id,int n)95 	inline int getAdd(int id, int n) const
96 	{	int s = (int)mP.size();  return isLooped ?  (id+n+s) % s : std::min(s-1, std::max(0, id+n));  }
97 
98 
99 	//  pos
100 	const Ogre::Vector3& getPos(int index) const;
101 	void setPos(int index, const Ogre::Vector3& value);
102 
103 	SplinePoint& getPoint(int index);
104 
105 
106 	//  interpolate
107 	//  get value at a single segment of the spline  t = 0..1
108 	Ogre::Vector3 interpolate(int id, Ogre::Real t) const;
109 
110 	//  interpolate 1 dim vars
111 	Ogre::Real interpWidth(int id, Ogre::Real t) const;
112 
113 	void recalcTangents();
114 
115 
116 	//  dir, length
117 	Ogre::Real GetSegLen(int seg);
118 	Ogre::Vector3 GetLenDir(int seg, Ogre::Real l, Ogre::Real la);
119 	static Ogre::Vector3 GetRot(Ogre::Real ayaw, Ogre::Real ang);
120 
121 
122 protected:
123 	bool isLooped;  ///=closed, if false begin and end are not connected
124 
125 	std::deque<SplinePoint> mP;  // points
126 	static std::deque<SplinePoint> mPc;  // copy points
127 };
128 
129 
130 
131 //--------------------------------------------------------------------------------------
132 //  Spline Edit,  base with editing
133 //--------------------------------------------------------------------------------------
134 
135 class SplineEdit : public SplineBase
136 {
137 public:
SplineEdit()138 	SplineEdit()
139 		:mTerrain(0)
140 		,iSelPoint(-1), iChosen(-1)
141 		,bSelChng(0)
142 		,rebuild(false), iDirtyId(-1)
143 		,g_Height(0.1f)
144 	{	}
145 
146 
147 	//  terrain helpers
148 	Ogre::Terrain* mTerrain;  // for on terrain, height snap
149 
150 	Ogre::Real getTerH(const Ogre::Vector3& p);
151 
152 	void UpdPointsH();  // set markers pos, h on ter
153 
154 
155 	//  point sel  ----
156 	void ChoosePoint();  // choose one
157 	void PrevPoint(),NextPoint(), FirstPoint(),LastPoint();
158 	void CopyNewPoint();  // set new point params from chosen
159 
160 	void SelAddPoint();  // toggle sel
161 	void SelClear(),SelAll();
162 	int GetSelCnt();  // select many
163 
164 	//  modify road point  ----
165 	void ToggleOnTerrain(), ToggleColumn();
166 	void ChgMtrId(int rel);  // next
167 	void ChgAngType(int rel), AngZero();
168 
169 	void ToggleOnPipe(bool old=false);  // extras
170 	void ChgLoopType(int rel), ToggleNotReal();
171 
172 
173 	///  Edit  ====
174 	void Move1(int id, Ogre::Vector3 relPos);
175 	void Move(Ogre::Vector3 relPos);  // 1 or sel
176 	void Scale1(int id, Ogre::Real posMul, Ogre::Real hMul);
177 
178 	void AddWidth(Ogre::Real relW);
179 	void AddRoll(Ogre::Real relA,Ogre::Real snapA, bool alt);  // changes camber
180 	void AddYaw( Ogre::Real relA,Ogre::Real snapA, bool alt);  // auto-
181 	void AddPipe(Ogre::Real relP);
182 
183 
184 	//  Edit Selected  ====
185 	Ogre::Vector3 getPos0();  // selection center point (or chosen)
186 
187 	void RotateSel(Ogre::Real relA, Ogre::Vector3 axis, int addYawRoll);
188 	void ScaleSel(Ogre::Real posMul);
189 	void MirrorSel(bool alt);  // reverse order of points
190 
191 
192 protected:
193 	SplinePoint newP;  // new point for insert
194 
195 	//  selection  ----
196 	//  chosen stays, SelPoint is under mouse Pick
197 	int iChosen, iSelPoint;  // -1 if none
198 	std::set<int> vSel;  // selected points
199 
200 	bool bSelChng;  // rebuild road after end of selection change
201 
202 
203 	//  rebuild, mark only  ----
204 	bool rebuild;
205 	int iDirtyId;
206 	void Rebuild(bool full=false);
207 
208 
209 	Ogre::Real g_Height;	 ///geom  above terrain global,  ?for each point-
210 
211 
212 	struct Mark  // marker node  ----
213 	{
214 		Ogre::SceneNode* nd; //,*ndC;
215 		Ogre::Entity* ent; //,*entC;
216 
MarkMark217 		Mark() : nd(0),ent(0) //, ndC(0),entC(0)
218 		{	}
219 		void setPos(Ogre::Vector3 pos);
220 		void setVis(bool vis);
221 	};
222 	std::vector<Mark> vMarks;
223 };
224 
225 
226 //--------------------------------------------------------------------------------------
227 //  Spline EditChk,  with checkpoints and car start
228 //--------------------------------------------------------------------------------------
229 
230 class SplineEditChk : public SplineEdit
231 {
232 public:
SplineEditChk()233 	SplineEditChk()
234 		:chksRoadLen(1.f)
235 		,iDir(0), iChkId1(0), iChkId1Rev(0)
236 	{	}
237 
238 	//  edit chks
239 	void AddChkR(Ogre::Real relR, bool dontCheckR=false);  // change radius
240 	void AddBoxW(Ogre::Real rel), AddBoxH(Ogre::Real rel);  // start dim
241 	void Set1stChk();
242 
243 
244 //  checkpoint spheres  ----
245 	std::vector<CheckSphere> mChks;
246 	Ogre::Vector3 vStBoxDim;   // start/finish box, half dimensions
247 	///TODO: vStPos for !isLooped, vStBoxDim at end, ed mode..
248 
249 	int iDir;     // -1 or +1  if road points go +/-1 with car start orientation
250 	int iChkId1, iChkId1Rev;   // 1st chekpoint index (and for reversed) for mChks[]
251 
252 	Ogre::Real chksRoadLen;    // for %, sum of all mChks[].dist (without last)
253 };
254 
255 
256 //--------------------------------------------------------------------------------------
257 //  Spline MarkEd,  with Markers (spheres)
258 //--------------------------------------------------------------------------------------
259 
260 class SplineMarkEd : public SplineEditChk
261 {
262 public:
263 	SplineMarkEd();
264 
265 	//  Setup, call this on Init
266 	void Setup(Ogre::String sMarkerMeshFile, Ogre::Real scale,
267 		Ogre::Terrain* terrain, Ogre::SceneManager* sceneMgr,  Ogre::Camera* camera);
268 
269 	void createMarker(Ogre::String name, Ogre::String mat,
270 					Ogre::Entity*& ent, Ogre::SceneNode*& nd);
271 
272 	//  control markers  -------
273 	void AddMarker(Ogre::Vector3 pos);
274 	void DestroyMarker(int id), DelLastMarker(), UpdAllMarkers(), DestroyMarkers();
275 	//  util
276 	void SetTerHitVis(bool visible), UpdRot();
277 
278 
279 //  ogre vars
280 	Ogre::SceneManager* mSceneMgr;
281 	Ogre::Camera* mCamera;
282 
283 	//  setup vars
284 	Ogre::String sMarkerMesh;
285 	Ogre::Real fMarkerScale, fScRot,fScHit;  // scale
286 
287 	Ogre::SceneNode *ndSel,*ndChosen,*ndRot,*ndHit,*ndChk;
288 	int lastNdSel, lastNdChosen;
289 	Ogre::Entity* entSel,*entChs,*entRot,*entHit,*entChk;
290 };
291