AaronCameron.net
Not Left, nor right. Just correct.
Not a Member? - Login or Create an Account
Wednesday the 23rd of May 2012 @ 05:10pm
Front Page Journal Projects Your Profile About
[]

LibN2L-4 Library Code Reference

Classes
Compounds
Files
Members
Method Index
Full Reference

cRK3DRawAsciiModel.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 
00026 #include "renderTools/cRK3DRawAsciiModel.h"
00027 #include "n2l/geometry.h"
00028 #include "n2l/vfs.h"
00029 
00030 #include <GL/gl.h>
00031 
00032 namespace n2l
00033 {
00034 
00035 
00036     /* ************************************************************ */
00037     cRK3DRawAsciiModel::cRK3DRawAsciiModel( const cVfsNodeInterface & iFile ) :
00038         mNumVertices(0),
00039         mNumTriangles(0)
00040     {
00041         load(iFile);
00042     }
00043 
00044     /* ************************************************************ */
00045     cRK3DRawAsciiModel::~cRK3DRawAsciiModel()
00046     {
00047         free();
00048     }
00049 
00050 
00051     /* ************************************************************ */
00052     void cRK3DRawAsciiModel::load( const cVfsNodeInterface & iFile )
00053     {
00054         // Clear whatever we have in the class right now.
00055         // This call is safe, even if the class is already empty.
00056         free();
00057 
00058         // Make sure that the node is like a file.
00059         if (!iFile.likeFile())
00060             throw cBadDataUseException( "cRK3DRawAsciiModel::load",
00061                                         "Vfs Node isn\'t like a file" );
00062     
00063         // Get the data buffer.
00064         const tVfsFileBuffer & buffer = iFile.buffer();
00065         const tUint BufferSize(buffer.size());
00066 
00067         tVfsFileBuffer::size_type linePos(0);
00068         tVfsFileBuffer::size_type endLinePos(0);
00069 
00070         tBool loadingVertex = true;
00071 
00072         while ( tVfsFileBuffer::npos !=
00073                 (endLinePos=buffer.find_first_of("\n#",linePos)) ) {
00074             tString line = trimmed(buffer.substr(linePos,endLinePos-linePos));
00075             if (!line.empty()) {
00076                 std::vector<tString> tokens;
00077                 explode( line,tokens,' ','\0','\0',true );
00078                 if (tokens.size()==2) {
00079                     if (mNumVertices!=0 || mNumTriangles!=0)
00080                         throw cParsingException("cRK3DRawAsciiModel::load",
00081                                                 "Two tokens on a line after the header");
00082                     else {
00083                         mNumVertices = asUint32(tokens[0]);
00084                         mNumTriangles = asUint32(tokens[1]);
00085                         mVertices.reserve(mNumVertices);
00086                         mTriangles.reserve(mNumTriangles);
00087                     }
00088                 } else if (tokens.size()==3) {
00089                     if (!mNumVertices || !mNumTriangles)
00090                         throw cParsingException(    "cRK3DRawAsciiModel::load",
00091                                                     "Three tokens on a line before header" );
00092                     if (loadingVertex) {
00093                         tVertex v = {
00094                             asFloat(tokens[0]),
00095                             asFloat(tokens[1]),
00096                             asFloat(tokens[2])
00097                         };
00098                         mVertices.push_back(v);
00099                         if (mVertices.size()==mNumVertices)
00100                             loadingVertex = false;
00101                     } else {
00102                         // Triangles
00103                         tTriangle t = {
00104                             asUint32(tokens[0]),
00105                             asUint32(tokens[1]),
00106                             asUint32(tokens[2])
00107                         };
00108                         // Make sure that the indicies listed here
00109                         // are in the vertex array we've already loaded
00110                         if (t.a>=mNumVertices ||
00111                             t.b>=mNumVertices ||
00112                             t.c>=mNumVertices)
00113                             throw cParsingException("cRK3DRawAsciiModel::load",
00114                                                     "Vertex index out of range",
00115                                                     line,  asString(linePos) );
00116                         mTriangles.push_back(t);
00117                         if (mTriangles.size()>mNumTriangles) 
00118                             throw cParsingException("cRK3DRawAsciiModel::load",
00119                                                     "Too many vertices or triangles",
00120                                                     line,  asString(linePos) );
00121                     }
00122                 } else throw cParsingException( "cRK3DRawAsciiModel::load",
00123                                                 "Invalid number of tokens",
00124                                                 line, asString(linePos)  );
00125             }
00126             // Skip to the next line if we broke at a pound
00127             if (buffer[endLinePos] == '#') {
00128                 endLinePos = buffer.find_first_of("\n",endLinePos);
00129                 if (endLinePos==tVfsFileBuffer::npos) break;
00130             }
00131             // Get ready for the next line
00132             linePos = endLinePos;
00133             ++linePos;
00134             if (linePos>=BufferSize) break;
00135         }
00136         // Did anything even load?
00137         if (mTriangles.empty())
00138             throw cParsingException("cRK3DRawAsciiModel::load",
00139                                     "No recognizable triangles in file" );
00140 
00141         // Make sure we didn't underrun.
00142         if (mTriangles.size()!=mNumTriangles)
00143             throw cParsingException("cRK3DRawAsciiModel::load",
00144                                     "Data underrun.  Not enough vertices or triangles" );
00145 
00146         // Calculate normals for lighting
00147         calcVertexNormals();
00148     }
00149 
00150     /******************************************************************/
00151     const tString & cRK3DRawAsciiModel::vfsType() const
00152     {
00153         return VfsFileType_K3DRaw;
00154     }
00155 
00156     /* ************************************************************ */
00157     void cRK3DRawAsciiModel::render(    const cAutoPtr<const cGLTexture> & i_iTexture,
00158                                         const tRenderOptions iOptions ) const
00159     {
00160         if (!mNumTriangles || !mNumVertices) 
00161             throw cBadDataUseException( "cRK3DRawAsciiModel::render",
00162                                         "Rendering an uninitialized model" );
00163 
00164         const tBool Normals( !(iOptions & R_NoNormals) );
00165 
00166         glEnable(GL_CULL_FACE);
00167         glCullFace(GL_BACK);
00168         glEnable( GL_DEPTH_TEST );
00169 
00170         if (iOptions & R_Wireframe)
00171             glBegin( GL_LINE_STRIP );
00172         else glBegin( GL_TRIANGLES );
00173 
00174         for (tUint i=0; mNumTriangles>i; ++i) {
00175             if (Normals)
00176                 glNormal3f( mFaceNormals[i].x,
00177                             mFaceNormals[i].y,
00178                             mFaceNormals[i].z );
00179             glVertex3f( mVertices[mTriangles[i].a].x,
00180                         mVertices[mTriangles[i].a].y,
00181                         mVertices[mTriangles[i].a].z );
00182             glVertex3f( mVertices[mTriangles[i].b].x,
00183                         mVertices[mTriangles[i].b].y,
00184                         mVertices[mTriangles[i].b].z );
00185             glVertex3f( mVertices[mTriangles[i].c].x,
00186                         mVertices[mTriangles[i].c].y,
00187                         mVertices[mTriangles[i].c].z );
00188         }
00189         glEnd();
00190         glDisable( GL_DEPTH_TEST );
00191         glDisable( GL_CULL_FACE );
00192     }
00193 
00194 
00195     /* ************************************************************ */
00196     void cRK3DRawAsciiModel::free()
00197     {
00198         mNumVertices = 0;
00199         mNumTriangles = 0;
00200         mVertices.clear();
00201         mTriangles.clear();
00202     }
00203 
00204 
00205     /* ************************************************************ */
00206     void cRK3DRawAsciiModel::calcVertexNormals()
00207     {
00208         if (!mNumTriangles || !mNumVertices) 
00209             throw cBadDataUseException( "cRK3DRawAsciiModel::calcVertexNormals",
00210                                         "Using an uninitialized model" );
00211         // First off, we'll step through all the faces and calculate the
00212         // face normals.
00213         mFaceNormals.reserve(mNumTriangles);
00214         for (tUint i=0; i<mNumTriangles; ++i) {
00215             // Calculate two vector edges 
00216             tVector3f e1(   mVertices[mTriangles[i].b].x-mVertices[mTriangles[i].a].x,
00217                             mVertices[mTriangles[i].b].y-mVertices[mTriangles[i].a].y,
00218                             mVertices[mTriangles[i].b].z-mVertices[mTriangles[i].a].z );
00219             tVector3f e2(   mVertices[mTriangles[i].c].x-mVertices[mTriangles[i].a].x,
00220                             mVertices[mTriangles[i].c].y-mVertices[mTriangles[i].a].y,
00221                             mVertices[mTriangles[i].c].z-mVertices[mTriangles[i].a].z );
00222             tVector3f norm(e1.cross(e2));
00223             norm.normalize();
00224             tVertex normVertex = { norm.x(),norm.y(),norm.z() };
00225             mFaceNormals.push_back( normVertex );
00226         }
00227         // Use the face normals to calculate normals for each vertex.
00228         tVertexList *tempNormals = new tVertexList[mNumVertices];
00229         mVertexNormals.reserve(mNumVertices);
00230         
00231         for (tUint i=0; i<mNumTriangles; ++i)
00232             for (tUint v=0; v<mNumVertices; ++v) {
00233                 
00234             }
00235         delete []tempNormals;
00236     }
00237 
00238 
00239     /******************************************************************/
00240     void cRK3DRawAsciiModel::centerAroundOrigin()
00241     {
00242         if (!mNumTriangles || !mNumVertices)
00243             throw cBadDataUseException( "cRK3DRawAsciiModel::centerAroundOrigin",
00244                                         "Tried to modify a model with no vertices" );
00245         // Re-orient the object so it is centered on the origin
00246         // Get the min & max in each of x,y and z
00247         tVector3f minV( mVertices[0].z, mVertices[0].y, mVertices[0].z );
00248         tVector3f maxV( mVertices[0].z, mVertices[0].y, mVertices[0].z );
00249         for (tUint v=1; v<mNumVertices; ++v) {
00250             minV.set(   n2l_min(mVertices[v].x,minV.x()),
00251                         n2l_min(mVertices[v].y,minV.y()),
00252                         n2l_min(mVertices[v].z,minV.z()) );
00253             maxV.set(   n2l_max(mVertices[v].x,maxV.x()),
00254                         n2l_max(mVertices[v].y,maxV.y()),
00255                         n2l_max(mVertices[v].z,maxV.z()) );
00256         }
00257         const tVector3f ModelCenter( minV+((maxV-minV)*0.5f) );
00258         for (tUint v=0; v<mNumVertices; ++v) {
00259             mVertices[v].x -= ModelCenter.x();
00260             mVertices[v].y -= ModelCenter.y();
00261             mVertices[v].z -= ModelCenter.z();
00262         }
00263     }
00264 
00265 } // namespace
©2012 Aaron Cameron