AaronCameron.net
No ads. No Profit. No Master, But Truth.
Not a Member? - Login or Create an Account
Thursday the 24th of May 2012 @ 01:51am
Front Page Journal Projects Your Profile About
[]

LibN2L-4 Library Code Reference

Classes
Compounds
Files
Members
Method Index
Full Reference

cRPovRayModel.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 Nova-2 Library (libN2L, or simply n2l) Game development C++ Library
00003 Copyright (C) 2003  Aaron Cameron
00004 
00005 This library is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU Lesser General Public
00007 License as published by the Free Software Foundation; either
00008 version 2.1 of the License, or (at your option) any later version.
00009 
00010 This library is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 Lesser General Public License for more details.
00014 
00015 You should have received a copy of the GNU Lesser General Public
00016 License along with this library; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 
00019 A copy of the GNU Lesser General Public License has been provided with
00020 this library in the file 'COPYING'.
00021 
00022 Contact information for the author of this library has been provided
00023 with this library in the file 'AUTHOR'.
00024 ************************************************************************/
00025 #include "renderTools/cRPovRayModel.h"
00026 
00027 #include "n2l/vfs.h"
00028 #include "n2l/materials.h"
00029 
00030 namespace n2l
00031 {
00032 
00033     /******************************************************************/
00034     cRPovRayModel::cRPovRayModel( const cVfsNodeInterface & iFile )
00035     {
00036         load(iFile);
00037     }
00038 
00039 
00040     /******************************************************************/
00041     cRPovRayModel::~cRPovRayModel()
00042     {
00043     }
00044 
00045     /******************************************************************/
00046     void cRPovRayModel::load( const cVfsNodeInterface & iFile )
00047     {
00048         // Clear out whatever we're currently holding.
00049         free();
00050         
00051         // Make sure that the node is like a file.
00052         if (!iFile.likeFile())
00053             throw cBadDataUseException( "cRPovRayModel::load",
00054                                         "Vfs Node isn\'t like a file" );
00055 
00056         tVfsFileBuffer buffer( iFile.buffer() );
00057 
00058         tVfsFileBuffer::size_type pos(0);
00059         while ( (pos=buffer.find("mesh2",pos)) != tVfsFileBuffer::npos ) {
00060             tVfsFileBuffer::size_type newPos;
00061 
00062             cAutoPtr<cMesh2> mesh2( new cMesh2(buffer,pos,newPos) );
00063             mMeshes.push_back(mesh2);
00064             if (pos==newPos)
00065                 throw cParsingException("cRPovRayModel::load",
00066                                         "Mesh loader didn\'t advance",
00067                                         buffer, asString(pos) );
00068             pos = newPos;
00069         } // while
00070         if (mMeshes.empty())
00071             throw cParsingException(    "cRPovRayModel::load",
00072                                         "No mesh2 meshes in file" );
00073     }
00074 
00075     /******************************************************************/
00076     void cRPovRayModel::defaultTexture( const tUint iMeshIndex,
00077                                         const cAutoPtr<const cGLTexture> & iTexture )
00078     {
00079         if (iMeshIndex>=mMeshes.size())
00080             throw cOutOfBoundsException("cRPovRayModel::texture",
00081                                         tString("No such mesh: ")+asString(iMeshIndex));
00082         mMeshes[iMeshIndex]->defaultTexture( iTexture );
00083     }
00084 
00085     /******************************************************************/
00086     void cRPovRayModel::render( const cAutoPtr<const cGLTexture> & i_iTexture,
00087                                 const tRenderOptions iOptions ) const
00088     {
00089         const tUint NumMeshes = mMeshes.size();
00090         for (tUint i=0; i<NumMeshes; ++i)
00091             mMeshes[i]->render(i_iTexture,iOptions);
00092     }
00093 
00094     /******************************************************************/
00095     void cRPovRayModel::free()
00096     {
00097     }
00098 
00099 
00100     /******************************************************************/
00101     void cRPovRayModel::centerAroundOrigin()
00102     {
00103         // We assume all meshes in a file are part of the same model,
00104         // so we'll center them all as if they were joined.
00105         
00106     }
00107 
00108 
00109     /******************************************************************/
00110     const tString & cRPovRayModel::vfsType() const
00111     {
00112         return VfsFileType_POVRay;
00113     }
00114 
00115 
00116     /******************************************************************/
00117     cRPovRayModel::cMesh2::cMesh2(  const tString & iBuffer,
00118                                     const tString::size_type & iPos,
00119                                     tString::size_type & oPos ) :
00120         mVertVectors(0),
00121         mNormVectors(0),
00122         mUVVectors(0),
00123         mFaceIndices(0),
00124         mUVIndices(0),
00125         mNumVertices(0),
00126         mNumNormals(0),
00127         mNumUVVectors(0),
00128         mNumFaceIndices(0),
00129         mNumUVIndices(0),
00130         mTexture(0)
00131     {
00132         const tString::size_type BufferSize( iBuffer.size() );
00133         tString::size_type pos;
00134         // Find the block open.
00135         pos = iBuffer.find("{",iPos);
00136         if (pos==tString::npos)
00137             throw cParsingException(    "cRPovRayModel::cMesh2::cMesh2",
00138                                         "No {", iBuffer, asString(pos) );
00139         ++pos;
00140         tString token;
00141         do {
00142             const tString::size_type StartTPos = iBuffer.find_first_not_of(" \t\n",pos);
00143             const tString::size_type EndTPos = iBuffer.find_first_of(" \t\n",StartTPos);
00144             if (StartTPos==tString::npos || EndTPos==tString::npos) 
00145                 throw cParsingException("cRPovRayModel::cMesh2::cMesh2",
00146                                         "No useable tokens",
00147                                         iBuffer, asString(pos) );
00148             token = iBuffer.substr(StartTPos,EndTPos-StartTPos);
00149 
00150             pos += token.size()+1;
00151             
00152             // Check for brackets to properly skip unknown components
00153             if (token=="{") {
00154                 pos = iBuffer.find("}",pos);
00155                 if (pos==tString::npos)
00156                     throw cParsingException("cRPovRayModel::cMesh2::cMesh2",
00157                                             "Unmatched { skipping unknown block",
00158                                             iBuffer, asString(pos) );
00159                 ++pos;
00160                 continue;
00161             }
00162 
00163             // Check the token.
00164             if (token=="vertex_vectors") {
00165                 pos = loadVertex3Array( mVertVectors, iBuffer, pos, mNumVertices );
00166 
00167             } else if (token=="normal_vectors") {
00168                 pos = loadVertex3Array( mNormVectors, iBuffer, pos, mNumNormals );
00169 
00170             } else if (token=="uv_vectors") {
00171                 pos = loadVertex2Array( mUVVectors, iBuffer, pos, mNumUVVectors );
00172 
00173             } else if (token=="face_indices") {
00174                 pos = loadIndex3Array(  mFaceIndices, iBuffer, pos, mNumFaceIndices );
00175 
00176             } else if (token=="uv_indices") {
00177                 pos = loadIndex3Array(  mUVIndices, iBuffer, pos, mNumUVIndices );
00178 
00179             } else {
00180             }
00181             
00182         } while (token!="}" && pos<BufferSize);
00183 
00184         if (!mVertVectors ||
00185             !mNormVectors ||
00186             !mUVVectors ||
00187             !mFaceIndices ||
00188             !mUVIndices)
00189             throw cParsingException("cRPovRayModel::cMesh2::cMesh2",
00190                                     "Mesh was incomplete");
00191         oPos = pos;
00192     }
00193 
00194     /******************************************************************/
00195     const tString::size_type cRPovRayModel::cMesh2::loadVertex3Array(
00196                                             tVector3f *& oArray,
00197                                             const tString & iBuffer,
00198                                             const tString::size_type & iPos,
00199                                             tUint & oNumLoaded )
00200     {
00201         const tString::size_type SNumPos = iBuffer.find("{",iPos);
00202         const tString::size_type ENumPos = iBuffer.find(",",iPos);
00203         if (SNumPos==tString::npos || ENumPos==tString::npos)
00204             throw cParsingException("cRPovRayModel::cMesh2::loadVertex3Array",
00205                                     "No useable tokens",
00206                                     iBuffer, "char(npos)" );
00207         // Get the size it reports.
00208         const tUint ListSize( asUint32(trimmed(iBuffer.substr(SNumPos+1,ENumPos-(SNumPos+1)))) );
00209         oArray = new tVector3f[ListSize];
00210         oNumLoaded = ListSize;
00211         tString::size_type pos = ENumPos+1;
00212         try
00213         {
00214             tUint numLoaded(0);
00215             while (numLoaded<ListSize) {
00216                 const tString::size_type STriPos = iBuffer.find("<",pos);
00217                 const tString::size_type ETriPos = iBuffer.find(">",pos);
00218                 if (STriPos==tString::npos || ETriPos==tString::npos ||
00219                     ETriPos<STriPos+6)
00220                     throw cParsingException("cRPovRayModel::cMesh2::loadVertex3Array",
00221                                             "Missing < or > characters",
00222                                             iBuffer, asString(pos) );
00223                 const tString::size_type C1( iBuffer.find(",",STriPos));
00224                 const tString::size_type C2( iBuffer.find(",",C1+1));
00225                 if (C1>ETriPos || C2>ETriPos)
00226                     throw cParsingException("cRPovRayModel::cMesh2::loadVertex3Array",
00227                                             "Missing , characters in inner block",
00228                                             iBuffer, asString(pos) );
00229                 tVector3f temp( asFloat( iBuffer.substr(STriPos+1,C1-(STriPos+1)) ),
00230                                 asFloat( iBuffer.substr(C1+1,C2-(C1+1)) ),
00231                                 asFloat( iBuffer.substr(C2+1,ETriPos-(C2+1)) ) );
00232                 oArray[numLoaded] = temp;
00233                 // Moving on
00234                 ++numLoaded;
00235                 pos = ETriPos+1;
00236             }
00237             pos = iBuffer.find("}",pos);
00238             if (pos==tString::npos)
00239                 throw cParsingException("cRPovRayModel::cMesh2::loadVertex3Array",
00240                                         "Missing } characters",
00241                                         iBuffer, "char(npos)" );
00242         }
00243         catch (const cException & iException)
00244         {
00245             delete []oArray;
00246             oArray = 0;
00247             iException.rethrow();
00248         }
00249         // That's it.
00250         return pos+1;
00251     }
00252 
00253 
00254     /******************************************************************/
00255     const tString::size_type cRPovRayModel::cMesh2::loadVertex2Array(
00256                                             tVector2f *& oArray,
00257                                             const tString & iBuffer,
00258                                             const tString::size_type & iPos,
00259                                             tUint & oNumLoaded )
00260     {
00261         const tString::size_type SNumPos = iBuffer.find("{",iPos);
00262         const tString::size_type ENumPos = iBuffer.find(",",iPos);
00263         if (SNumPos==tString::npos || ENumPos==tString::npos)
00264             throw cParsingException("cRPovRayModel::cMesh2::loadVertex2Array",
00265                                     "No useable tokens",
00266                                     iBuffer, "char(npos)" );
00267         // Get the size it reports.
00268         const tUint ListSize( asUint32(trimmed(iBuffer.substr(SNumPos+1,ENumPos-(SNumPos+1)))) );
00269         oArray = new tVector2f[ListSize];
00270         oNumLoaded = ListSize;
00271         tString::size_type pos = ENumPos+1;
00272         try
00273         {
00274             tUint numLoaded(0);
00275             while (numLoaded<ListSize) {
00276                 const tString::size_type STriPos = iBuffer.find("<",pos);
00277                 const tString::size_type ETriPos = iBuffer.find(">",pos);
00278                 if (STriPos==tString::npos || ETriPos==tString::npos ||
00279                     ETriPos<STriPos+6)
00280                     throw cParsingException("cRPovRayModel::cMesh2::loadVertex2Array",
00281                                             "Missing < or > characters",
00282                                             iBuffer, asString(pos) );
00283                 const tString::size_type C1( iBuffer.find(",",STriPos));
00284                 if (C1>ETriPos)
00285                     throw cParsingException("cRPovRayModel::cMesh2::loadVertex2Array",
00286                                             "Missing , characters in inner block",
00287                                             iBuffer, asString(pos) );
00288                 tVector2f temp( asFloat( iBuffer.substr(STriPos+1,C1-(STriPos+1)) ),
00289                                 asFloat( iBuffer.substr(C1+1,ETriPos-(C1+1)) ) );
00290                 oArray[numLoaded] = temp;
00291                 // Moving on
00292                 ++numLoaded;
00293                 pos = ETriPos+1;
00294             }
00295             pos = iBuffer.find("}",pos);
00296             if (pos==tString::npos)
00297                 throw cParsingException("cRPovRayModel::cMesh2::loadVertex2Array",
00298                                         "Missing } characters",
00299                                         iBuffer, "char(npos)" );
00300         }
00301         catch (const cException & iException)
00302         {
00303             delete []oArray;
00304             oArray = 0;
00305             iException.rethrow();
00306         }
00307         // That's it.
00308         return pos+1;
00309     }
00310 
00311 
00312 
00313     /******************************************************************/
00314     const tString::size_type cRPovRayModel::cMesh2::loadIndex3Array(
00315                                             tVector3u *& oArray,
00316                                             const tString & iBuffer,
00317                                             const tString::size_type & iPos,
00318                                             tUint & oNumLoaded )
00319     {
00320         const tString::size_type SNumPos = iBuffer.find("{",iPos);
00321         const tString::size_type ENumPos = iBuffer.find(",",iPos);
00322         if (SNumPos==tString::npos || ENumPos==tString::npos)
00323             throw cParsingException("cRPovRayModel::cMesh2::loadIndex3Array",
00324                                     "No useable tokens",
00325                                     iBuffer, "char(npos)" );
00326         // Get the size it reports.
00327         const tUint ListSize( asUint32(trimmed(iBuffer.substr(SNumPos+1,ENumPos-(SNumPos+1)))) );
00328 
00329         oArray = new tVector3u[ListSize];
00330         oNumLoaded = ListSize;
00331         tString::size_type pos = ENumPos+1;
00332         try
00333         {
00334             tUint numLoaded(0);
00335             while (numLoaded<ListSize) {
00336                 const tString::size_type STriPos = iBuffer.find("<",pos);
00337                 const tString::size_type ETriPos = iBuffer.find(">",pos);
00338                 if (STriPos==tString::npos || ETriPos==tString::npos ||
00339                     ETriPos<STriPos+6)
00340                     throw cParsingException("cRPovRayModel::cMesh2::loadIndex3Array",
00341                                             "Missing < or > characters",
00342                                             iBuffer, asString(pos) );
00343                 const tString::size_type C1( iBuffer.find(",",STriPos));
00344                 const tString::size_type C2( iBuffer.find(",",C1+1));
00345                 if (C1>ETriPos || C2>ETriPos)
00346                     throw cParsingException("cRPovRayModel::cMesh2::loadVertex3Array",
00347                                             "Missing , characters in inner block",
00348                                             iBuffer, asString(pos) );
00349                 tVector3u temp( asUint32( iBuffer.substr(STriPos+1,C1-(STriPos+1)) ),
00350                                 asUint32( iBuffer.substr(C1+1,C2-(C1+1)) ),
00351                                 asUint32( iBuffer.substr(C2+1,ETriPos-(C2+1)) ) );
00352                 oArray[numLoaded] = temp;
00353                 // Moving on
00354                 ++numLoaded;
00355                 pos = ETriPos+1;
00356             }
00357             pos = iBuffer.find("}",pos);
00358             if (pos==tString::npos)
00359                 throw cParsingException("cRPovRayModel::cMesh2::loadIndex3Array",
00360                                         "Missing } characters",
00361                                         iBuffer, "char(npos)" );
00362         }
00363         catch (const cException & iException)
00364         {
00365             delete []oArray;
00366             oArray = 0;
00367             iException.rethrow();
00368         }
00369         // That's it.
00370         return pos+1;
00371     }
00372 
00373     /******************************************************************/
00374     void cRPovRayModel::cMesh2::defaultTexture( const cAutoPtr<const cGLTexture> & iTexture)
00375     {
00376         mTexture = iTexture;
00377     }
00378 
00379 
00380     /******************************************************************/
00381     void cRPovRayModel::cMesh2::render( const cAutoPtr<const cGLTexture> & i_iTexture,
00382                                         const tRenderOptions iOptions ) const
00383     {
00384         const tBool Textured( !(iOptions & R_NoTextures) && (i_iTexture || mTexture) );
00385         const tBool Normals( !(iOptions & R_NoNormals) );
00386 
00387         if (Textured) {
00388             glEnable( GL_TEXTURE_2D );
00389             if (i_iTexture)
00390                 i_iTexture->bind();
00391             else mTexture->bind();
00392         }
00393         glEnable( GL_DEPTH_TEST );
00394         glCullFace(GL_BACK);
00395         glEnable(GL_CULL_FACE);
00396 
00397         // Lets render the retarded thing.
00398         if (iOptions & R_Wireframe)
00399             glBegin( GL_LINE_STRIP );
00400         else glBegin( GL_TRIANGLES );
00401 
00402         for (tUint f=0; f<mNumFaceIndices; ++f) {
00403             if (Normals)    mNormVectors[ mFaceIndices[f].x() ].glNormal3f();
00404             if (Textured)   mUVVectors[ mUVIndices[f].x() ].glTexCoord2f();
00405             mVertVectors[ mFaceIndices[f].x() ].glVertex3f();
00406             
00407             if (Normals)    mNormVectors[ mFaceIndices[f].y() ].glNormal3f();
00408             if (Textured)   mUVVectors[ mUVIndices[f].y() ].glTexCoord2f();
00409             mVertVectors[ mFaceIndices[f].y() ].glVertex3f();
00410             
00411             if (Normals)    mNormVectors[ mFaceIndices[f].z() ].glNormal3f();
00412             if (Textured)   mUVVectors[ mUVIndices[f].z() ].glTexCoord2f();
00413             mVertVectors[ mFaceIndices[f].z() ].glVertex3f();
00414         }
00415         glEnd();
00416 
00417         glDisable( GL_CULL_FACE );
00418         glDisable( GL_DEPTH_TEST );
00419         if (Textured)
00420             glDisable( GL_TEXTURE_2D );
00421     }
00422 
00423 
00424     /******************************************************************/
00425 /*  void cRPovRayModel::cMesh2::render() const
00426     {
00427         if (mTexture) {
00428             glEnable( GL_TEXTURE_2D );
00429             mTexture->bind();
00430         }
00431         glEnable( GL_DEPTH_TEST );
00432         glCullFace(GL_BACK);
00433         glEnable(GL_CULL_FACE);
00434 
00435         // Lets render the retarded thing.
00436         glBegin( GL_TRIANGLES );
00437         for (tUint f=0; f<mNumFaceIndices; ++f) {
00438             mNormVectors[ mFaceIndices[f].x() ].glNormal3f();
00439             mUVVectors[ mUVIndices[f].x() ].glTexCoord2f();
00440             mVertVectors[ mFaceIndices[f].x() ].glVertex3f();
00441             
00442             mNormVectors[ mFaceIndices[f].y() ].glNormal3f();
00443             mUVVectors[ mUVIndices[f].y() ].glTexCoord2f();
00444             mVertVectors[ mFaceIndices[f].y() ].glVertex3f();
00445             
00446             mNormVectors[ mFaceIndices[f].z() ].glNormal3f();
00447             mUVVectors[ mUVIndices[f].z() ].glTexCoord2f();
00448             mVertVectors[ mFaceIndices[f].z() ].glVertex3f();
00449         }
00450         glEnd();
00451 
00452         glDisable( GL_CULL_FACE );
00453         glDisable( GL_DEPTH_TEST );
00454         if (mTexture)
00455             glDisable( GL_TEXTURE_2D );
00456     }
00457 */
00458 
00459     /******************************************************************/
00460     void cRPovRayModel::cMesh2::minMaxVectors(  tVector3f & oMin,
00461                                                 tVector3f & oMax ) const
00462     {
00463         for (tUint v=0; v<mNumVertices; ++v) {
00464             oMax.set(   n2l_min(mVertVectors[v].x(), oMin.x()),
00465                         n2l_min(mVertVectors[v].y(), oMin.y()),
00466                         n2l_min(mVertVectors[v].z(), oMin.z()) );
00467             oMax.set(   n2l_max(mVertVectors[v].x(), oMax.x()),
00468                         n2l_max(mVertVectors[v].y(), oMax.y()),
00469                         n2l_max(mVertVectors[v].z(), oMax.z()) );
00470         }
00471     }
00472 
00473 
00474     /******************************************************************/
00475     cRPovRayModel::cMesh2::~cMesh2()
00476     {
00477         if (mVertVectors) delete []mVertVectors;
00478         if (mNormVectors) delete []mNormVectors;
00479         if (mUVVectors) delete []mUVVectors;
00480         if (mFaceIndices) delete []mFaceIndices;
00481         if (mUVIndices) delete []mUVIndices;
00482     }
00483 
00484 } // namespace n2l
©2012 Aaron Cameron