00001 #include "MercuryMesh.h"
00002 #include "MercuryUtil.h"
00003 #include "MercuryDisplay.h"
00004 #include "MercuryPoly.h"
00005 #include "MercuryMath.h"
00006 #include "MercuryLog.h"
00007
00008 MercuryMeshManager MESHMAN;
00009
00010 MercuryMeshCore::MercuryMeshCore()
00011 {
00012 m_iMeshCount = 0;
00013 m_drawType = MGL_INVALID;
00014
00015 m_useVBOs = false;
00016 m_verticesVBO = MVPtr(NULL);
00017 m_tangentVBO = MVPtr(NULL);
00018 m_binormalVBO = MVPtr(NULL);
00019 m_indicesVBO = MVPtr(NULL);
00020 m_extrasVBO = MVPtr(NULL);
00021 m_VBOinited = false;
00022 }
00023
00024 bool MercuryMeshManager::RegMesh( MercuryMesh * pOut, const MString & sName, bool bCanCache )
00025 {
00026 if( !bCanCache )
00027 {
00028 pOut->SetName( sName );
00029 pOut->core = new MercuryMeshCore;
00030 pOut->Init();
00031 pOut->core->m_iMeshCount = 1;
00032 return false;
00033 }
00034
00035 MercuryMeshCore ** m = m_hAllMeshes.get(sName);
00036
00037
00038 if( m )
00039 {
00040 pOut->SetName( sName );
00041 pOut->Init();
00042 pOut->core = (*m);
00043 pOut->core->m_iMeshCount++;
00044 return true;
00045 }
00046
00047
00048 pOut->SetName( sName );
00049 m_hAllMeshes[sName] = pOut->core = new MercuryMeshCore;
00050 pOut->Init();
00051 pOut->core->m_iMeshCount = 1;
00052 return false;
00053 }
00054
00055 void MercuryMeshManager::UnregMesh( MercuryMesh * pIn )
00056 {
00057 pIn->core->m_iMeshCount--;
00058 if( pIn->core->m_iMeshCount <= 0 )
00059 {
00060 DISPLAY->DestroyVBO(*pIn);
00061
00062 if( m_hAllMeshes.get( pIn->GetName() ) )
00063 m_hAllMeshes.remove( pIn->GetName() );
00064 SAFE_DELETE( pIn->core );
00065 return;
00066 }
00067 }
00068
00069
00070 MercuryMesh::MercuryMesh()
00071 :MercuryObject()
00072 {
00073 m_glState.Disable(MGLS_ALL);
00074 m_glState.Enable(MGLS_DEPTHWRITE | MGLS_DEPTHTEST | MGLS_COLORWRITE | MGLS_VERTEXARRAY |
00075 MGLS_NORMALARRAY | MGLS_UVARRAY | MGLS_TEXTURING | MGLS_LIGHTING | MGLS_BLEND |
00076 MGLS_SHADER | MGLS_OPAQUE );
00077 }
00078
00079 MercuryMesh::~MercuryMesh()
00080 {
00081 MESHMAN.UnregMesh(this);
00082 }
00083
00084 void MercuryMesh::Init()
00085 {
00086 MercuryObject::Init();
00087 m_drawable = true;
00088 }
00089
00090 void MercuryMesh::Draw()
00091 {
00092 if (core->m_drawType == MGL_INVALID)
00093 return;
00094
00095 ASSERT(!GetName().empty());
00096
00097 DISPLAY->SendMatrixData(GetFinalMatrix());
00098
00099
00100
00101
00102 DISPLAY->DrawMesh(*this);
00103 }
00104
00105 void MercuryMesh::BuildVBO()
00106 {
00107 if (core->m_useVBOs && !core->m_VBOinited)
00108 {
00109 DISPLAY->GenerateVBO(*this);
00110 core->m_VBOinited = true;
00111 }
00112 }
00113
00114 void MercuryMeshCore::CalculateVertexNormals()
00115 {
00116 unsigned i;
00117 MVector <float> numFacePerVert;
00118 numFacePerVert.resize(m_vertices.size());
00119
00120 for( i = 0; i < m_vertices.size(); ++i )
00121 {
00122 numFacePerVert[i] = 0;
00123 m_vertices[i].m_normal.Clear();
00124 }
00125
00126 if (m_drawType == MGL_TRIANGLE)
00127 for( i = 0; i < m_indices.size(); i+=3 )
00128 {
00129 MercuryPoint pThisNormal = ( m_vertices[m_indices[i]].GetPointHandle() -
00130 m_vertices[m_indices[i+1]].GetPointHandle() ).CrossProduct(
00131 m_vertices[m_indices[i]].GetPointHandle() -
00132 m_vertices[m_indices[i+2]].GetPointHandle());
00133
00134 m_vertices[m_indices[i]].m_normal += pThisNormal;
00135 m_vertices[m_indices[i+1]].m_normal += pThisNormal;
00136 m_vertices[m_indices[i+2]].m_normal += pThisNormal;
00137
00138 ++numFacePerVert[m_indices[i]];
00139 ++numFacePerVert[m_indices[i+1]];
00140 ++numFacePerVert[m_indices[i+2]];
00141 }
00142
00143 for( i = 0; i < m_vertices.size(); ++i )
00144 {
00145 m_vertices[i].m_normal /= numFacePerVert[i];
00146 m_vertices[i].m_normal.NormalizeSelf();
00147 }
00148
00149 ComputeBinormalsAndTangents();
00150 }
00151
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 inline void RowAddEqualScalar( float * r1s, float * r2, float scalar )
00167 { r1s[0] += r2[0] * scalar; r1s[1] += r2[1] * scalar; r1s[2] += r2[2] * scalar; r1s[3] += r2[3] * scalar; }
00168
00169 inline void RowScale( float * r1s, float scalar )
00170 { r1s[0] *= scalar; r1s[1] *= scalar; r1s[2] *= scalar; r1s[3] *= scalar; }
00171
00172 void SolveThreeByFour( float * mat )
00173 {
00174
00175
00176 if( ABS( mat[0] ) < 0.001f )
00177 if( ABS( mat[4] ) > ABS( mat[8] ) )
00178 RowAddEqualScalar( &mat[0], &mat[4], 1 );
00179 else
00180 RowAddEqualScalar( &mat[0], &mat[8], 1 );
00181
00182
00183 RowScale( &mat[0], 1.f/mat[0] );
00184 RowAddEqualScalar( &mat[4], &mat[0], -mat[4]/mat[0] );
00185 RowAddEqualScalar( &mat[8], &mat[0], -mat[8]/mat[0] );
00186
00187 if( ABS( mat[5] ) < 0.001f )
00188 if( ABS( mat[1] ) > ABS( mat[9] ) )
00189 RowAddEqualScalar( &mat[4], &mat[0], 1 );
00190 else
00191 RowAddEqualScalar( &mat[4], &mat[8], 1 );
00192
00193 RowScale( &mat[4], 1.f/mat[5] );
00194 RowAddEqualScalar( &mat[0], &mat[4], -mat[1]/mat[5] );
00195 RowAddEqualScalar( &mat[8], &mat[4], -mat[9]/mat[5] );
00196
00197 if( ABS( mat[10] ) < 0.001f )
00198 if( ABS( mat[2] ) > ABS( mat[6] ) )
00199 RowAddEqualScalar( &mat[8], &mat[0], 1 );
00200 else
00201 RowAddEqualScalar( &mat[8], &mat[4], 1 );
00202
00203 RowScale( &mat[8], 1.f/mat[10] );
00204 RowAddEqualScalar( &mat[0], &mat[8], -mat[2]/mat[10] );
00205 RowAddEqualScalar( &mat[4], &mat[8], -mat[6]/mat[10] );
00206
00207
00208 return;
00209 }
00210
00211 void MercuryMeshCore::ComputeBinormalsAndTangents()
00212 {
00213 if (m_indices.size() <= 0)
00214 return;
00215
00216 unsigned int * ints = &m_indices[0];
00217
00218 m_tangents.resize( m_vertices.size() );
00219 m_binormals.resize( m_vertices.size() );
00220
00221 unsigned i;
00222
00223 for( i = 0; i < m_indices.size(); i+=3 )
00224 {
00225 unsigned int ind[3];
00226 ind[0] = ints[i+0];
00227 ind[1] = ints[i+1];
00228 ind[2] = ints[i+2];
00229
00230 float uv[3][2];
00231 MercuryPoint p[3];
00232 p[0] = m_vertices[ind[0]].GetPointHandle();
00233 p[1] = m_vertices[ind[1]].GetPointHandle();
00234 p[2] = m_vertices[ind[2]].GetPointHandle();
00235 m_vertices[ind[0]].GetUV( uv[0] );
00236 m_vertices[ind[1]].GetUV( uv[1] );
00237 m_vertices[ind[2]].GetUV( uv[2] );
00238
00239 MercuryPoint pLocalNormal;
00240 pLocalNormal = (p[0] - p[1]).CrossProduct( p[2] - p[1] );
00241 pLocalNormal.NormalizeSelf();
00242
00243 bool bSubZForX = false;
00244 bool bSubZForY = false;
00245
00246 if( ABS( pLocalNormal.z ) < 0.001f )
00247 {
00248 if( ABS( pLocalNormal.y ) < 0.001f )
00249 bSubZForX = true;
00250 else
00251 bSubZForY = true;
00252 }
00253
00254 float fMatToSolve[12];
00255 fMatToSolve[ 0] = (!bSubZForX)?p[0].x:p[0].z;
00256 fMatToSolve[ 1] = (!bSubZForY)?p[0].y:p[0].z;
00257 fMatToSolve[ 2] = uv[0][1];
00258 fMatToSolve[ 3] = 1;
00259 fMatToSolve[ 4] = (!bSubZForX)?p[1].x:p[1].z;
00260 fMatToSolve[ 5] = (!bSubZForY)?p[1].y:p[1].z;
00261 fMatToSolve[ 6] = uv[1][1];
00262 fMatToSolve[ 7] = 1;
00263 fMatToSolve[ 8] = (!bSubZForX)?p[2].x:p[2].z;
00264 fMatToSolve[ 9] = (!bSubZForY)?p[2].y:p[2].z;
00265 fMatToSolve[10] = uv[2][1];
00266 fMatToSolve[11] = 1;
00267
00268 SolveThreeByFour( fMatToSolve );
00269
00270 float xComp = fMatToSolve[3];
00271 float yComp = fMatToSolve[7];
00272 float cComp = fMatToSolve[11];
00273
00274 MercuryPoint pBiNormal;
00275 if( bSubZForX )
00276 {
00277 pBiNormal.x = 0;
00278 pBiNormal.y = yComp;
00279 pBiNormal.z = xComp;
00280 } else if( bSubZForY )
00281 {
00282 pBiNormal.x = xComp;
00283 pBiNormal.y = 0;
00284 pBiNormal.z = yComp;
00285 }
00286 else
00287 {
00288 pBiNormal.x = xComp;
00289 pBiNormal.y = yComp;
00290 pBiNormal.z = 0;
00291 }
00292
00293 MercuryPoint pTangent = (pBiNormal.CrossProduct( pLocalNormal )).Normalize();
00294
00295 pBiNormal = (pTangent.CrossProduct( pLocalNormal)).Normalize();
00296
00297 m_tangents[ind[0]] += pTangent;
00298 m_tangents[ind[1]] += pTangent;
00299 m_tangents[ind[2]] += pTangent;
00300
00301 m_binormals[ind[0]] += pBiNormal;
00302 m_binormals[ind[1]] += pBiNormal;
00303 m_binormals[ind[2]] += pBiNormal;
00304 }
00305
00306
00307 for( i = 0; i < m_tangents.size(); ++i )
00308 {
00309 m_tangents[i].NormalizeSelf();
00310 m_binormals[i].NormalizeSelf();
00311
00312 }
00313
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342