1 #include "pch.h"
2 #include "par.h"
3 #include "track.h"
4
5 #include "configfile.h"
6 #include "reseatable_reference.h"
7 #include "tracksurface.h"
8 #include "objectloader.h"
9 #include <functional>
10 #include <algorithm>
11 #include "../ogre/common/Def_Str.h"
12 #include "game.h" // for tires map
13
14 #include <list>
15 #include <map>
16 #include <string>
17 #include <iostream>
18 #include <fstream>
19 #include <sstream>
20 using namespace std;
21
22
TRACK()23 TRACK::TRACK()
24 :pGame(0),
25 texture_size("large"),
26 loaded(false), asphalt(false),
27 sDefaultTire("gravel")
28 {
29 }
30
~TRACK()31 TRACK::~TRACK()
32 {
33 Clear();
34 }
35
DeferredLoad(const string & trackpath,bool reverse,int anisotropy,const string & texsize,bool dynamicshadowsenabled,bool doagressivecombining)36 bool TRACK::DeferredLoad(
37 const string & trackpath,
38 bool reverse,
39 int anisotropy,
40 const string & texsize,
41 bool dynamicshadowsenabled,
42 bool doagressivecombining)
43 {
44 Clear();
45
46 texture_size = texsize;
47 LogO("-=- Loading track from path: "+trackpath);
48
49 //load roads
50 if (!LoadRoads(trackpath, reverse))
51 {
52 //error_output << "Error during road loading; continuing with an unsmoothed track" << endl;
53 ClearRoads();
54 }
55
56 //if (!CreateRacingLines())
57 // return false;
58
59 //load objects
60 if (!BeginObjectLoad(trackpath, anisotropy, dynamicshadowsenabled, doagressivecombining))
61 return false;
62
63 return true;
64 }
65
ContinueDeferredLoad()66 bool TRACK::ContinueDeferredLoad()
67 {
68 if (Loaded())
69 return true;
70
71 pair <bool,bool> loadstatus = ContinueObjectLoad();
72 if (loadstatus.first)
73 return false;
74
75 if (!loadstatus.second)
76 loaded = true;
77
78 return true;
79 }
80
DeferredLoadTotalObjects()81 int TRACK::DeferredLoadTotalObjects()
82 {
83 assert(objload.get());
84 return objload->GetNumObjects();
85 }
86
Clear()87 void TRACK::Clear()
88 {
89 objects.clear();
90 model_library.clear();
91 texture_library.clear();
92
93 ogre_meshes.clear();///
94
95 ClearRoads();
96
97 loaded = false;
98 }
99
BeginObjectLoad(const string & trackpath,int anisotropy,bool dynamicshadowsenabled,bool doagressivecombining)100 bool TRACK::BeginObjectLoad(
101 const string & trackpath,
102 int anisotropy,
103 bool dynamicshadowsenabled,
104 bool doagressivecombining)
105 {
106 objload.reset(new OBJECTLOADER(trackpath, anisotropy, dynamicshadowsenabled,
107 true, doagressivecombining));
108
109 if (!objload->BeginObjectLoad())
110 return false;
111
112 return true;
113 }
114
ContinueObjectLoad()115 pair <bool,bool> TRACK::ContinueObjectLoad()
116 {
117 assert(objload.get());
118 return objload->ContinueObjectLoad(this, model_library, texture_library, objects, texture_size);
119 }
120
LoadObjects(const string & trackpath,int anisotropy)121 bool TRACK::LoadObjects(const string & trackpath, int anisotropy)
122 {
123 BeginObjectLoad(trackpath, anisotropy, false, false);
124 pair <bool,bool> loadstatus = ContinueObjectLoad();
125
126 while (!loadstatus.first && loadstatus.second)
127 loadstatus = ContinueObjectLoad();
128
129 return !loadstatus.first;
130 }
131
LoadRoads(const string & trackpath,bool reverse)132 bool TRACK::LoadRoads(const string & trackpath, bool reverse)
133 {
134 ClearRoads();
135
136 ifstream trackfile;
137 trackfile.open((trackpath + "/roads.trk").c_str());
138 if (!trackfile)
139 {
140 //error_output << "Error opening roads file: " << trackpath + "/roads.trk" << endl;
141 //return false;
142 }
143
144 int numroads=0;
145 trackfile >> numroads;
146
147 for (int i = 0; i < numroads && trackfile; ++i)
148 {
149 roads.push_back(ROADSTRIP());
150 roads.back().ReadFrom(trackfile, cerr);
151 }
152
153 if (reverse)
154 for_each(roads.begin(), roads.end(), mem_fun_ref(&ROADSTRIP::Reverse));
155
156 return true;
157 }
158
CastRay(const MATHVECTOR<float,3> & origin,const MATHVECTOR<float,3> & direction,float seglen,MATHVECTOR<float,3> & outtri,const BEZIER * & colpatch,MATHVECTOR<float,3> & normal) const159 bool TRACK::CastRay(
160 const MATHVECTOR<float,3> & origin,
161 const MATHVECTOR<float,3> & direction,
162 float seglen, MATHVECTOR<float,3> & outtri,
163 const BEZIER * & colpatch,
164 MATHVECTOR<float,3> & normal) const
165 {
166 bool col = false;
167 for (list <ROADSTRIP>::const_iterator i = roads.begin(); i != roads.end(); ++i)
168 {
169 MATHVECTOR<float,3> coltri, colnorm;
170 const BEZIER * colbez = NULL;
171 if (i->Collide(origin, direction, seglen, coltri, colbez, colnorm))
172 {
173 if (!col || (coltri-origin).Magnitude() < (outtri-origin).Magnitude())
174 {
175 outtri = coltri;
176 normal = colnorm;
177 colpatch = colbez;
178 }
179 col = true;
180 }
181 }
182
183 return col;
184 }
185
FindBezierAtOffset(const BEZIER * bezier,int offset) const186 optional <const BEZIER *> ROADSTRIP::FindBezierAtOffset(const BEZIER * bezier, int offset) const
187 {
188 list <ROADPATCH>::const_iterator it = patches.end(); //this iterator will hold the found ROADPATCH
189
190 //search for the roadpatch containing the bezier and store an iterator to it in "it"
191 for (list <ROADPATCH>::const_iterator i = patches.begin(); i != patches.end(); ++i)
192 {
193 if (&i->GetPatch() == bezier)
194 {
195 it = i;
196 break;
197 }
198 }
199
200 if (it == patches.end())
201 return optional <const BEZIER *>(); //return nothing
202 else
203 {
204 //now do the offset
205 int curoffset = offset;
206 while (curoffset != 0)
207 {
208 if (curoffset < 0)
209 {
210 //why is this so difficult? all i'm trying to do is make the iterator loop around
211 list <ROADPATCH>::const_reverse_iterator rit(it);
212 if (rit == patches.rend())
213 rit = patches.rbegin();
214 ++rit;
215 if (rit == patches.rend())
216 rit = patches.rbegin();
217 it = rit.base();
218 if (it == patches.end())
219 it = patches.begin();
220
221 ++curoffset;
222 }
223 else if (curoffset > 0)
224 {
225 ++it;
226 if (it == patches.end())
227 it = patches.begin();
228
229 --curoffset;
230 }
231 }
232
233 assert(it != patches.end());
234 return optional <const BEZIER *>(&it->GetPatch());
235 }
236 }
237