src/render/rModel.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 
00008 **************************************************************************
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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")){ // 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 }
00241 
00242 rModel::rModel(const char *fileName,const char *fileName_alt)
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 }
00273 
00274 #ifndef DEDICATED
00275 void rModel::Render(){
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 }
00341 #endif
00342 
00343 rModel::~rModel(){
00344     tCHECK_DEST;
00345 }
00346 
00347 
00348 
00349 
00350 

Generated on Sat Mar 15 22:55:52 2008 for Armagetron Advanced by  doxygen 1.5.4