Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

ac3dobject.cpp

00001 /***************************************************************************
00002                             AC3DModel.h  -  description
00003                                 -------------------
00004     begin                : mer juin 29 05
00005     copyright            : (C) 2005-2006 by Duong-Khang NGUYEN
00006     email                : neoneurone @ users sourceforge net
00007     
00008     $Id: ac3dobject.cpp 6 2006-06-19 21:43:20Z neoneurone $
00009  ***************************************************************************/
00010 
00011 /***************************************************************************
00012  *                                                                         *
00013  *   This program is free software; you can redistribute it and/or modify  *
00014  *   it under the terms of the GNU General Public License as published by  *
00015  *   the Free Software Foundation; either version 2 of the License, or     *
00016  *   any later version.                                                    *
00017  *                                                                         *
00018  ***************************************************************************/
00019 
00020 #include "ac3dobject.h"
00021 
00022 #include "macros.h"     // debug macros
00023 #include "ac3dmacros.h"
00024 
00025 #include <cstring>
00026 
00027 
00028 namespace AC3D {
00029 
00030 
00031    /*=====================================================================*/
00032 AC3DObject::AC3DObject():
00033 strName(""),
00034 fCrease(45),
00035 uiNumVert(0),
00036 uiNumSurf(0),
00037 uiKids(0)
00038 {
00039 // WARNING: uninitialized attributes
00040     OPENCITY_DEBUG("ctor1");
00041 
00042     this->ac3dSetDefault();
00043 }
00044 
00045 
00046    /*=====================================================================*/
00047 AC3DObject::AC3DObject
00048 (
00049     stringstream& data
00050 ):
00051 strName(""),
00052 fCrease(45),
00053 uiNumVert(0),
00054 uiNumSurf(0),
00055 uiKids(0)
00056 {
00057 //  OPENCITY_DEBUG("ctor2");
00058 
00059     this->ac3dSetDefault();
00060     this->Parse( data );
00061 }
00062 
00063 
00064    /*=====================================================================*/
00065 AC3DObject::~AC3DObject()
00066 {
00067     //OPENCITY_DEBUG("dtor");
00068     vector<AC3DObject*>::size_type pos, size;
00069 
00070 
00071     size = this->vpObject.size();
00072     for (pos = 0; pos < size; pos++)
00073         delete vpObject[pos];
00074 
00075     size = this->vpSurface.size();
00076     for (pos = 0; pos < size; pos++)
00077         delete vpSurface[pos];
00078 }
00079 
00080 
00081    /*=====================================================================*/
00082 void
00083 AC3DObject::AddKid
00084 (
00085     AC3DObject* kid
00086 )
00087 {
00088     this->vpObject.push_back( kid );
00089 }
00090 
00091 
00092    /*=====================================================================*/
00093 bool
00094 AC3DObject::IsTranslucent() const
00095 {
00096     return (this->strName.find("alpha") != string::npos);
00097 }
00098 
00099 
00100    /*=====================================================================*/
00101 string
00102 AC3DObject::GetName() const
00103 {
00104     return this->strName;
00105 }
00106 
00107 
00108    /*=====================================================================*/
00109 unsigned int
00110 AC3DObject::GetNumberKid() const
00111 {
00112     return this->uiKids;
00113 }
00114 
00115 
00116    /*=====================================================================*/
00117 const string&
00118 AC3DObject::GetTextureFile() const
00119 {
00120     return this->strTexture;
00121 }
00122 
00123 
00124    /*=====================================================================*/
00125 const float*
00126 AC3DObject::GetLoc() const
00127 {
00128     return this->fLoc;
00129 }
00130 
00131 
00132    /*=====================================================================*/
00133 const vector<Vertex>&
00134 AC3DObject::GetVVertex() const
00135 {
00136     return this->vVertex;
00137 }
00138 
00139 
00140    /*=====================================================================*/
00141 const vector<AC3DSurface*>&
00142 AC3DObject::GetVPSurface() const
00143 {
00144     return this->vpSurface;
00145 }
00146 
00147 
00148    /*=====================================================================*/
00149 const vector<AC3DObject*>&
00150 AC3DObject::GetVPObject() const
00151 {
00152     return this->vpObject;
00153 }
00154 
00155 
00156    /*=====================================================================*/
00157 void
00158 AC3DObject::Parse(
00159     stringstream& data
00160 )
00161 {
00162     char line[AC3D_MAX_LINE_LENGTH];
00163     char cstr[AC3D_MAX_LINE_LENGTH];
00164 
00165 //debug cout << "Given ss: " << data.str() << endl;
00166     
00167     data.getline( line, AC3D_MAX_LINE_LENGTH );
00168     while (data.good()) {
00169         if ( strncmp( line, AC3D_TOKEN_OBJECT, AC3D_TOKEN_OBJECT_L ) == 0 ) {
00170             sscanf( line, "OBJECT %s", cstr );
00171             if (strncmp( cstr, "world", 5 ) == 0)
00172                 this->type = OBJECT_WORLD;
00173             else if (strncmp( cstr, "poly", 5 ) == 0)
00174                 this->type = OBJECT_POLYGON;
00175             else if (strncmp( cstr, "group", 5 ) == 0)
00176                 this->type = OBJECT_GROUP;
00177             data.getline( line, AC3D_MAX_LINE_LENGTH );
00178         } else
00179         if ( strncmp( line, AC3D_TOKEN_NAME, AC3D_TOKEN_NAME_L ) == 0 ) {
00180             sscanf( line,  "name %s", cstr );
00181             this->strName = cstr;
00182             data.getline( line, AC3D_MAX_LINE_LENGTH );
00183         } else
00184         if ( strncmp( line, AC3D_TOKEN_TEXTURE, AC3D_TOKEN_TEXTURE_L ) == 0 ) {
00185             sscanf( line, "texture %s", cstr );
00186             this->strTexture = cstr;
00187         // Strip out the doublequotes
00188             if (this->strTexture.size() >= 2) {
00189                 this->strTexture = this->strTexture.substr( 1, this->strTexture.size()-2 );
00190             } else {
00191                 OPENCITY_DEBUG("Unable to strip doublequotes");
00192             }
00193             data.getline( line, AC3D_MAX_LINE_LENGTH );
00194         } else
00195         if ( strncmp( line, AC3D_TOKEN_TEXREP, AC3D_TOKEN_TEXREP_L ) == 0 ) {
00196             sscanf( line, "texrep %f %f", this->fTexRep, this->fTexRep+1 );
00197             data.getline( line, AC3D_MAX_LINE_LENGTH );
00198         } else
00199         if ( strncmp( line, AC3D_TOKEN_ROT, AC3D_TOKEN_ROT_L ) == 0 ) {
00200             sscanf(
00201                 line,
00202                 "rot %f %f %f %f %f %f %f %f %f",
00203                 this->fRot  , this->fRot+1, this->fRot+2,
00204                 this->fRot+3, this->fRot+4, this->fRot+5,
00205                 this->fRot+6, this->fRot+7, this->fRot+8
00206             );
00207             data.getline( line, AC3D_MAX_LINE_LENGTH );
00208         } else
00209         if ( strncmp( line, AC3D_TOKEN_LOC, AC3D_TOKEN_LOC_L ) == 0 ) {
00210             sscanf( line, "loc %f %f %f", this->fLoc, this->fLoc+1, this->fLoc+2 );
00211             data.getline( line, AC3D_MAX_LINE_LENGTH );
00212         } else
00213         if ( strncmp( line, AC3D_TOKEN_CREASE, AC3D_TOKEN_CREASE_L ) == 0 ) {
00214             sscanf( line, "crease %f", &(this->fCrease) );
00215             data.getline( line, AC3D_MAX_LINE_LENGTH );
00216         } else
00217         if ( strncmp( line, AC3D_TOKEN_URL, AC3D_TOKEN_URL_L ) == 0 ) {
00218             sscanf( line, "url %s", cstr );
00219             this->strURL = cstr;
00220             data.getline( line, AC3D_MAX_LINE_LENGTH );
00221         } else
00222         if ( strncmp( line, AC3D_TOKEN_KIDS, AC3D_TOKEN_KIDS_L ) == 0 ) {
00223             sscanf( line, "kids %u", &(this->uiKids) );
00224             data.getline( line, AC3D_MAX_LINE_LENGTH );
00225         } else
00226         if ( strncmp( line, AC3D_TOKEN_NUMVERT, AC3D_TOKEN_NUMVERT_L ) == 0 ) {
00227             sscanf( line, "numvert %u", &(this->uiNumVert) );
00228             ac3dobjectParseVertex( this->uiNumVert, data, line );
00229         } else
00230         if ( strncmp( line, AC3D_TOKEN_NUMSURF, AC3D_TOKEN_NUMSURF_L ) == 0 ) {
00231             sscanf( line, "numsurf %u", &(this->uiNumSurf) );
00232             ac3dobjectParseSurface( this->uiNumSurf, data, line );
00233         } else {
00234             OPENCITY_DEBUG("WARNING: unknown command discarded. See below: ");
00235             OPENCITY_DEBUG( line );
00236             data.getline( line, AC3D_MAX_LINE_LENGTH );
00237         }
00238     }
00239 
00240     data.clear();
00241 }
00242 
00243 
00244    /*=====================================================================*/
00245 string
00246 AC3DObject::ToStr() const
00247 {
00248     stringstream ss;
00249     vector<AC3DObject*>::size_type pos, size;
00250 
00251 
00252     ss << "OBJECT ";
00253     switch (this->type) {
00254         case OBJECT_WORLD: ss << "world"; break;
00255         case OBJECT_POLYGON: ss << "poly"; break;
00256         case OBJECT_GROUP: ss << "group"; break;
00257     }
00258     ss << endl;
00259 
00260     ss << ((this->strName != "") ? "name " + this->strName + "\n" : "")
00261        << "loc " << this->fLoc[0] << " "
00262                  << this->fLoc[1] << " "
00263                  << this->fLoc[2] << endl
00264        << "texrep " << this->fTexRep[0] << " "
00265                     << this->fTexRep[1] << endl;
00266 
00267     ss << ((this->strTexture != "") ? "texture " + this->strTexture + "\n" : "")
00268        << "crease " << this->fCrease << endl
00269        << "numvert " << this->uiNumVert << endl;
00270 
00271     size = this->vVertex.size();
00272     for (pos = 0; pos < size; pos++) {
00273         ss << this->vVertex[pos].x << " "
00274            << this->vVertex[pos].y << " "
00275            << this->vVertex[pos].z << endl;
00276     }
00277 
00278     ss << "numsurf " << this->uiNumSurf << endl;
00279 
00280     size = this->vpSurface.size();
00281     for (pos = 0; pos < size; pos++)
00282         ss << this->vpSurface[pos]->ToStr();
00283 
00284     ss << "kids " << this->uiKids << endl;
00285 
00286     size = this->vpObject.size();
00287     for (pos = 0; pos < size; pos++)
00288         ss << this->vpObject[pos]->ToStr();
00289 
00290     return ss.str();
00291 }
00292 
00293 
00294    /*=====================================================================*/
00295    /*                        PRIVATE      METHODS                         */
00296    /*=====================================================================*/
00297 void
00298 AC3DObject::ac3dSetDefault()
00299 {
00300 // Default "texrep" values
00301     this->fTexRep[0] = 1.;
00302     this->fTexRep[1] = 1.;
00303 
00304 // Default "loc" values
00305     this->fLoc[0] = 0.; this->fLoc[1] = 0.; this->fLoc[2] = 0.;
00306 
00307 // Default "rot" values
00308     this->fRot[0] = 1.; this->fRot[1] = 0.; this->fRot[2] = 0.;
00309     this->fRot[3] = 0.; this->fRot[4] = 1.; this->fRot[5] = 0.;
00310     this->fRot[3] = 0.; this->fRot[4] = 0.; this->fRot[5] = 1.;
00311 }
00312 
00313 
00314    /*=====================================================================*/
00315 void
00316 AC3DObject::ac3dobjectParseVertex
00317 (
00318     unsigned int nb,
00319     stringstream& data,
00320     char* buffer
00321 )
00322 {
00323     Vertex newVertex;
00324 
00325 // WARNING no error checking
00326     data.getline( buffer, AC3D_MAX_LINE_LENGTH );
00327     while (data.good() && (nb-- > 0)) {
00328         sscanf( buffer, "%f %f %f", &newVertex.x, &newVertex.y, &newVertex.z );
00329         this->vVertex.push_back( newVertex );
00330         data.getline( buffer, AC3D_MAX_LINE_LENGTH );
00331     }
00332 }
00333 
00334 
00335    /*=====================================================================*/
00336 void
00337 AC3DObject::ac3dobjectParseSurface
00338 (
00339     unsigned int nb,
00340     stringstream& data,
00341     char* buffer
00342 )
00343 {
00344     stringstream ss;
00345 
00346     bool endBlock = false;
00347     bool endSurf = false;
00348 
00349     AC3DSurface* pSurf = NULL;
00350 
00351     data.getline( buffer, AC3D_MAX_LINE_LENGTH );
00352     while (data.good() && !endSurf) {
00353         if ( strncmp( buffer, AC3D_TOKEN_SURF, AC3D_TOKEN_SURF_L ) == 0 ) {
00354             ss << buffer << endl;
00355             data.getline( buffer, AC3D_MAX_LINE_LENGTH );
00356         } else
00357         if ( strncmp( buffer, AC3D_TOKEN_MAT, AC3D_TOKEN_MAT_L ) == 0 ) {
00358             ss << buffer << endl;
00359             data.getline( buffer, AC3D_MAX_LINE_LENGTH );
00360         } else
00361         if ( strncmp( buffer, AC3D_TOKEN_KIDS, AC3D_TOKEN_KIDS_L ) == 0 ) {
00362             endSurf = true;
00363         } else
00364         if ( strncmp( buffer, AC3D_TOKEN_REFS, AC3D_TOKEN_REFS_L ) == 0 ) {
00365             ss << buffer << endl;
00366             data.getline( buffer, AC3D_MAX_LINE_LENGTH );
00367 
00368             endBlock = false;
00369             while (data.good() && !endBlock) {
00370             // IF this is a new "SURF", "mat" or "refs" command
00371             // THEN  we reach the end of the block
00372                 if ((strncmp( buffer, AC3D_TOKEN_SURF, AC3D_TOKEN_SURF_L ) == 0 )
00373                  || (strncmp( buffer, AC3D_TOKEN_MAT, AC3D_TOKEN_MAT_L ) == 0 )
00374                  || (strncmp( buffer, AC3D_TOKEN_REFS, AC3D_TOKEN_REFS_L ) == 0 )
00375                  || (strncmp( buffer, AC3D_TOKEN_KIDS, AC3D_TOKEN_KIDS_L ) == 0 )) {
00376                     endBlock = true;
00377                 }
00378                 else {
00379                     //debug cout << "New buffer: " << buffer << endl;
00380                     ss << buffer << endl;
00381                     data.getline( buffer, AC3D_MAX_LINE_LENGTH );
00382                 }
00383             }
00384 
00385             // Create new surface from the data block
00386             pSurf = new AC3DSurface( ss );
00387             this->vpSurface.push_back( pSurf );
00388             ss.str("");
00389         }
00390     }
00391     
00392 }
00393 
00394 
00395 }
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 

Generated on Sat Nov 11 10:21:09 2006 for OpenCity by  doxygen 1.4.2