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