00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "rModel.h"
00029 #include <string>
00030 #include <fstream>
00031 #include <stdlib.h>
00032 #include "rScreen.h"
00033 #include "tString.h"
00034 #include "tDirectories.h"
00035 #include "tConfiguration.h"
00036 #include "tLocale.h"
00037 #include "rGL.h"
00038 #include <string.h>
00039
00040 tCONFIG_ENUM(rDisplayListUsage);
00041
00042 static tConfItem<rDisplayListUsage> mod_udl("USE_DISPLAYLISTS", sr_useDisplayLists);
00043
00044 #ifndef DEDICATED
00045
00046 void Vec3::RenderVertex(){
00047 glVertex3f(x[0],x[1],x[2]);
00048 }
00049
00050 void Vec3::RenderNormal(){
00051 glNormal3f(x[0],x[1],x[2]);
00052 }
00053 #endif
00054
00055 void rModel::Load(std::istream &in,const char *fileName){
00056
00057 #ifndef DEDICATED
00058 modelTexFacesCoherent = false;
00059 bool calc_normals=true;
00060
00061 if (strstr(fileName,".mod")){
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{
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
00158
00159
00160
00161
00162
00163
00164
00165 if (translate[realvert]<0){
00166 translate[realvert]=my_vert;
00167
00168 for(int i=0;i<3;i++){
00169
00170 vertices[my_vert].x[i]=vec[i]*.025;
00171 }
00172
00173 my_vert++;
00174 }
00175 }
00176 if (!strcmp(word,"MESH_FACE")){
00177 status=FACES;
00178 in >> word;
00179 in >> word;
00180
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
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
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
00210
00211
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 }
00241
00242 rModel::rModel(const char *fileName,const char *fileName_alt)
00243 {
00244 #ifndef DEDICATED
00245
00246
00247
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 }
00273
00274 #ifndef DEDICATED
00275 void rModel::Render(){
00276 if (!sr_glOut)
00277 return;
00278 if ( !displayList_.Call() )
00279 {
00280
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
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
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 }
00341 #endif
00342
00343 rModel::~rModel(){
00344 tCHECK_DEST;
00345 }
00346
00347
00348
00349
00350