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

ac3dmodel.cpp

00001 /***************************************************************************
00002                           AC3DModel.cpp  -  description
00003           $Id: ac3dmodel.cpp 3 2006-06-11 08:16:14Z neoneurone $
00004                              -------------------
00005     begin                : mer juin 29 05
00006     copyright            : (C) 2005 by Duong-Khang NGUYEN
00007     email                : neoneurone @ users sourceforge net
00008  ***************************************************************************/
00009 
00010 /***************************************************************************
00011  *                                                                         *
00012  *   This program is free software; you can redistribute it and/or modify  *
00013  *   it under the terms of the GNU General Public License as published by  *
00014  *   the Free Software Foundation; either version 2 of the License, or     *
00015  *   any later version.                                                    *
00016  *                                                                         *
00017  ***************************************************************************/
00018 
00019 #include "ac3dmodel.h"
00020 #include "ac3dobject.h"
00021 
00022 #include "macros.h"         // For debugging macros
00023 #include "ac3dmacros.h"     // Our macros
00024 
00025 #include <fstream>
00026 #include <cstring>
00027 #include <sstream>
00028 
00029 using std::ifstream;
00030 using std::stringstream;
00031 
00032 namespace AC3D {
00033 
00034    /*=====================================================================*/
00035 AC3DModel::AC3DModel
00036 (
00037     string fileName
00038 ):
00039 strFileName(fileName),
00040 pObject(NULL)
00041 {
00042     OPENCITY_DEBUG("ctor");
00043     this->bGood = this->ac3dmodelParse();
00044 }
00045 
00046 
00047    /*=====================================================================*/
00048 AC3DModel::~AC3DModel()
00049 {
00050     OPENCITY_DEBUG("dtor");
00051     
00052     delete this->pObject;
00053     this->pObject = NULL;
00054     this->bGood = false;
00055 }
00056 
00057 
00058    /*=====================================================================*/
00059 const vector<AC3DMaterial> &
00060 AC3DModel::GetVMaterial() const
00061 {
00062     return this->vMaterial;
00063 }
00064 
00065 
00066    /*=====================================================================*/
00067 const AC3DObject* const
00068 AC3DModel::GetPObject() const
00069 {
00070     return this->pObject;
00071 }
00072 
00073 
00074    /*=====================================================================*/
00075 bool
00076 AC3DModel::IsGood() const
00077 {
00078     return this->bGood;
00079 }
00080 
00081 
00082    /*=====================================================================*/
00083 string
00084 AC3DModel::ToStr() const
00085 {
00086     string str = this->strHeader + "\n";
00087     vector<AC3DMaterial>::size_type pos, size;
00088 
00089 // Output all materials
00090     size = this->vMaterial.size();
00091     for (pos = 0; pos < size; pos++)
00092         str += this->vMaterial[pos].ToStr();
00093 
00094 // Output all objects
00095     if (this->pObject != NULL)
00096         str += this->pObject->ToStr();
00097 
00098     return str; 
00099 }
00100 
00101 
00102    /*=====================================================================*/
00103    /*                        PRIVATE      METHODS                         */
00104    /*=====================================================================*/
00105 bool
00106 AC3DModel::ac3dmodelParse()
00107 {
00108     ifstream in;
00109     stringstream ss;
00110     
00111     char line[AC3D_MAX_LINE_LENGTH];
00112     bool endBlock;
00113 
00114     AC3DObject* pNewObj = NULL;
00115     AC3DObject* pCurrentObj = NULL;
00116     vector<AC3DObject*> vpObj;              // Stack used for recursive object loading
00117 
00118 
00119     in.open(this->strFileName.c_str());
00120 
00121     if (!in.good()) {
00122         OPENCITY_DEBUG("File open error");
00123         OPENCITY_DEBUG( this->strFileName.c_str() );
00124         return false;
00125     }
00126 
00127 // Get the header. Ex: "AC3Db"
00128 // TODO: version check
00129     in.getline( line, AC3D_MAX_LINE_LENGTH );
00130     if (in.good())
00131         strHeader = line;
00132 
00133 // Parse the file
00134     in.getline( line, AC3D_MAX_LINE_LENGTH );
00135     while (in.good()) {
00136     // Looks for "MATERIAL" token
00137         if ( strncmp( line, AC3D_TOKEN_MATERIAL, AC3D_TOKEN_MATERIAL_L ) == 0 ) {
00138         // Create new MATERIAL
00139             this->vMaterial.push_back( AC3DMaterial( line ) );
00140             in.getline( line, AC3D_MAX_LINE_LENGTH );
00141         } else
00142         if( strncmp( line, AC3D_TOKEN_OBJECT, AC3D_TOKEN_OBJECT_L ) == 0 ) {
00143             ss.str("");
00144             //debug cout << "New line: " << line << endl;
00145             ss << line << endl;
00146 
00147         // Get all the OBJECT block
00148             in.getline( line, AC3D_MAX_LINE_LENGTH );
00149             endBlock = false;
00150             while (in.good() && !endBlock) {
00151             // IF this is a new OBJECT command then we reach the end of the block
00152                 if( strncmp( line, AC3D_TOKEN_OBJECT, AC3D_TOKEN_OBJECT_L ) == 0 ) {
00153                     endBlock = true;
00154                 }
00155                 else {
00156                     //debug cout << "New line: " << line << endl;
00157                     ss << line << endl;
00158                     in.getline( line, AC3D_MAX_LINE_LENGTH );
00159                 }
00160             } // while
00161 
00162         // Create new OBJECT from the block of data
00163             pNewObj = new AC3DObject( ss );
00164 
00165         // IF this is the first object THEN
00166             if (this->pObject == NULL) {
00167                 this->pObject = pNewObj;
00168                 pCurrentObj = pNewObj;
00169             } 
00170             else {
00171                 assert( pCurrentObj != NULL );
00172                 pCurrentObj->AddKid( pNewObj );
00173 
00174             // IF this object has any kids THEN
00175                 if (pNewObj->GetNumberKid() > 0) {
00176                 // Save the current level on the stack
00177                     vpObj.push_back( pCurrentObj );
00178                     pCurrentObj = pNewObj;
00179                 }
00180                 else {
00181                 // IF all the kids have been loaded THEN
00182                     while ((pCurrentObj->GetVPObject().size() == pCurrentObj->GetNumberKid())
00183                         && (vpObj.empty() == false)) {
00184                     // Restore the previous level
00185                         pCurrentObj = vpObj.back();
00186                         vpObj.pop_back();
00187                     }
00188                 }
00189             } // IF first object
00190 
00191         } // new OBJECT
00192     } // while good
00193     
00194     if (in.is_open())
00195         in.close();
00196 
00197     return true;            // everything is OK
00198 }
00199 
00200 
00201 }
00202 
00203 
00204 
00205 
00206 
00207 
00208 
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 

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