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