Commit f1402849e5be2c2d9ce26a0d7f4c74b5748b8a74

Authored by dmayerich
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.

CHECK_OPENGL_ERROR.h 0 โ†’ 100755
  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
... ...
PerformanceDataTemplate.h 0 โ†’ 100755
  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 +//-------------------------------------------------------------------------------
... ...
cudaHandleError.h 0 โ†’ 100755
  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
... ...
cuda_callable.h 0 โ†’ 100644
  1 +++ a/cuda_callable.h
  1 +#ifndef CUDA_CALLABLE
  2 +
  3 +//define the CUDA_CALLABLE macro (will prefix all members)
  4 +#ifdef __CUDACC__
  5 +#define CUDA_CALLABLE __host__ __device__
  6 +#else
  7 +#define CUDA_CALLABLE
  8 +#endif
  9 +
  10 +#endif
... ...
objJedi.cpp 0 โ†’ 100755
  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
... ...
objJedi.h 0 โ†’ 100755
  1 +++ a/objJedi.h
  1 +#ifndef OBJJEDI_H
  2 +#define OBJJEDI_H
  3 +
  4