![[]](/images/special/trans.gif)
LibN2L-4 Library Code ReferenceClassesCompounds Files Members Method Index Full Reference cRPovRayModel.cppGo 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 |