#include <rModel.h>
Public Member Functions | |
rModel (const char *fileName, const char *fileName_alt="") | |
~rModel () | |
void | Render () |
Private Member Functions | |
void | Load (std::istream &s, const char *fileName) |
Private Attributes | |
rDisplayList | displayList_ |
tArray< Vec3 > | vertices |
tArray< Vec3 > | texVert |
tArray< Vec3 > | normals |
tArray< rModelFace > | modelFaces |
tArray< rModelFace > | modelTexFaces |
bool | modelTexFacesCoherent |
Definition at line 60 of file rModel.h.
rModel::rModel | ( | const char * | fileName, | |
const char * | fileName_alt = "" | |||
) |
Definition at line 242 of file rModel.cpp.
References tDirectories::Data(), in, Load(), tPath::Open(), and tERR_ERROR.
00243 { 00244 #ifndef DEDICATED 00245 // tString s; 00246 //s << "models/"; 00247 // s << fileName; 00248 00249 std::ifstream in; 00250 00251 if ( !tDirectories::Data().Open( in, fileName ) ) 00252 { 00253 if (fileName_alt){ 00254 std::ifstream in2; 00255 tDirectories::Data().Open( in2, fileName_alt ); 00256 00257 if (!in2.good()){ 00258 tERR_ERROR("\n\nModel file " << fileName_alt << " could not be found.\n" << 00259 "are you sure you are running " << tOutput("$program_name") << " in it's own directory?\n\n"); 00260 } 00261 else 00262 Load(in2,fileName_alt); 00263 } 00264 else 00265 tERR_ERROR("\n\nModel file " << fileName << " could not be found.\n" << 00266 "are you sure you are running " << tOutput("$program_name") << " in it's own directory?\n\n"); 00267 00268 } 00269 else 00270 Load(in,fileName); 00271 #endif 00272 }
rModel::~rModel | ( | ) |
Definition at line 343 of file rModel.cpp.
References tCHECK_DEST.
00343 { 00344 tCHECK_DEST; 00345 }
void rModel::Load | ( | std::istream & | s, | |
const char * | fileName | |||
) | [private] |
Definition at line 55 of file rModel.cpp.
References a, b, c, GrowingArrayBase::Len(), MAXVERT, modelFaces, modelTexFaces, modelTexFacesCoherent, Vec3::Norm(), normals, REAL, texVert, vertices, Vec3::x, x, and z.
Referenced by rModel().
00055 { 00056 00057 #ifndef DEDICATED 00058 modelTexFacesCoherent = false; 00059 bool calc_normals=true; 00060 00061 if (strstr(fileName,".mod")){ // old loader 00062 REAL xmax=-1E+32f, xmin=1E+32f; 00063 REAL zmax=-1E+32f, zmin=1E+32f; 00064 00065 while (in && !in.eof()){ 00066 char c; 00067 00068 REAL x,y,z; 00069 int A,B,C; 00070 int num; 00071 00072 in >> c; 00073 switch (c){ 00074 case('v'): 00075 in >> num >> x >> y >> z; 00076 00077 if (x > xmax) 00078 xmax = x; 00079 if (x < xmin) 00080 xmin = x; 00081 if (z > zmax) 00082 zmax = z; 00083 if (z < zmin) 00084 zmin = z; 00085 00086 vertices[num]=Vec3(x,y,z); 00087 normals[num]=Vec3(0,0,0); 00088 break; 00089 00090 case('f'): 00091 in >> A >> B >> C; 00092 modelFaces[modelFaces.Len()]=rModelFace(A,B,C); 00093 break; 00094 00095 default: 00096 break; 00097 } 00098 } 00099 00100 int i; 00101 for (i = vertices.Len()-1; i>=0; i--) 00102 { 00103 Vec3 &v = vertices[i]; 00104 texVert[i] = Vec3((v.x[0]-xmin)/(xmax-xmin), (zmax-v.x[2])/(zmax-zmin), 0); 00105 } 00106 modelTexFacesCoherent = true; 00107 for (i = modelFaces.Len()-1; i>=0; i--) 00108 { 00109 modelTexFaces[i] = modelFaces[i]; 00110 } 00111 00112 } 00113 else{ // new 3DSMax loader 00114 int offset=0; // 00115 int current_vertex=0; // 00116 00117 #define MAXVERT 10000 00118 00119 int translate[MAXVERT]; 00120 00121 enum {VERTICES,FACES} status=VERTICES; 00122 00123 int my_vert=1; 00124 00125 while(in && !in.eof()){ 00126 char c; 00127 char word[100]; 00128 in >> c; 00129 if (c=='*'){ 00130 in >> word; 00131 if (!strcmp(word,"MESH_TVERT")){ 00132 int n; 00133 REAL x,y,z; 00134 in >> n >> x >> y >> z; 00135 texVert[n]=Vec3(x,1-y,z); 00136 } 00137 00138 if (!strcmp(word,"MESH_TFACE")){ 00139 int n; 00140 int a,b,c; 00141 in >> n >> a >> b >> c; 00142 modelTexFaces[n]=rModelFace(a,b,c); 00143 } 00144 00145 if (!strcmp(word,"MESH_VERTEX")){ 00146 if (status==FACES){ 00147 status=VERTICES; 00148 offset+=current_vertex+1; 00149 } 00150 00151 float vec[3]; 00152 in >> current_vertex >> vec[0] >> vec[1] >> vec[2]; 00153 int realvert=current_vertex+offset; 00154 00155 translate[realvert]=-1; 00156 /* 00157 for(int i=realvert-1;i>0;i--){ 00158 float dist=0; 00159 for(int j=2;j>=0;j--) 00160 dist+= (vec[j]-vertices[i].x[j])*(vec[j]-vertices[i].x[j]); 00161 if (dist<.1) 00162 translate[realvert]=i; 00163 } 00164 */ 00165 if (translate[realvert]<0){ 00166 translate[realvert]=my_vert; 00167 //std::cerr << "v " << my_vert; 00168 for(int i=0;i<3;i++){ 00169 //std::cerr << '\t' << vec[i]*.025; // change inch to meters 00170 vertices[my_vert].x[i]=vec[i]*.025; 00171 } 00172 //std::cerr << '\n'; 00173 my_vert++; 00174 } 00175 } 00176 if (!strcmp(word,"MESH_FACE")){ 00177 status=FACES; 00178 in >> word; 00179 in >> word; 00180 //std::cerr << "f "; 00181 00182 int face=modelFaces.Len(); 00183 00184 if (strcmp(word,"A:")){ 00185 std::cerr << "wrong face format: expected A:, got " << word << '\n'; 00186 exit(-1); 00187 } 00188 int n; 00189 in >> n; 00190 modelFaces[face].A[0]=translate[n+offset]; 00191 //std::cerr << '\t' << translate[n+offset]; 00192 00193 in >> word; 00194 if (strcmp(word,"B:")){ 00195 std::cerr << "wrong face format: expected B:, got " << word << '\n'; 00196 exit(-1); 00197 } 00198 in >> n; 00199 modelFaces[face].A[1]=translate[n+offset]; 00200 // std::cerr << '\t' << translate[n+offset]; 00201 00202 in >> word; 00203 if (strcmp(word,"C:")){ 00204 std::cerr << "wrong face format: expected C:, got " << word << '\n'; 00205 exit(-1); 00206 } 00207 in >> n; 00208 modelFaces[face].A[2]=translate[n+offset]; 00209 // std::cerr << '\t' << translate[n+offset]; 00210 00211 // std::cerr << '\n'; 00212 00213 word[0]='\0'; 00214 } 00215 00216 } 00217 } 00218 } 00219 00220 if (calc_normals) 00221 for(int i=modelFaces.Len()-1;i>=0;i--){ 00222 Vec3 &A=vertices(modelFaces[i].A[0]); 00223 Vec3 &B=vertices(modelFaces[i].A[1]); 00224 Vec3 &C=vertices(modelFaces[i].A[2]); 00225 Vec3 X(B.x[0]-A.x[0],B.x[1]-A.x[1],B.x[2]-A.x[2]); 00226 Vec3 Y(C.x[0]-A.x[0],C.x[1]-A.x[1],C.x[2]-A.x[2]); 00227 Vec3 normal(X.x[1]*Y.x[2]-X.x[2]*Y.x[1], 00228 X.x[2]*Y.x[0]-X.x[0]*Y.x[2], 00229 X.x[0]*Y.x[1]-X.x[1]*Y.x[0]); 00230 normal=normal*(1/normal.Norm()); 00231 00232 for(int j=2;j>=0;j--) 00233 normals[modelFaces[i].A[j]]+=normal; 00234 } 00235 for(int i=normals.Len()-1;i>=0;i--){ 00236 normals[i]=normals[i]*(1/normals[i].Norm()); 00237 } 00238 00239 #endif 00240 }
void rModel::Render | ( | ) |
Definition at line 275 of file rModel.cpp.
References rDisplayList::Call(), rDisplayList::Cancel(), displayList_, glBegin, glEnd, GrowingArrayBase::Len(), modelFaces, modelTexFaces, modelTexFacesCoherent, normals, sr_glOut, texVert, and vertices.
Referenced by gCycle::Render().
00275 { 00276 if (!sr_glOut) 00277 return; 00278 if ( !displayList_.Call() ) 00279 { 00280 // model display lists should definitely be compiled before other lists 00281 rDisplayList::Cancel(); 00282 00283 bool texcoord=true; 00284 if (texVert.Len()<0) 00285 texcoord=false; 00286 if (modelTexFaces.Len()!=modelFaces.Len()) 00287 texcoord=false; 00288 if ( !modelTexFacesCoherent ) 00289 texcoord=false; 00290 00291 if (texcoord) 00292 { 00293 glTexCoordPointer(3,GL_FLOAT,0,&texVert[0]); 00294 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 00295 } 00296 00297 rDisplayListFiller filler( displayList_ ); 00298 00299 glEnable(GL_CULL_FACE); 00300 00301 if ( !modelTexFacesCoherent ) 00302 { 00303 // sigh, we need to do it the complicated way 00304 glBegin( GL_TRIANGLES ); 00305 for(int i=modelFaces.Len()-1;i>=0;i--) 00306 { 00307 for(int j=0;j<=2;j++) 00308 { 00309 glTexCoord3fv(reinterpret_cast<REAL *>(&(texVert(modelTexFaces(i).A[j])))); 00310 glNormal3fv(reinterpret_cast<REAL *>(&(normals(modelFaces(i).A[j])))); 00311 glVertex3fv(reinterpret_cast<REAL *>(&(vertices(modelFaces(i).A[j])))); 00312 } 00313 } 00314 glEnd(); 00315 00316 } 00317 else 00318 { 00319 // glDrawElements works 00320 if (normals.Len()>=vertices.Len()) 00321 { 00322 glNormalPointer(GL_FLOAT,0,&normals[0]); 00323 glEnableClientState(GL_NORMAL_ARRAY); 00324 } 00325 glVertexPointer(3,GL_FLOAT,0,&vertices[0]); 00326 glEnableClientState(GL_VERTEX_ARRAY); 00327 00328 glDrawElements(GL_TRIANGLES, 00329 modelFaces.Len()*3, 00330 GL_UNSIGNED_INT, 00331 &modelFaces(0)); 00332 } 00333 00334 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 00335 glDisableClientState(GL_VERTEX_ARRAY); 00336 glDisableClientState(GL_NORMAL_ARRAY); 00337 00338 glDisable(GL_CULL_FACE); 00339 } 00340 }
rDisplayList rModel::displayList_ [private] |
tArray<Vec3> rModel::vertices [private] |
tArray<Vec3> rModel::texVert [private] |
tArray<Vec3> rModel::normals [private] |
tArray<rModelFace> rModel::modelFaces [private] |
tArray<rModelFace> rModel::modelTexFaces [private] |
bool rModel::modelTexFacesCoherent [private] |