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