Commit f1402849e5be2c2d9ce26a0d7f4c74b5748b8a74
0 parents
renewed commit
Showing
101 changed files
with
25830 additions
and
0 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 101 files are displayed.
1 | +++ a/CHECK_OPENGL_ERROR.h | |
1 | +#ifndef RTS_OPENGL_ERROR | |
2 | +#define RTS_OPENGL_ERROR | |
3 | + | |
4 | +#include <stdio.h> | |
5 | +#include <GL/gl.h> | |
6 | +#include <GL/glu.h> | |
7 | + | |
8 | +#define CHECK_OPENGL_ERROR \ | |
9 | +{ GLenum error; \ | |
10 | + while ( (error = glGetError()) != GL_NO_ERROR) { \ | |
11 | + printf( "OpenGL ERROR: %s\nCHECK POINT: %s (line %d)\n", gluErrorString(error), __FILE__, __LINE__ ); \ | |
12 | + } \ | |
13 | +} | |
14 | + | |
15 | +#endif | |
0 | 16 | \ No newline at end of file | ... | ... |
1 | +++ a/PerformanceDataTemplate.h | |
1 | +// add the following to a cpp file: | |
2 | +// PerformanceData PD; | |
3 | + | |
4 | + | |
5 | +#pragma once | |
6 | +#include <ostream> | |
7 | +using namespace std; | |
8 | + | |
9 | +enum PerformanceDataType | |
10 | +{ | |
11 | + PD_DISPLAY=0, | |
12 | + PD_SPS, | |
13 | + PD_UNUSED0, | |
14 | + | |
15 | + //my stuff | |
16 | + SIMULATE_SPECTRUM, | |
17 | + SIMULATE_GPU, | |
18 | + KRAMERS_KRONIG, | |
19 | + | |
20 | + | |
21 | + | |
22 | + //end my stuff | |
23 | + PERFORMANCE_DATA_TYPE_COUNT | |
24 | +}; | |
25 | + | |
26 | +static char PDTypeNames[][255] = { | |
27 | + "Display ", | |
28 | + "Simulation Total ", | |
29 | + " ----------------- ", | |
30 | + //my stuff | |
31 | + "Simulate Spectrum ", | |
32 | + " GPU Portion ", | |
33 | + "Kramers-Kronig ", | |
34 | + | |
35 | + //end my stuff | |
36 | + | |
37 | +}; | |
38 | +#ifdef WIN32 | |
39 | +#include <stdio.h> | |
40 | +#include <windows.h> | |
41 | +#include <float.h> | |
42 | + | |
43 | +#include <iostream> | |
44 | +#include <iomanip> | |
45 | + | |
46 | +//------------------------------------------------------------------------------- | |
47 | + | |
48 | +class PerformanceData | |
49 | +{ | |
50 | +public: | |
51 | + PerformanceData() { ClearAll(); QueryPerformanceFrequency(&cps); } | |
52 | + ~PerformanceData(){} | |
53 | + | |
54 | + void ClearAll() | |
55 | + { | |
56 | + for ( int i=0; i<PERFORMANCE_DATA_TYPE_COUNT; i++ ) { | |
57 | + for ( int j=0; j<256; j++ ) times[i][j] = 0; | |
58 | + pos[i] = 0; | |
59 | + minTime[i] = 0xFFFFFFFF; | |
60 | + maxTime[i] = 0; | |
61 | + totalTime[i] = 0; | |
62 | + dataReady[i] = false; | |
63 | + } | |
64 | + } | |
65 | + | |
66 | + void StartTimer( int type ) { QueryPerformanceCounter( &startTime[type] );} | |
67 | + void EndTimer( int type ) { | |
68 | + LARGE_INTEGER endTime; | |
69 | + QueryPerformanceCounter( &endTime ); | |
70 | + double t = (double)(endTime.QuadPart - startTime[type].QuadPart); | |
71 | + //unsigned int t = GetTickCount() - startTime[type]; | |
72 | + if ( t < minTime[type] ) minTime[type] = t; | |
73 | + if ( t > maxTime[type] ) maxTime[type] = t; | |
74 | + totalTime[type] -= times[type][ pos[type] ]; | |
75 | + times[type][ pos[type] ] = t; | |
76 | + totalTime[type] += t; | |
77 | + pos[type]++; | |
78 | + if ( pos[type] == 0 ) dataReady[type] = true; | |
79 | + } | |
80 | + | |
81 | + void PrintResult( ostream &os,int i=PERFORMANCE_DATA_TYPE_COUNT) | |
82 | + { | |
83 | + os.setf(ios::fixed); | |
84 | + if ((i<PERFORMANCE_DATA_TYPE_COUNT)&&(i>=0)){ | |
85 | + double a = GetAvrgTime(i); | |
86 | + if ( a ) | |
87 | + os<< PDTypeNames[i]<<" : avrg="<<setw(8)<<setprecision(3)<<a<<"\tmin="<<setw(8)<<setprecision(3)<< GetMinTime(i) <<"\tmax="<<setw(8)<<setprecision(3)<< GetMaxTime(i) <<endl ; | |
88 | + else | |
89 | + os<< PDTypeNames[i]<<" : avrg= -----\tmin= -----\tmax= -----"<<endl; | |
90 | + } | |
91 | + } | |
92 | + | |
93 | + void PrintResults( ostream &os) | |
94 | + { | |
95 | + for ( int i=0; i<PERFORMANCE_DATA_TYPE_COUNT; i++ ) | |
96 | + PrintResult(os,i); | |
97 | + } | |
98 | + | |
99 | + double GetLastTime( int type ) { return times[type][pos[type]]; } | |
100 | + double GetAvrgTime( int type ) { double a = 1000.0 * totalTime[type] / (float)cps.QuadPart / ( (dataReady[type]) ? 256.0 : (double)pos[type] ); return (_finite(a))? a:0; } | |
101 | + double GetMinTime( int type ) { return 1000.0 * minTime[type] / (float)cps.LowPart; } | |
102 | + double GetMaxTime( int type ) { return 1000.0 * maxTime[type] / (float)cps.LowPart; } | |
103 | + | |
104 | +private: | |
105 | + double times[PERFORMANCE_DATA_TYPE_COUNT][256]; | |
106 | + unsigned char pos[PERFORMANCE_DATA_TYPE_COUNT]; | |
107 | + LARGE_INTEGER startTime[PERFORMANCE_DATA_TYPE_COUNT]; | |
108 | + double minTime[ PERFORMANCE_DATA_TYPE_COUNT ]; | |
109 | + double maxTime[ PERFORMANCE_DATA_TYPE_COUNT ]; | |
110 | + double totalTime[ PERFORMANCE_DATA_TYPE_COUNT ]; | |
111 | + bool dataReady[ PERFORMANCE_DATA_TYPE_COUNT ]; | |
112 | + LARGE_INTEGER cps; | |
113 | +}; | |
114 | + | |
115 | +//------------------------------------------------------------------------------- | |
116 | +#else | |
117 | + | |
118 | +class PerformanceData{ | |
119 | +public: | |
120 | + PerformanceData() {;}; | |
121 | + ~PerformanceData(){;}; | |
122 | + void ClearAll(){;}; | |
123 | + void StartTimer( int type ) {;}; | |
124 | + void EndTimer( int type ) {;}; | |
125 | + void PrintResults( ostream &os){;}; | |
126 | + void PrintResult( ostream &os, int i=PERFORMANCE_DATA_TYPE_COUNT){;}; | |
127 | + double GetLastTime( int type ) { return 0.0; }; | |
128 | + double GetAvrgTime( int type ) { return 0.0; }; | |
129 | + double GetMinTime( int type ) { return 0.0; }; | |
130 | + double GetMaxTime( int type ) { return 0.0; }; | |
131 | +}; | |
132 | + | |
133 | +#endif | |
134 | +//------------------------------------------------------------------------------- | |
135 | + | |
136 | +extern PerformanceData PD; | |
137 | + | |
138 | +//------------------------------------------------------------------------------- | ... | ... |
1 | +++ a/cudaHandleError.h | |
1 | +#include <stdio.h> | |
2 | +#include "cuda_runtime.h" | |
3 | +#include "device_launch_parameters.h" | |
4 | + | |
5 | +#ifndef CUDA_HANDLE_ERROR_H | |
6 | +#define CUDA_HANDLE_ERROR_H | |
7 | + | |
8 | +//handle error macro | |
9 | +static void HandleError( cudaError_t err, const char *file, int line ) { | |
10 | + if (err != cudaSuccess) { | |
11 | + FILE* outfile = fopen("cudaErrorLog.txt", "w"); | |
12 | + fprintf(outfile, "%s in %s at line %d\n", cudaGetErrorString( err ), file, line ); | |
13 | + fclose(outfile); | |
14 | + exit( EXIT_FAILURE ); | |
15 | + printf("%s in %s at line %d\n", cudaGetErrorString( err ), file, line ); | |
16 | + } | |
17 | +} | |
18 | +#define HANDLE_ERROR( err ) (HandleError( err, __FILE__, __LINE__ )) | |
19 | + | |
20 | +static cudaEvent_t tStartEvent; | |
21 | +static cudaEvent_t tStopEvent; | |
22 | +static void gpuStartTimer() | |
23 | +{ | |
24 | + //set up timing events | |
25 | + cudaEventCreate(&tStartEvent); | |
26 | + cudaEventCreate(&tStopEvent); | |
27 | + cudaEventRecord(tStartEvent, 0); | |
28 | +} | |
29 | + | |
30 | +static float gpuStopTimer() | |
31 | +{ | |
32 | + cudaEventRecord(tStopEvent, 0); | |
33 | + cudaEventSynchronize(tStopEvent); | |
34 | + float elapsedTime; | |
35 | + cudaEventElapsedTime(&elapsedTime, tStartEvent, tStopEvent); | |
36 | + cudaEventDestroy(tStartEvent); | |
37 | + cudaEventDestroy(tStopEvent); | |
38 | + return elapsedTime; | |
39 | +} | |
40 | + | |
41 | +#endif | ... | ... |
1 | +++ a/objJedi.cpp | |
1 | +/*BUG NOTES | |
2 | +The standard function calls for inserting vertices don't work anymore. I've fixed points | |
3 | +but everything beyond that has to be updated. | |
4 | +*/ | |
5 | + | |
6 | +#include "objJedi.h" | |
7 | +#include "rtsvector3D.h" | |
8 | +#include "rtspoint3D.h" | |
9 | +#include <string> | |
10 | +//variable for use in global functions | |
11 | +rtsOBJ g_OBJ; | |
12 | + | |
13 | +/********UTILITY METHODS*******************************/ | |
14 | +void rtsOBJ::Scale(float scale_x, float scale_y, float scale_z) | |
15 | +{ | |
16 | + vector<vertex_position>::iterator i; | |
17 | + for(i = v_list.begin(); i!= v_list.end(); i++) | |
18 | + { | |
19 | + (*i).x *= scale_x; | |
20 | + (*i).y *= scale_y; | |
21 | + (*i).z *= scale_z; | |
22 | + } | |
23 | +} | |
24 | + | |
25 | +void rtsOBJ::Translate(float trans_x, float trans_y, float trans_z) | |
26 | +{ | |
27 | + vector<vertex_position>::iterator i; | |
28 | + for(i = v_list.begin(); i!= v_list.end(); i++) | |
29 | + { | |
30 | + (*i).x += trans_x; | |
31 | + (*i).y += trans_y; | |
32 | + (*i).z += trans_z; | |
33 | + } | |
34 | + | |
35 | +} | |
36 | + | |
37 | +float rtsOBJ::GetDistance(float x, float y, float z) | |
38 | +{ | |
39 | + //gets the distance between the specified point and the nearest surface of the OBJ | |
40 | + //currently only works for lines | |
41 | + | |
42 | + //cout<<"Primitives: "<<primitives.size()<<endl; | |
43 | + int num_primitives = primitives.size(); | |
44 | + point3D<double> p0, p1, p2; | |
45 | + double min_dist = 255; | |
46 | + double dist, numerator, denominator; | |
47 | + int p, l; | |
48 | + vector3D<double> v, w; | |
49 | + double c1, c2, b; | |
50 | + point3D<double> Pb; | |
51 | + | |
52 | + //for each line | |
53 | + for(l=0; l<num_primitives; l++) | |
54 | + { | |
55 | + if(primitives[l].type & OBJ_LINES) | |
56 | + { | |
57 | + //for each point | |
58 | + for(p = 1; p<primitives[l].p.size(); p++) | |
59 | + { | |
60 | + | |
61 | + vertex_position v1 = v_list[primitives[l].p[p-1].v]; | |
62 | + vertex_position v2 = v_list[primitives[l].p[p].v]; | |
63 | + p1.x = v1.x; | |
64 | + p1.y = v1.y; | |
65 | + p1.z = v1.z; | |
66 | + p2.x = v2.x; | |
67 | + p2.y = v2.y; | |
68 | + p2.z = v2.z; | |
69 | + | |
70 | + p0.x = x; | |
71 | + p0.y = y; | |
72 | + p0.z = z; | |
73 | + | |
74 | + v = p2 - p1; | |
75 | + w = p0 - p1; | |
76 | + if((c1 = w*v) <= 0) | |
77 | + dist = (p1 - p0).Length(); | |
78 | + else if((c2 = v*v) <= c1) | |
79 | + dist = (p2 - p0).Length(); | |
80 | + else | |
81 | + { | |
82 | + b = c1/c2; | |
83 | + Pb = p1 + b*v; | |
84 | + dist = (Pb - p0).Length(); | |
85 | + } | |
86 | + if(dist < min_dist) | |
87 | + min_dist = dist; | |
88 | + | |
89 | + | |
90 | + | |
91 | + } | |
92 | + } | |
93 | + } | |
94 | + //cout<<"---------------------------------------------"<<endl; | |
95 | + | |
96 | + return min_dist; | |
97 | + | |
98 | + | |
99 | +} | |
100 | + | |
101 | +/********CLASS METHOD DEFINITIONS**********************/ | |
102 | +//constructors | |
103 | + | |
104 | +//constructor | |
105 | +rtsOBJ::rtsOBJ() | |
106 | +{ | |
107 | + g_CurrentMode = OBJ_NONE; | |
108 | + g_NumVertices = 0; | |
109 | + g_AttributeMask = 0x0; | |
110 | + g_AttributeResetMask = 0x0; | |
111 | + g_LatestVT = 0; | |
112 | + g_LatestVN = 0; | |
113 | + | |
114 | + m_bounds.min.x = m_bounds.min.y = m_bounds.min.z = 99999; | |
115 | + m_bounds.max.x = m_bounds.max.y = m_bounds.max.z = -99999; | |
116 | + | |
117 | + current_primitive_mask = 0x0; | |
118 | +} | |
119 | + | |
120 | +void rtsOBJ::CopyOBJ(const rtsOBJ& obj) | |
121 | +{ | |
122 | + current_vt = obj.current_vt; | |
123 | + current_vn = obj.current_vn; | |
124 | + vt_changed = obj.vt_changed; //true if a new vt or vn was inserted since the last vertex | |
125 | + vn_changed = obj.vn_changed; | |
126 | + current_primitive_mask = obj.current_primitive_mask; //defines what coordinates are being used by the current primitive | |
127 | + //global variable storing the current render mode | |
128 | + g_CurrentMode = obj.g_CurrentMode; | |
129 | + //output file stream | |
130 | + //g_objFile = obj.g_objFile; | |
131 | + //obj file object | |
132 | + //objData g_OBJ; | |
133 | + //number of vertices since the last BEGIN | |
134 | + g_NumVertices = obj.g_NumVertices; | |
135 | + /*Attribute mask. This indicates what attributes are stored for each vertex. | |
136 | + Only a single mask applies to each vertex between objBegin() and objEnd(). The | |
137 | + attribute mask is flipped the first time an attribute is set but it is fixed after | |
138 | + the first vertex is passed.*/ | |
139 | + g_AttributeMask = obj.g_AttributeMask; | |
140 | + /*Attribute reset mask. This indicates whether or not an attribute has been | |
141 | + reset since the last vertex was rendered. This applies to OBJ_VT and OBJ_VN*/ | |
142 | + g_AttributeResetMask = obj.g_AttributeResetMask; | |
143 | + //latest texture coordinate sent | |
144 | + g_LatestVT = obj.g_LatestVT; | |
145 | + //latest vertex normal sent | |
146 | + g_LatestVN = obj.g_LatestVN; | |
147 | + m_bounds = obj.m_bounds; | |
148 | + | |
149 | + | |
150 | + v_list = obj.v_list; | |
151 | + vt_list = obj.vt_list; | |
152 | + vn_list = obj.vn_list; | |
153 | + primitives = obj.primitives; | |
154 | + | |
155 | + points = obj.points; | |
156 | + lines = obj.lines; | |
157 | + faces = obj.faces; | |
158 | +} | |
159 | + | |
160 | +//opens an obj file for rendering | |
161 | +OBJint rtsOBJ::objOpen(const char* filename) | |
162 | +{ | |
163 | + g_objFile.open(filename); | |
164 | + return OBJ_OK; | |
165 | +} | |
166 | + | |
167 | +//close the obj file | |
168 | +OBJint rtsOBJ::objClose() | |
169 | +{ | |
170 | + //TODO: write obj data | |
171 | + f_OutputVertices(); | |
172 | + f_OutputTextureCoordinates(); | |
173 | + f_OutputVertexNormals(); | |
174 | + f_OutputPoints(); | |
175 | + f_OutputLines(); | |
176 | + f_OutputFaces(); | |
177 | + | |
178 | + //close the file | |
179 | + g_objFile.close(); | |
180 | + | |
181 | + //delete all of the data from the global object | |
182 | + f_ClearAll(); | |
183 | + return OBJ_OK; | |
184 | +} | |
185 | + | |
186 | +OBJint rtsOBJ::objBegin(OBJint mode) | |
187 | +{ | |
188 | + //make sure that we aren't currently rendering | |
189 | + if(g_CurrentMode != OBJ_NONE) | |
190 | + return OBJ_ERROR; | |
191 | + //make sure that the given mode is valid | |
192 | + if(mode < OBJ_POINTS || mode > OBJ_POLYGON) | |
193 | + return OBJ_ERROR; | |
194 | + | |
195 | + //otherwise, go ahead and set the mode | |
196 | + g_CurrentMode = mode; | |
197 | + //set the number of vertices to zero | |
198 | + g_NumVertices = 0; | |
199 | + | |
200 | + //reset the current state primitive state | |
201 | + current_primitive_mask = 0x0; | |
202 | + | |
203 | + return OBJ_OK; | |
204 | +} | |
205 | + | |
206 | +OBJint rtsOBJ::objEnd() | |
207 | +{ | |
208 | + OBJint error = OBJ_OK; | |
209 | + //check to make sure the number of rendered vertices is valid for the current mode | |
210 | + switch(g_CurrentMode) | |
211 | + { | |
212 | + case OBJ_NONE: | |
213 | + //can't quit if we haven't started | |
214 | + error = OBJ_ERROR; | |
215 | + break; | |
216 | + case OBJ_LINES: | |
217 | + //if less than two vertices or an odd number of vertices | |
218 | + if(g_NumVertices < 2 || g_NumVertices%2 != 0) | |
219 | + { | |
220 | + //if there wasn't a vertex at all | |
221 | + if(g_NumVertices == 0) | |
222 | + error = OBJ_ERROR; | |
223 | + //if there was at least one vertex | |
224 | + else | |
225 | + { | |
226 | + //pop the last line off the list | |
227 | + primitives.pop_back(); | |
228 | + lines.pop_back(); | |
229 | + error = OBJ_ERROR; | |
230 | + } | |
231 | + } | |
232 | + break; | |
233 | + case OBJ_LINE_STRIP: | |
234 | + //if less than two vertices | |
235 | + if(g_NumVertices < 2) | |
236 | + { | |
237 | + //if there wasn't a vertex at all | |
238 | + if(g_NumVertices == 0) | |
239 | + error = OBJ_ERROR; | |
240 | + //if there was at least one vertex | |
241 | + else | |
242 | + { | |
243 | + //pop the last line off the list | |
244 | + primitives.pop_back(); | |
245 | + lines.pop_back(); | |
246 | + error = OBJ_ERROR; | |
247 | + } | |
248 | + } | |
249 | + break; | |
250 | + case OBJ_LINE_LOOP: | |
251 | + //if less than three vertices | |
252 | + if(g_NumVertices < 3) | |
253 | + { | |
254 | + //pop the last line off the list | |
255 | + primitives.pop_back(); | |
256 | + lines.pop_back(); | |
257 | + error = OBJ_ERROR; | |
258 | + } | |
259 | + //connect the first and last points | |
260 | + else | |
261 | + { | |
262 | + error = f_TerminateLineLoop(); | |
263 | + } | |
264 | + break; | |
265 | + case OBJ_TRIANGLES: | |
266 | + //if less than three vertices or not a power of three | |
267 | + if(g_NumVertices < 3 || g_NumVertices%3 !=0) | |
268 | + { | |
269 | + primitives.pop_back(); | |
270 | + faces.pop_back(); | |
271 | + error = OBJ_ERROR; | |
272 | + } | |
273 | + break; | |
274 | + case OBJ_TRIANGLE_STRIP: | |
275 | + //if less than three vertices | |
276 | + if(g_NumVertices < 3) | |
277 | + { | |
278 | + primitives.pop_back(); | |
279 | + faces.pop_back(); | |
280 | + error = OBJ_ERROR; | |
281 | + } | |
282 | + break; | |
283 | + case OBJ_TRIANGLE_FAN: | |
284 | + //if less than three vertices | |
285 | + if(g_NumVertices < 3) | |
286 | + { | |
287 | + primitives.pop_back(); | |
288 | + faces.pop_back(); | |
289 | + error = OBJ_ERROR; | |
290 | + } | |
291 | + break; | |
292 | + case OBJ_QUADS: | |
293 | + if(g_NumVertices < 4 || g_NumVertices%4 != 0) | |
294 | + { | |
295 | + primitives.pop_back(); | |
296 | + faces.pop_back(); | |
297 | + error = OBJ_ERROR; | |
298 | + } | |
299 | + break; | |
300 | + case OBJ_QUAD_STRIP: | |
301 | + //has to be at least 4 vertices and an even number | |
302 | + if(g_NumVertices < 4 || g_NumVertices%2 != 0) | |
303 | + { | |
304 | + primitives.pop_back(); | |
305 | + faces.pop_back(); | |
306 | + error = OBJ_ERROR; | |
307 | + } | |
308 | + break; | |
309 | + case OBJ_POLYGON: | |
310 | + //has to be at least three vertices | |
311 | + if(g_NumVertices < 3) | |
312 | + { | |
313 | + primitives.pop_back(); | |
314 | + faces.pop_back(); | |
315 | + error = OBJ_ERROR; | |
316 | + } | |
317 | + break; | |
318 | + } | |
319 | + | |
320 | + //reset the attribute mask | |
321 | + g_AttributeMask = 0x0; | |
322 | + //just for closure, reset the attribute reset mask | |
323 | + g_AttributeResetMask = 0x0; | |
324 | + //stop rendering | |
325 | + g_CurrentMode = OBJ_NONE; | |
326 | + return error; | |
327 | +} | |
328 | + | |
329 | +OBJint rtsOBJ::f_InsertVertexf(float x, float y, float z, float w, unsigned char mask) | |
330 | +{ | |
331 | + //make sure we're rendering | |
332 | + if(g_CurrentMode == OBJ_NONE) | |
333 | + return OBJ_ERROR; | |
334 | + | |
335 | + //insert the vertex into the vertex vector | |
336 | + vertex_position v; | |
337 | + v.x = x; v.y = y; v.z=z; v.w=w; v.mask = mask; | |
338 | + v_list.push_back(v); | |
339 | + f_AdjustExtents(v); //set the bounding box | |
340 | + //insert texture coordinate and normal if specified for this primitive | |
341 | + if((current_primitive_mask & OBJ_VT) && (vt_changed)) | |
342 | + vt_list.push_back(current_vt); | |
343 | + if((current_primitive_mask & OBJ_VN) && (vn_changed)) | |
344 | + vn_list.push_back(current_vn); | |
345 | + | |
346 | + | |
347 | + //increment the number of vertices inserted | |
348 | + g_NumVertices++; | |
349 | + | |
350 | + //handle each case of the vertex creation individually | |
351 | + OBJint error = OBJ_OK; | |
352 | + switch(g_CurrentMode) | |
353 | + { | |
354 | + case OBJ_POINTS: | |
355 | + error = f_InsertPointVertex(); | |
356 | + break; | |
357 | + case OBJ_LINES: | |
358 | + error = f_InsertLineVertex(); | |
359 | + break; | |
360 | + case OBJ_LINE_LOOP: | |
361 | + error = f_InsertLineLoopVertex(); | |
362 | + break; | |
363 | + case OBJ_LINE_STRIP: | |
364 | + error = f_InsertLineStripVertex(); | |
365 | + break; | |
366 | + case OBJ_TRIANGLES: | |
367 | + error = f_InsertTriangleVertex(); | |
368 | + break; | |
369 | + case OBJ_TRIANGLE_STRIP: | |
370 | + error = f_InsertTriangleStripVertex(); | |
371 | + break; | |
372 | + case OBJ_TRIANGLE_FAN: | |
373 | + error = f_InsertTriangleFanVertex(); | |
374 | + break; | |
375 | + case OBJ_QUADS: | |
376 | + error = f_InsertQuadVertex(); | |
377 | + break; | |
378 | + case OBJ_QUAD_STRIP: | |
379 | + error = f_InsertQuadStripVertex(); | |
380 | + break; | |
381 | + case OBJ_POLYGON: | |
382 | + error = f_InsertPolygonVertex(); | |
383 | + break; | |
384 | + } | |
385 | + //set the reset mask to zero | |
386 | + g_AttributeResetMask = 0x0; | |
387 | + | |
388 | + //set the attribute mask to include vertex position | |
389 | + g_AttributeMask = g_AttributeMask | OBJ_V; | |
390 | + | |
391 | + //return the result of the insertion | |
392 | + return error; | |
393 | +} | |
394 | + | |
395 | +OBJint rtsOBJ::objVertex1f(float x) | |
396 | +{ | |
397 | + return f_InsertVertexf(x, 0.0, 0.0, 0.0, OBJ_V_X); | |
398 | +} | |
399 | + | |
400 | +OBJint rtsOBJ::objVertex2f(float x, float y) | |
401 | +{ | |
402 | + return f_InsertVertexf(x, y, 0.0, 0.0, OBJ_V_X | OBJ_V_Y); | |
403 | +} | |
404 | + | |
405 | +OBJint rtsOBJ::objVertex3f(float x, float y, float z) | |
406 | +{ | |
407 | + return f_InsertVertexf(x, y, z, 0.0, OBJ_V_X | OBJ_V_Y | OBJ_V_Z); | |
408 | + | |
409 | +} | |
410 | + | |
411 | +OBJint rtsOBJ::objVertex4f(float x, float y, float z, float w) | |
412 | +{ | |
413 | + return f_InsertVertexf(x, y, z, w, OBJ_V_X | OBJ_V_Y | OBJ_V_Z | OBJ_V_W); | |
414 | +} | |
415 | + | |
416 | +OBJint rtsOBJ::objNormal3f(float i, float j, float k) | |
417 | +{ | |
418 | + return f_InsertNormalf(i, j, k, OBJ_VN_I | OBJ_VN_J | OBJ_VN_K); | |
419 | +} | |
420 | +OBJint rtsOBJ::objNormal2f(float i, float j) | |
421 | +{ | |
422 | + return f_InsertNormalf(i, j, 0.0, OBJ_VN_I | OBJ_VN_J); | |
423 | +} | |
424 | + | |
425 | +OBJint rtsOBJ::objNormal1f(float i) | |
426 | +{ | |
427 | + return f_InsertNormalf(i, 0.0, 0.0, OBJ_VN_I); | |
428 | +} | |
429 | + | |
430 | +OBJint rtsOBJ::f_InsertNormalf(float i, float j, float k, unsigned char mask) | |
431 | +{ | |
432 | + /*DEPRECATED | |
433 | + //if the mode is not rendering faces, there is an error | |
434 | + if(g_CurrentMode < OBJ_TRIANGLES) | |
435 | + return OBJ_ERROR; | |
436 | + //if the normal attribute flag is not set, set it (as long as a vertex hasn't been written) | |
437 | + if(!(g_AttributeMask & OBJ_VN)) | |
438 | + { | |
439 | + //if a vertex has been rendered, then we can't change the attribute, so exit | |
440 | + if(g_NumVertices > 0) | |
441 | + return OBJ_ERROR; | |
442 | + else | |
443 | + //otherwise, just set the attribute flag | |
444 | + g_AttributeMask = g_AttributeMask | OBJ_VN; | |
445 | + } | |
446 | + | |
447 | + | |
448 | + //insert the new normal into the normal list for the file | |
449 | + vertex_normal new_vn; | |
450 | + new_vn.i = i; new_vn.j = j; new_vn.k = k; | |
451 | + new_vn.mask = mask; | |
452 | + vn_list.push_back(new_vn); | |
453 | + */ | |
454 | + current_vn.i = i; //set the current texture state to the given coordinates | |
455 | + current_vn.j = j; | |
456 | + current_vn.k = k; | |
457 | + current_vn.mask = mask; //set the mask as appropriate | |
458 | + vn_changed = true; //the texture coordinate state has changed | |
459 | + current_primitive_mask = current_primitive_mask | OBJ_VN; //the current primitive now uses texture coordinates (if it didn't previously) | |
460 | + | |
461 | + return OBJ_OK; | |
462 | +} | |
463 | + | |
464 | +OBJint rtsOBJ::objTexCoord3f(float u, float v, float w) | |
465 | +{ | |
466 | + return f_InsertTexCoordf(u, v, w, OBJ_VT_U | OBJ_VT_V | OBJ_VT_W); | |
467 | +} | |
468 | + | |
469 | +OBJint rtsOBJ::objTexCoord2f(float u, float v) | |
470 | +{ | |
471 | + return f_InsertTexCoordf(u, v, 0.0, OBJ_VT_U | OBJ_VT_V); | |
472 | +} | |
473 | + | |
474 | +OBJint rtsOBJ::objTexCoord1f(float u) | |
475 | +{ | |
476 | + return f_InsertTexCoordf(u, 0.0, 0.0, OBJ_VT_U); | |
477 | +} | |
478 | + | |
479 | +OBJint rtsOBJ::f_InsertTexCoordf(float u, float v, float w, unsigned char mask) | |
480 | +{ | |
481 | + /* | |
482 | + DEPRECATED | |
483 | + //if the normal attribute flag is not set, set it (as long as a vertex hasn't been written) | |
484 | + if(!(g_AttributeMask & OBJ_VT)) | |
485 | + { | |
486 | + //if a vertex has been rendered, then we can't change the attribute, so exit | |
487 | + if(g_NumVertices > 0) | |
488 | + return OBJ_ERROR; | |
489 | + else | |
490 | + //otherwise, just set the attribute flag | |
491 | + g_AttributeMask = g_AttributeMask | OBJ_VT; | |
492 | + } | |
493 | + | |
494 | + //insert the new texture coordinate into the list for the file | |
495 | + vertex_texture new_vt; | |
496 | + new_vt.u = u; new_vt.v = v; new_vt.w = w; | |
497 | + new_vt.mask = mask; | |
498 | + vt_list.push_back(new_vt); | |
499 | + */ | |
500 | + current_vt.u = u; //set the current texture state to the given coordinates | |
501 | + current_vt.v = v; | |
502 | + current_vt.w = w; | |
503 | + current_vt.mask = mask; //set the mask as appropriate | |
504 | + vt_changed = true; //the texture coordinate state has changed | |
505 | + current_primitive_mask = current_primitive_mask | OBJ_VT; //the current primitive now uses texture coordinates (if it didn't previously) | |
506 | + | |
507 | + return OBJ_OK; | |
508 | +} | |
509 | + | |
510 | + | |
511 | +void rtsOBJ::insertVertexPosition(float x, float y, float z, unsigned char mask) | |
512 | +{ | |
513 | + vertex_position v; | |
514 | + v.x = x; | |
515 | + v.y = y; | |
516 | + v.z = z; | |
517 | + v.mask = mask; | |
518 | + | |
519 | + v_list.push_back(v); | |
520 | +} | |
521 | + | |
522 | +void rtsOBJ::insertLine(unsigned int num_points, unsigned int* pointlist, unsigned int* normallist, unsigned int* texturelist) | |
523 | +{ | |
524 | + //create the new primitive | |
525 | + primitive line; | |
526 | + line.type = OBJ_LINES; | |
527 | + line.mask = 0; | |
528 | + | |
529 | + //set the mask based on the passed data | |
530 | + if(pointlist != NULL) | |
531 | + line.mask = line.mask | OBJ_V; | |
532 | + if(normallist != NULL) | |
533 | + line.mask = line.mask | OBJ_VN; | |
534 | + if(texturelist != NULL) | |
535 | + line.mask = line.mask | OBJ_VT; | |
536 | + | |
537 | + //insert the line | |
538 | + int v; | |
539 | + vertex new_vert; | |
540 | + for(v=0; v<num_points; v++) | |
541 | + { | |
542 | + if(pointlist) | |
543 | + new_vert.v = pointlist[v]; | |
544 | + if(normallist) | |
545 | + new_vert.vn = normallist[v]; | |
546 | + if(texturelist) | |
547 | + new_vert.vt = texturelist[v]; | |
548 | + line.p.push_back(new_vert); | |
549 | + } | |
550 | + //insert the new primitive into the list | |
551 | + primitives.push_back(line); | |
552 | +} | |
553 | +OBJint rtsOBJ::f_InsertPointVertex() | |
554 | +{ | |
555 | + //insert the most recent point into the most recent point list | |
556 | + //if this is the first vertex, create the point list | |
557 | + if(g_NumVertices == 1) | |
558 | + { | |
559 | + primitive new_p; //create the new point | |
560 | + new_p.type = OBJ_POINTS; | |
561 | + new_p.mask = current_primitive_mask; | |
562 | + points.push_back(primitives.size()); //store the primitive id in the points list | |
563 | + primitives.push_back(new_p); | |
564 | + } | |
565 | + | |
566 | + //find the id of the most recent primitive | |
567 | + unsigned int p_index = primitives.size() - 1; | |
568 | + //find the index of the recent point | |
569 | + vertex p; | |
570 | + p.v = v_list.size() - 1; | |
571 | + //insert the indices for texture coordinates and normal if necessary | |
572 | + if(primitives[p_index].mask & OBJ_VT) | |
573 | + p.vt = vt_list.size() - 1; | |
574 | + if(primitives[p_index].mask & OBJ_VN) | |
575 | + p.vn = vn_list.size() - 1; | |
576 | + | |
577 | + //insert the vertex index into the primitive's point list | |
578 | + primitives[p_index].p.push_back(p); | |
579 | + | |
580 | + //push the point into the points list if it is not the only point in the primitive | |
581 | + if(g_NumVertices > 1) | |
582 | + points.push_back(p_index); | |
583 | + | |
584 | + return OBJ_OK; | |
585 | +} | |
586 | + | |
587 | +OBJint rtsOBJ::f_InsertLineVertex() | |
588 | +{ | |
589 | + //if this is an odd vertex, create a new line | |
590 | + if(g_NumVertices%2 == 1) | |
591 | + { | |
592 | + f_CreateNewLine(); | |
593 | + } | |
594 | + | |
595 | + f_InsertNewLineVertex(); | |
596 | + | |
597 | + return OBJ_OK; | |
598 | +} | |
599 | +OBJint rtsOBJ::f_InsertLineLoopVertex() | |
600 | +{ | |
601 | + //technically, this is the same as inserting a line strip vertex | |
602 | + f_InsertLineStripVertex(); | |
603 | + return OBJ_OK; | |
604 | +} | |
605 | + | |
606 | +OBJint rtsOBJ::f_InsertLineStripVertex() | |
607 | +{ | |
608 | + if(g_NumVertices == 1) | |
609 | + { | |
610 | + f_CreateNewLine(); | |
611 | + } | |
612 | + | |
613 | + f_InsertNewLineVertex(); | |
614 | + | |
615 | + return OBJ_OK; | |
616 | +} | |
617 | + | |
618 | +OBJint rtsOBJ::f_InsertTriangleVertex() | |
619 | +{ | |
620 | + //if this is the first vertex in a triangle, create a new triangle | |
621 | + if(g_NumVertices%3 == 1) | |
622 | + { | |
623 | + f_CreateNewFace(); | |
624 | + } | |
625 | + | |
626 | + | |
627 | + f_InsertNewFaceVertex(); | |
628 | + | |
629 | + return OBJ_OK; | |
630 | +} | |
631 | +OBJint rtsOBJ::f_InsertTriangleStripVertex() | |
632 | +{ | |
633 | + //in the special case of the first three vertices, just create a triangle | |
634 | + if(g_NumVertices <4) | |
635 | + f_InsertTriangleVertex(); | |
636 | + else | |
637 | + { | |
638 | + | |
639 | + //create a new face for the new triangle | |
640 | + f_CreateNewFace(); | |
641 | + | |
642 | + //insert the last two vertices from the previous triangle | |
643 | + f_InsertPreviousFaceVertex(1); | |
644 | + f_InsertPreviousFaceVertex(2); | |
645 | + //insert the new vertex | |
646 | + f_InsertNewFaceVertex(); | |
647 | + } | |
648 | + | |
649 | + return OBJ_OK; | |
650 | +} | |
651 | +OBJint rtsOBJ::f_InsertTriangleFanVertex() | |
652 | +{ | |
653 | + //in the special case of the first three vertices, just create a triangle | |
654 | + if(g_NumVertices <4) | |
655 | + f_InsertTriangleVertex(); | |
656 | + else | |
657 | + { | |
658 | + //create a new face for the new triangle | |
659 | + f_CreateNewFace(); | |
660 | + //add the previous vertices to the face | |
661 | + f_InsertFirstFaceVertex(0); | |
662 | + f_InsertPreviousFaceVertex(2); | |
663 | + //insert the current vertex | |
664 | + f_InsertNewFaceVertex(); | |
665 | + } | |
666 | + | |
667 | + return OBJ_OK; | |
668 | +} | |
669 | +OBJint rtsOBJ::f_InsertQuadVertex() | |
670 | +{ | |
671 | + //if this is the first vertex in a quad, create a new quad | |
672 | + if(g_NumVertices%4 == 1) | |
673 | + { | |
674 | + f_CreateNewFace(); | |
675 | + } | |
676 | + | |
677 | + f_InsertNewFaceVertex(); | |
678 | + | |
679 | + return OBJ_OK; | |
680 | +} | |
681 | +OBJint rtsOBJ::f_InsertQuadStripVertex() | |
682 | +{ | |
683 | + //in the case of one of the first four vertices, just create a quad | |
684 | + if(g_NumVertices < 5) | |
685 | + f_InsertQuadVertex(); | |
686 | + //if the vertex is odd (it will be the third vertex of a quad) | |
687 | + else if(g_NumVertices%2 == 1) | |
688 | + { | |
689 | + //create a new face for the new quad | |
690 | + f_CreateNewFace(); | |
691 | + //add the previous two vertices | |
692 | + f_InsertPreviousFaceVertex(2); | |
693 | + f_InsertPreviousFaceVertex(3); | |
694 | + //add the current vertex | |
695 | + f_InsertNewFaceVertex(); | |
696 | + } | |
697 | + else | |
698 | + { | |
699 | + //if this is the last vertex of the quad, just add it | |
700 | + f_InsertNewFaceVertex(); | |
701 | + | |
702 | + } | |
703 | + return OBJ_OK; | |
704 | +} | |
705 | +OBJint rtsOBJ::f_InsertPolygonVertex() | |
706 | +{ | |
707 | + //if this is the first vertex, create the quad | |
708 | + if(g_NumVertices == 1) | |
709 | + { | |
710 | + f_CreateNewFace(); | |
711 | + } | |
712 | + f_InsertNewFaceVertex(); | |
713 | + | |
714 | + return OBJ_OK; | |
715 | +} | |
716 | + | |
717 | +OBJint rtsOBJ::f_InsertPreviousFaceVertex(unsigned int v_index) | |
718 | +{ | |
719 | + /*Finds the vertex used in the previous face with the given index and | |
720 | + inserts it into the current face. This limits the redundancy in the file | |
721 | + for re-used vertices (in strips and fans). This also transfers texture | |
722 | + and normal information.*/ | |
723 | + | |
724 | + //find the index of the previous face | |
725 | + unsigned int prev_f_index = primitives.size() - 2; | |
726 | + //find the index of the current face | |
727 | + unsigned int f_index = prev_f_index +1; | |
728 | + //add the vertex information from the previous face to this face | |
729 | + primitives[f_index].p.push_back(primitives[prev_f_index].p[v_index]); | |
730 | + | |
731 | + return OBJ_OK; | |
732 | +} | |
733 | + | |
734 | +OBJint rtsOBJ::f_InsertFirstFaceVertex(unsigned int v_index) | |
735 | +{ | |
736 | + /*Finds the vertex used in the first face (since the last objBegin()) | |
737 | + with the given index and inserts it at the end of the current face. | |
738 | + This includes texture and normal information.*/ | |
739 | + | |
740 | + //The result depends on the type of face being rendered | |
741 | + //So far, this function only applies to triangle fans | |
742 | + if(g_CurrentMode != OBJ_TRIANGLE_FAN) | |
743 | + return OBJ_ERROR; | |
744 | + | |
745 | + //calculate the number of faces that have been rendered | |
746 | + unsigned int num_faces = g_NumVertices - 2; | |
747 | + //find the index of the first face | |
748 | + unsigned int first_f_index = primitives.size() - num_faces; | |
749 | + //find the index of the current face | |
750 | + unsigned int f_index = primitives.size() - 1; | |
751 | + //transfer the vertex information from the first face to this one | |
752 | + primitives[f_index].p.push_back(primitives[first_f_index].p[v_index]); | |
753 | + | |
754 | + | |
755 | + return OBJ_OK; | |
756 | +} | |
757 | + | |
758 | +OBJint rtsOBJ::f_InsertNewFaceVertex() | |
759 | +{ | |
760 | + /*This inserts information about the current vertex into the current face*/ | |
761 | + //find the new vertex index | |
762 | + vertex p; | |
763 | + p.v = v_list.size() -1; | |
764 | + p.vt = vt_list.size() - 1; | |
765 | + p.vn = vn_list.size() -1; | |
766 | + //find the face index | |
767 | + unsigned int f_index = primitives.size() -1; | |
768 | + //INSERT VERTEX AND ATTRIBUTE DATA | |
769 | + //just add the vertex to the face | |
770 | + primitives[f_index].p.push_back(p); | |
771 | + | |
772 | + return OBJ_OK; | |
773 | +} | |
774 | + | |
775 | +OBJint rtsOBJ::f_InsertNewLineVertex() | |
776 | +{ | |
777 | + /*This inserts information about the current vertex into the current line*/ | |
778 | + //find the new vertex index | |
779 | + vertex p; | |
780 | + p.v = v_list.size() -1; | |
781 | + p.vt = vt_list.size() - 1; | |
782 | + //find the line index | |
783 | + unsigned int l_index = primitives.size() -1; | |
784 | + | |
785 | + //ADD VERTEX AND ATTRIBUTE INFORMATION | |
786 | + //add the vertex to the line | |
787 | + primitives[l_index].p.push_back(p); | |
788 | + | |
789 | + return OBJ_OK; | |
790 | +} | |
791 | + | |
792 | +OBJint rtsOBJ::f_CreateNewFace() | |
793 | +{ | |
794 | + primitive new_f; | |
795 | + new_f.type = OBJ_FACE; | |
796 | + new_f.mask = g_AttributeMask; | |
797 | + faces.push_back(primitives.size()); | |
798 | + primitives.push_back(new_f); | |
799 | + | |
800 | + | |
801 | + return OBJ_OK; | |
802 | +} | |
803 | + | |
804 | +OBJint rtsOBJ::f_CreateNewLine() | |
805 | +{ | |
806 | + primitive new_l; | |
807 | + new_l.type = OBJ_LINES; | |
808 | + new_l.mask = g_AttributeMask; | |
809 | + lines.push_back(primitives.size()); | |
810 | + primitives.push_back(new_l); | |
811 | + | |
812 | + return OBJ_OK; | |
813 | +} | |
814 | + | |
815 | + | |
816 | +OBJint rtsOBJ::f_TerminateLineLoop() | |
817 | +{ | |
818 | + /*This function just terminates the line loop by setting the last vertex | |
819 | + to the first vertex.*/ | |
820 | + if(g_CurrentMode != OBJ_LINE_LOOP) | |
821 | + return OBJ_ERROR; | |
822 | + //find the index for the current line | |
823 | + unsigned int l_index = lines.size() -1; | |
824 | + //insert the first vertex as the last vertex | |
825 | + primitives[l_index].p.push_back(primitives[l_index].p[0]); | |
826 | + | |
827 | + return OBJ_OK; | |
828 | +} | |
829 | + | |
830 | +void rtsOBJ::f_OutputVertices() | |
831 | +{ | |
832 | + //get the number of vertices in the object | |
833 | + unsigned int v_num = v_list.size(); | |
834 | + for(unsigned int i=0; i<v_num; i++) | |
835 | + { | |
836 | + g_objFile<<"v"; | |
837 | + if(v_list[i].mask & OBJ_V_X) | |
838 | + g_objFile<<" "<<v_list[i].x; | |
839 | + if(v_list[i].mask & OBJ_V_Y) | |
840 | + g_objFile<<" "<<v_list[i].y; | |
841 | + if(v_list[i].mask & OBJ_V_Z) | |
842 | + g_objFile<<" "<<v_list[i].z; | |
843 | + if(v_list[i].mask & OBJ_V_W) | |
844 | + g_objFile<<" "<<v_list[i].w; | |
845 | + g_objFile<<endl; | |
846 | + } | |
847 | + | |
848 | +} | |
849 | + | |
850 | +void rtsOBJ::f_OutputVertexNormals() | |
851 | +{ | |
852 | + //get the number of normals in the object | |
853 | + unsigned int vn_num = vn_list.size(); | |
854 | + for(unsigned int i=0; i<vn_num; i++) | |
855 | + { | |
856 | + g_objFile<<"vn "; | |
857 | + if(vn_list[i].mask & OBJ_VN_I) | |
858 | + { | |
859 | + g_objFile<<vn_list[i].i; | |
860 | + if(vn_list[i].mask & OBJ_VN_J) | |
861 | + { | |
862 | + g_objFile<<" "<<vn_list[i].j; | |
863 | + if(vn_list[i].mask & OBJ_VN_K) | |
864 | + g_objFile<<" "<<vn_list[i].k; | |
865 | + } | |
866 | + } | |
867 | + g_objFile<<endl; | |
868 | + } | |
869 | +} | |
870 | + | |
871 | +void rtsOBJ::f_OutputTextureCoordinates() | |
872 | +{ | |
873 | + //get the number of vertices in the object | |
874 | + unsigned int vt_num = vt_list.size(); | |
875 | + for(unsigned int i=0; i<vt_num; i++) | |
876 | + { | |
877 | + g_objFile<<"vt "; | |
878 | + if(vt_list[i].mask & OBJ_VT_U) | |
879 | + { | |
880 | + g_objFile<<vt_list[i].u; | |
881 | + if(vt_list[i].mask & OBJ_VT_V) | |
882 | + { | |
883 | + g_objFile<<" "<<vt_list[i].v; | |
884 | + if(vt_list[i].mask & OBJ_VT_W) | |
885 | + g_objFile<<" "<<vt_list[i].w; | |
886 | + } | |
887 | + } | |
888 | + g_objFile<<endl; | |
889 | + } | |
890 | +} | |
891 | + | |
892 | +void rtsOBJ::f_OutputPoints() | |
893 | +{ | |
894 | + /* | |
895 | + //get the number of point vectors | |
896 | + unsigned int p_num = points.size(); | |
897 | + | |
898 | + //for each point vector, output the points | |
899 | + for(unsigned int i=0; i<p_num; i++) | |
900 | + { | |
901 | + g_objFile<<"p"; | |
902 | + unsigned int v_num = points[i].p.size(); | |
903 | + for(unsigned int j=0; j<v_num; j++) | |
904 | + { | |
905 | + g_objFile<<" "<<points[i].p[j].v+1; | |
906 | + } | |
907 | + g_objFile<<endl; | |
908 | + } | |
909 | + */ | |
910 | +} | |
911 | + | |
912 | +void rtsOBJ::f_OutputLines() | |
913 | +{ | |
914 | + /* | |
915 | + //get the number of line vectors | |
916 | + unsigned int l_num = lines.size(); | |
917 | + | |
918 | + //for each line vector, output the associated points | |
919 | + for(unsigned int i=0; i<l_num; i++) | |
920 | + { | |
921 | + g_objFile<<"l"; | |
922 | + unsigned int v_num = lines[i].p.size(); | |
923 | + for(unsigned int j=0; j<v_num; j++) | |
924 | + { | |
925 | + g_objFile<<" "<<lines[i].p[j].v+1; | |
926 | + //output texture coordinate if there are any | |
927 | + if(lines[i].mask & OBJ_VT) | |
928 | + g_objFile<<"/"<<lines[i].p[j].vt+1; | |
929 | + } | |
930 | + g_objFile<<endl; | |
931 | + } | |
932 | + */ | |
933 | +} | |
934 | + | |
935 | +void rtsOBJ::f_OutputFaces() | |
936 | +{ | |
937 | + /* | |
938 | + //get the number of faces | |
939 | + unsigned int f_num = faces.size(); | |
940 | + | |
941 | + //for each face, output the associated points | |
942 | + for(unsigned int i=0; i<f_num; i++) | |
943 | + { | |
944 | + g_objFile<<"f"; | |
945 | + //get the number of face vertices | |
946 | + unsigned int v_num = faces[i].p.size(); | |
947 | + for(unsigned int j=0; j<v_num; j++) | |
948 | + { | |
949 | + g_objFile<<" "<<faces[i].p[j].v+1; | |
950 | + //if there are texture coordinates | |
951 | + if(faces[i].mask & OBJ_VT) | |
952 | + g_objFile<<"/"<<faces[i].p[j].vt+1; | |
953 | + //if there is a normal | |
954 | + if(faces[i].mask & OBJ_VN) | |
955 | + { | |
956 | + //but no texture coordinates, put an extra slash | |
957 | + if(!(faces[i].mask & OBJ_VT)) | |
958 | + g_objFile<<"/"; | |
959 | + g_objFile<<"/"<<faces[i].p[j].vn+1; | |
960 | + } | |
961 | + | |
962 | + } | |
963 | + g_objFile<<endl; | |
964 | + } | |
965 | + */ | |
966 | +} | |
967 | + | |
968 | +void rtsOBJ::f_ClearAll() | |
969 | +{ | |
970 | + rtsOBJ(); | |
971 | + //clear all data from the global obj function | |
972 | + faces.clear(); | |
973 | + lines.clear(); | |
974 | + points.clear(); | |
975 | + v_list.clear(); | |
976 | + vn_list.clear(); | |
977 | + vt_list.clear(); | |
978 | + primitives.clear(); | |
979 | +} | |
980 | + | |
981 | +/*GLOBAL FUNCTION DEFINITIONS*/ | |
982 | +//initialize the OBJ file | |
983 | +OBJint objOpen(char* filename) | |
984 | +{ | |
985 | + return g_OBJ.objOpen(filename); | |
986 | +} | |
987 | +//close the obj file | |
988 | +OBJint objClose() | |
989 | +{ | |
990 | + return g_OBJ.objClose(); | |
991 | +} | |
992 | + | |
993 | +//start rendering in a certain mode | |
994 | +OBJint objBegin(OBJint mode) | |
995 | +{ | |
996 | + return g_OBJ.objBegin(mode); | |
997 | +} | |
998 | +//stop the current rendering sequence | |
999 | +OBJint objEnd(void) | |
1000 | +{ | |
1001 | + return g_OBJ.objEnd(); | |
1002 | +} | |
1003 | +//render a vertex to the file | |
1004 | +OBJint objVertex1f(float x) | |
1005 | +{ | |
1006 | + return g_OBJ.objVertex1f(x); | |
1007 | +} | |
1008 | + | |
1009 | +OBJint objVertex2f(float x, float y) | |
1010 | +{ | |
1011 | + return g_OBJ.objVertex2f(x, y); | |
1012 | +} | |
1013 | + | |
1014 | +OBJint objVertex3f(float x, float y, float z) | |
1015 | +{ | |
1016 | + return g_OBJ.objVertex3f(x, y, z); | |
1017 | +} | |
1018 | + | |
1019 | +OBJint objVertex4f(float x, float y, float z, float w) | |
1020 | +{ | |
1021 | + return g_OBJ.objVertex4f(x, y, z, w); | |
1022 | +} | |
1023 | +//set a normal vector for a vertex | |
1024 | +OBJint objNormal3f(float i, float j, float k) | |
1025 | +{ | |
1026 | + return g_OBJ.objNormal3f(i, j, k); | |
1027 | +} | |
1028 | +OBJint objNormal2f(float i, float j) | |
1029 | +{ | |
1030 | + return g_OBJ.objNormal2f(i, j); | |
1031 | +} | |
1032 | +OBJint objNormal1f(float i) | |
1033 | +{ | |
1034 | + return g_OBJ.objNormal1f(i); | |
1035 | +} | |
1036 | +//set a texture coordinate for a vertex | |
1037 | +OBJint objTexCoord3f(float u, float v, float w) | |
1038 | +{ | |
1039 | + return g_OBJ.objTexCoord3f(u, v, w); | |
1040 | +} | |
1041 | + | |
1042 | +OBJint objTexCoord2f(float u, float v) | |
1043 | +{ | |
1044 | + return g_OBJ.objTexCoord2f(u,v); | |
1045 | +} | |
1046 | + | |
1047 | +OBJint objTexCoord1f(float u) | |
1048 | +{ | |
1049 | + return g_OBJ.objTexCoord1f(u); | |
1050 | +} | |
1051 | + | |
1052 | +OBJint rtsOBJ::f_ReadPosition(ifstream &infile) | |
1053 | +{ | |
1054 | + vertex_position new_vertex; | |
1055 | + //get each coordinate | |
1056 | + infile>>new_vertex.x; | |
1057 | + new_vertex.mask = OBJ_V_X; | |
1058 | + | |
1059 | + if(infile.peek() == ' ') | |
1060 | + { | |
1061 | + infile>>new_vertex.y; | |
1062 | + new_vertex.mask = new_vertex.mask | OBJ_V_Y; | |
1063 | + } | |
1064 | + if(infile.peek() == ' ') | |
1065 | + { | |
1066 | + infile>>new_vertex.z; | |
1067 | + new_vertex.mask = new_vertex.mask | OBJ_V_Z; | |
1068 | + } | |
1069 | + if(infile.peek() == ' ') | |
1070 | + { | |
1071 | + infile>>new_vertex.w; | |
1072 | + new_vertex.mask = new_vertex.mask | OBJ_V_W; | |
1073 | + } | |
1074 | + int c = infile.peek(); | |
1075 | + //ignore the rest of the line | |
1076 | + infile.ignore(1000, '\n'); | |
1077 | + c = infile.peek(); | |
1078 | + | |
1079 | + //cout<<"vertex read: "<<new_vertex.x<<","<<new_vertex.y<<","<<new_vertex.z<<","<<new_vertex.w<<endl; | |
1080 | + //insert the vertex into the list | |
1081 | + v_list.push_back(new_vertex); | |
1082 | + | |
1083 | + //adjust the extents of the model | |
1084 | + f_AdjustExtents(new_vertex); | |
1085 | + | |
1086 | + return OBJ_OK; | |
1087 | +} | |
1088 | + | |
1089 | +OBJint rtsOBJ::f_ReadNormal(ifstream &infile) | |
1090 | +{ | |
1091 | + vertex_normal new_normal; | |
1092 | + infile>>new_normal.i; | |
1093 | + new_normal.mask = OBJ_VN_I; | |
1094 | + //get every other component | |
1095 | + if(infile.peek() == ' ') | |
1096 | + { | |
1097 | + infile>>new_normal.j; | |
1098 | + new_normal.mask = new_normal.mask | OBJ_VN_J; | |
1099 | + } | |
1100 | + if(infile.peek() == ' ') | |
1101 | + { | |
1102 | + infile>>new_normal.k; | |
1103 | + new_normal.mask = new_normal.mask | OBJ_VN_K; | |
1104 | + } | |
1105 | + //ignore the rest of the line | |
1106 | + infile.ignore(1000, '\n'); | |
1107 | + //insert the normal | |
1108 | + vn_list.push_back(new_normal); | |
1109 | + | |
1110 | + return OBJ_OK; | |
1111 | +} | |
1112 | + | |
1113 | +OBJint rtsOBJ::f_ReadTexCoord(ifstream &infile) | |
1114 | +{ | |
1115 | + vertex_texture new_texcoord; | |
1116 | + infile>>new_texcoord.u; | |
1117 | + new_texcoord.mask = OBJ_VT_U; | |
1118 | + //get every other component | |
1119 | + if(infile.peek() == ' ') | |
1120 | + { | |
1121 | + infile>>new_texcoord.v; | |
1122 | + new_texcoord.mask = new_texcoord.mask | OBJ_VT_V; | |
1123 | + } | |
1124 | + if(infile.peek() == ' ') | |
1125 | + { | |
1126 | + infile>>new_texcoord.w; | |
1127 | + new_texcoord.mask = new_texcoord.mask | OBJ_VT_W; | |
1128 | + } | |
1129 | + | |
1130 | + //ignore the rest of the line | |
1131 | + infile.ignore(1000, '\n'); | |
1132 | + //insert the texture coordinate | |
1133 | + vt_list.push_back(new_texcoord); | |
1134 | + | |
1135 | + return OBJ_OK; | |
1136 | + | |
1137 | +} | |
1138 | + | |
1139 | +OBJint rtsOBJ::f_ReadVertex(ifstream &infile, vertex &new_point, unsigned char &mask) | |
1140 | +{ | |
1141 | + //store the line vertex | |
1142 | + infile>>new_point.v; | |
1143 | + new_point.v--; | |
1144 | + mask = OBJ_V; | |
1145 | + //new_face.v.push_back(new_v - 1); | |
1146 | + if(infile.peek() == '/') | |
1147 | + { | |
1148 | + infile.get(); | |
1149 | + //if there actually is a texcoord | |
1150 | + if(infile.peek() != '/') | |
1151 | + { | |
1152 | + infile>>new_point.vt; //get the index | |
1153 | + new_point.vt--; | |
1154 | + mask = mask | OBJ_VT; //update the mask | |
1155 | + //new_face.vt.push_back(new_vt - 1); | |
1156 | + } | |
1157 | + } | |
1158 | + //check for a normal | |
1159 | + if(infile.peek() == '/') | |
1160 | + { | |
1161 | + infile.get(); | |
1162 | + infile>>new_point.vn; //get the index | |
1163 | + new_point.vn--; | |
1164 | + mask = mask | OBJ_VN; //update the mask | |
1165 | + } | |
1166 | + | |
1167 | + return OBJ_OK; | |
1168 | +} | |
1169 | + | |
1170 | +OBJint rtsOBJ::f_ReadPrimitive(ifstream &infile, primitive_type type) | |
1171 | +{ | |
1172 | + //create a new point list | |
1173 | + primitive new_primitive; | |
1174 | + new_primitive.type = type; | |
1175 | + //until the end of the line | |
1176 | + while(infile.peek() != '\n') | |
1177 | + { | |
1178 | + //read each point | |
1179 | + if(infile.peek() == ' ') | |
1180 | + infile.get(); | |
1181 | + else | |
1182 | + { | |
1183 | + vertex new_point; | |
1184 | + f_ReadVertex(infile, new_point, new_primitive.mask); | |
1185 | + new_primitive.p.push_back(new_point); | |
1186 | + } | |
1187 | + } | |
1188 | + //ignore the rest of the line | |
1189 | + infile.ignore(1000, '\n'); | |
1190 | + | |
1191 | + //push the id of the primitive into the new list | |
1192 | + //:DEBUG: | |
1193 | + if(type == OBJ_POINTS) | |
1194 | + points.push_back(primitives.size()); | |
1195 | + else if(type == OBJ_LINES) | |
1196 | + lines.push_back(primitives.size()); | |
1197 | + else if(type == OBJ_FACE) | |
1198 | + faces.push_back(primitives.size()); | |
1199 | + | |
1200 | + primitives.push_back(new_primitive); //push the new primitive | |
1201 | + | |
1202 | + return OBJ_OK; | |
1203 | +} | |
1204 | + | |
1205 | + | |
1206 | +OBJint rtsOBJ::f_AdjustExtents(vertex_position v) | |
1207 | +{ | |
1208 | + if(v.x < m_bounds.min.x) | |
1209 | + m_bounds.min.x = v.x; | |
1210 | + if(v.y < m_bounds.min.y) | |
1211 | + m_bounds.min.y = v.y; | |
1212 | + if(v.z < m_bounds.min.z) | |
1213 | + m_bounds.min.z = v.z; | |
1214 | + | |
1215 | + if(v.x > m_bounds.max.x) m_bounds.max.x = v.x; | |
1216 | + if(v.y > m_bounds.max.y) m_bounds.max.y = v.y; | |
1217 | + if(v.z > m_bounds.max.z) m_bounds.max.z = v.z; | |
1218 | + | |
1219 | + return OBJ_OK; | |
1220 | +} | |
1221 | + | |
1222 | +OBJint rtsOBJ::f_LoadOBJ(const char* filename) | |
1223 | +{ | |
1224 | + f_ClearAll(); | |
1225 | + //open the file as a stream | |
1226 | + ifstream infile; | |
1227 | + infile.open(filename); | |
1228 | + if(!infile.is_open()) | |
1229 | + return OBJ_ERROR; | |
1230 | + | |
1231 | + unsigned int vertices = 0; | |
1232 | + | |
1233 | + string token; | |
1234 | + infile>>token; | |
1235 | + while(!infile.eof()) | |
1236 | + { | |
1237 | + //if the token is some vertex property | |
1238 | + if(token == "v") | |
1239 | + f_ReadPosition(infile); | |
1240 | + else if(token == "vn") | |
1241 | + f_ReadNormal(infile); | |
1242 | + else if(token == "vt") | |
1243 | + f_ReadTexCoord(infile); | |
1244 | + else if(token == "p") | |
1245 | + f_ReadPrimitive(infile, OBJ_POINTS); | |
1246 | + else if(token == "l") | |
1247 | + f_ReadPrimitive(infile, OBJ_LINES); | |
1248 | + else if(token == "f") | |
1249 | + f_ReadPrimitive(infile, OBJ_FACE); | |
1250 | + else | |
1251 | + infile.ignore(9999, '\n'); | |
1252 | + //vertices++; | |
1253 | + | |
1254 | + infile>>token; | |
1255 | + } | |
1256 | + | |
1257 | +} | |
1258 | + | |
1259 | +OBJint rtsOBJ::f_LoadSWC(const char* filename) | |
1260 | +{ | |
1261 | + f_ClearAll(); | |
1262 | + //open the file as a stream | |
1263 | + ifstream infile; | |
1264 | + infile.open(filename); | |
1265 | + if(!infile.is_open()) | |
1266 | + return OBJ_ERROR; | |
1267 | + | |
1268 | + vector<vertex_position> swcVertices; | |
1269 | + float token; | |
1270 | + objBegin(OBJ_LINES); | |
1271 | + while(!infile.eof()) | |
1272 | + { | |
1273 | + vertex_position v; | |
1274 | + infile>>token; //get the id | |
1275 | + infile>>token; //get the fiber type | |
1276 | + infile>>v.x; //get the node position | |
1277 | + infile>>v.y; | |
1278 | + infile>>v.z; | |
1279 | + infile>>token; //get the radius | |
1280 | + infile>>token; //get the parent | |
1281 | + | |
1282 | + //insert the node into the swc vector | |
1283 | + swcVertices.push_back(v); | |
1284 | + //now draw the line from the parent to the current node | |
1285 | + if(token != -1) | |
1286 | + { | |
1287 | + objVertex3f(swcVertices[token-1].x, swcVertices[token-1].y, swcVertices[token-1].z); | |
1288 | + objVertex3f(v.x, v.y, v.z); | |
1289 | + } | |
1290 | + } | |
1291 | + objEnd(); | |
1292 | + | |
1293 | + | |
1294 | + return OBJ_OK; | |
1295 | + | |
1296 | +} | |
1297 | +OBJint rtsOBJ::LoadFile(const char* filename) | |
1298 | +{ | |
1299 | + string strFilename = filename; | |
1300 | + int length = strFilename.length(); | |
1301 | + string extension = strFilename.substr(strFilename.length() - 3, 3); | |
1302 | + if(!extension.compare(string("obj"))) | |
1303 | + return f_LoadOBJ(filename); | |
1304 | + else if(!extension.compare(string("swc"))) | |
1305 | + return f_LoadSWC(filename); | |
1306 | + else return f_LoadOBJ(filename); | |
1307 | + | |
1308 | +} | |
1309 | + | |
1310 | +OBJint rtsOBJ::SaveFile(const char* filename) | |
1311 | +{ | |
1312 | + //open the file as a stream | |
1313 | + ofstream outfile; | |
1314 | + outfile.open(filename); | |
1315 | + if(!outfile.is_open()) | |
1316 | + return OBJ_ERROR; | |
1317 | + | |
1318 | + //output vertex positions | |
1319 | + vector<vertex_position>::iterator v; | |
1320 | + for(v=v_list.begin(); v!= v_list.end(); v++) | |
1321 | + { | |
1322 | + outfile<<"v"; | |
1323 | + if((*v).mask & OBJ_V_X) | |
1324 | + { | |
1325 | + outfile<<' '<<(*v).x; | |
1326 | + if((*v).mask & OBJ_V_Y) | |
1327 | + { | |
1328 | + outfile<<' '<<(*v).y; | |
1329 | + if((*v).mask & OBJ_V_Z) | |
1330 | + { | |
1331 | + outfile<<' '<<(*v).z; | |
1332 | + if((*v).mask & OBJ_V_W) | |
1333 | + outfile<<' '<<(*v).w; | |
1334 | + } | |
1335 | + } | |
1336 | + } | |
1337 | + outfile<<'\n'; | |
1338 | + } | |
1339 | + | |
1340 | + //output vertex texture coordinates | |
1341 | + vector<vertex_texture>::iterator vt; | |
1342 | + for(vt=vt_list.begin(); vt!= vt_list.end(); vt++) | |
1343 | + { | |
1344 | + outfile<<"vt"; | |
1345 | + if((*vt).mask & OBJ_VT_U) | |
1346 | + { | |
1347 | + outfile<<' '<<(*vt).u; | |
1348 | + if((*vt).mask & OBJ_VT_V) | |
1349 | + { | |
1350 | + outfile<<' '<<(*vt).v; | |
1351 | + if((*vt).mask & OBJ_VT_W) | |
1352 | + outfile<<' '<<(*vt).w; | |
1353 | + } | |
1354 | + } | |
1355 | + outfile<<'\n'; | |
1356 | + } | |
1357 | + | |
1358 | + //output vertex normal coordinates | |
1359 | + vector<vertex_normal>::iterator vn; | |
1360 | + for(vn=vn_list.begin(); vn!= vn_list.end(); vn++) | |
1361 | + { | |
1362 | + outfile<<"vn"; | |
1363 | + if((*vn).mask & OBJ_VN_I) | |
1364 | + { | |
1365 | + outfile<<' '<<(*vn).i; | |
1366 | + if((*vn).mask & OBJ_VN_J) | |
1367 | + { | |
1368 | + outfile<<' '<<(*vn).j; | |
1369 | + if((*vn).mask & OBJ_VN_K) | |
1370 | + outfile<<' '<<(*vn).k; | |
1371 | + } | |
1372 | + } | |
1373 | + outfile<<'\n'; | |
1374 | + } | |
1375 | + | |
1376 | + //output each primitive | |
1377 | + vector<primitive>::iterator p; | |
1378 | + vector<vertex>::iterator vert; | |
1379 | + for(p=primitives.begin(); p!= primitives.end(); p++) | |
1380 | + { | |
1381 | + switch((*p).type) | |
1382 | + { | |
1383 | + case OBJ_POINTS: | |
1384 | + outfile<<"p"; //output the points token | |
1385 | + break; | |
1386 | + case OBJ_LINES: | |
1387 | + outfile<<"l"; //output the lines token | |
1388 | + break; | |
1389 | + case OBJ_FACE: | |
1390 | + outfile<<"f"; //output the face token | |
1391 | + break; | |
1392 | + } | |
1393 | + | |
1394 | + //for each vertex in the list for the primitive | |
1395 | + for(vert = (*p).p.begin(); vert != (*p).p.end(); vert++) | |
1396 | + { | |
1397 | + outfile<<' '<<(*vert).v + 1; | |
1398 | + if((*p).mask & OBJ_VT) | |
1399 | + outfile<<'/'<<(*vert).vt + 1; | |
1400 | + if((*p).mask & OBJ_VN) | |
1401 | + { | |
1402 | + if(!((*p).mask & OBJ_VT)) | |
1403 | + outfile<<'/'; | |
1404 | + outfile<<'/'<<(*vert).vn + 1; | |
1405 | + } | |
1406 | + } | |
1407 | + outfile<<'\n'; | |
1408 | + | |
1409 | + } | |
1410 | + | |
1411 | + | |
1412 | + | |
1413 | +} | |
1414 | + | |
1415 | +//get methods | |
1416 | +unsigned int rtsOBJ::getNumVertices(){return v_list.size();} | |
1417 | +unsigned int rtsOBJ::getNumLines(){return lines.size();} | |
1418 | +unsigned int rtsOBJ::getNumFaces(){return faces.size();} | |
1419 | +unsigned int rtsOBJ::getNumPointLists(){return points.size();} | |
1420 | +unsigned int rtsOBJ::getNumTexCoords(){return vt_list.size();} | |
1421 | +unsigned int rtsOBJ::getNumNormals(){return vn_list.size();} | |
1422 | + | |
1423 | +//these functions return the coordinate index as well as the value | |
1424 | +unsigned int rtsOBJ::getNumFaceVertices(unsigned int face){return primitives[face].p.size();} | |
1425 | +unsigned int rtsOBJ::getFaceVertex(unsigned int face, unsigned int vertex){return primitives[face].p[vertex].v;} | |
1426 | +unsigned int rtsOBJ::getFaceNormal(unsigned int face, unsigned int normal){return primitives[face].p[normal].vn;} | |
1427 | +unsigned int rtsOBJ::getFaceTexCoord(unsigned int face, unsigned int texcoord){return primitives[face].p[texcoord].vt;} | |
1428 | +unsigned int rtsOBJ::getNumLineVertices(unsigned int line){return primitives[line].p.size();} | |
1429 | +unsigned int rtsOBJ::getLineVertex(unsigned int line, unsigned int vertex){return primitives[line].p[vertex].v;} | |
1430 | +unsigned int rtsOBJ::getLineTexCoord(unsigned int line, unsigned int texcoord){return primitives[line].p[texcoord].vt;} | |
1431 | +point3D<float> rtsOBJ::getVertex3d(unsigned int index) | |
1432 | +{ | |
1433 | + return point3D<float>(v_list[index].x, v_list[index].y, v_list[index].z); | |
1434 | +} | |
1435 | +point3D<float> rtsOBJ::getTexCoord3d(unsigned int index) | |
1436 | +{ | |
1437 | + return point3D<float>(vt_list[index].u, vt_list[index].v, vt_list[index].w); | |
1438 | +} | |
1439 | +point3D<float> rtsOBJ::getNormal3d(unsigned int index) | |
1440 | +{ | |
1441 | + return point3D<float>(vn_list[index].i, vn_list[index].j, vn_list[index].k); | |
1442 | +} | |
1443 | +vertex_position rtsOBJ::getVertex(unsigned int index){return v_list[index];} | |
1444 | +vertex_texture rtsOBJ::getTexCoord(unsigned int index){return vt_list[index];} | |
1445 | +vertex_normal rtsOBJ::getNormal(unsigned int index){return vn_list[index];} | |
1446 | + | |
1447 | + | |
1448 | +unsigned int rtsOBJ::getPrimitiveType(unsigned int primitive) | |
1449 | +{ | |
1450 | + /* | |
1451 | + switch(primitives[i].type) | |
1452 | + { | |
1453 | + case OBJ_POINTS: | |
1454 | + return OBJ_POINTS; | |
1455 | + break; | |
1456 | + case OBJ_LINES: | |
1457 | + return OBJ_LINES; | |
1458 | + break; | |
1459 | + case OBJ_FACE: | |
1460 | + f_RenderFace(i); | |
1461 | + break; | |
1462 | + }*/ | |
1463 | + return 0; | |
1464 | +} | |
1465 | +/****************************************************/ | |
1466 | +/*******Iterator Methods*****************************/ | |
1467 | +/****************************************************/ | |
1468 | + | |
1469 | +rtsOBJ::iterator rtsOBJ::begin() | |
1470 | +{ | |
1471 | + //create an iterator that will be returned and assign it to this OBJ | |
1472 | + iterator result; | |
1473 | + result.obj = this; | |
1474 | + result.end_object = false; | |
1475 | + result.end_primitive = false; | |
1476 | + | |
1477 | + //if there are no primitives, return the end iterator | |
1478 | + if(primitives.size() == 0) | |
1479 | + return end(); | |
1480 | + | |
1481 | + //start at the beginning of the primitive array | |
1482 | + result.primitive_index = 0; | |
1483 | + | |
1484 | + return result; | |
1485 | +} | |
1486 | + | |
1487 | +rtsOBJ::iterator rtsOBJ::end() | |
1488 | +{ | |
1489 | + //create an end iterator to return | |
1490 | + iterator result; | |
1491 | + result.obj = this; | |
1492 | + result.end_primitive = true; | |
1493 | + result.primitive_index = result.obj->primitives.size(); | |
1494 | + | |
1495 | + return result; | |
1496 | +} | |
1497 | + | |
1498 | +void rtsOBJ::iterator::operator++() | |
1499 | +{ | |
1500 | + primitive_index++; | |
1501 | + if(primitive_index >= obj->primitives.size()) | |
1502 | + (*this) = obj->end(); | |
1503 | + | |
1504 | +} | |
1505 | + | |
1506 | +bool rtsOBJ::iterator::operator ==(rtsOBJ::iterator operand) | |
1507 | +{ | |
1508 | + if(operand.primitive_index == primitive_index) | |
1509 | + return true; | |
1510 | + else return false; | |
1511 | +} | |
1512 | + | |
1513 | +bool rtsOBJ::iterator::operator !=(rtsOBJ::iterator operand) | |
1514 | +{ | |
1515 | + if(operand.primitive_index != primitive_index) | |
1516 | + return true; | |
1517 | + else return false; | |
1518 | +} | |
1519 | + | |
1520 | +unsigned int rtsOBJ::iterator::operator*() | |
1521 | +{ | |
1522 | + return primitive_index; | |
1523 | +} | |
1524 | + | |
1525 | +void rtsOBJ::iterator::print() | |
1526 | +{ | |
1527 | + cout<<"This is a test"<<endl; | |
1528 | +} | |
1529 | + | |
1530 | + | |
1531 | + | |
0 | 1532 | \ No newline at end of file | ... | ... |