Mesh.cpp
上传用户:sz83729876
上传日期:2013-03-07
资源大小:4140k
文件大小:6k
- #include <math.h>
- #include "Log.h"
- #include "Mesh.h"
- #include "3dsloader.h"
- //****************************************
- // CMesh
- //****************************************
- CMesh::CMesh()
- {
- m_strName = "Unknown Mesh";
- m_pVertices = NULL;
- m_pIndices = NULL;
- m_dwIndexCount = 0;
- m_dwVertexCount = 0;
- m_pMaterial = NULL;
- }
- CMesh::~CMesh()
- {
- if (m_pVertices)
- {
- delete[] m_pVertices;
- m_pVertices = NULL;
- }
- if (m_pIndices)
- {
- delete[] m_pIndices;
- m_pIndices = NULL;
- }
- }
- // standard hardcoded renderer
- void CMesh::Render()
- {
- glEnable( GL_TEXTURE_2D );
- glBindTexture( GL_TEXTURE_2D, m_pMaterial->m_iTextureID );
- //glColor4f( 1, 1, 1, 1 );
- glBegin( GL_TRIANGLES );
- for( int i=0; i<m_dwIndexCount/3; i++ )
- {
- CVertex v1 = m_pVertices[ m_pIndices[i*3+0] ];
- CVertex v2 = m_pVertices[ m_pIndices[i*3+1] ];
- CVertex v3 = m_pVertices[ m_pIndices[i*3+2] ];
- glNormal3f( v1.nx, v1.ny, v1.nz );
- glTexCoord2f( v1.tu, v1.tv );
- glVertex3f( v1.x, v1.y, v1.z );
- glNormal3f( v2.nx, v2.ny, v2.nz );
- glTexCoord2f( v2.tu, v2.tv );
- glVertex3f( v2.x, v2.y, v2.z );
- glNormal3f( v3.nx, v3.ny, v3.nz );
- glTexCoord2f( v3.tu, v3.tv );
- glVertex3f( v3.x, v3.y, v3.z );
- }
- glEnd();
- /*glColor3f( 1, 1, 0 );
- glBegin( GL_LINES );
- for( i=0; i<m_dwVertexCount; i++ )
- {
- CVertex v1 = m_pVertices[ i ];
- glVertex3f( v1.x, v1.y, v1.z );
- glVertex3f( v1.x+(v1.nx*5), v1.y+(v1.ny*5), v1.z+(v1.nz*5) );
- }
- glEnd();
- glColor3f( 1, 1, 1 );*/
- }
- void CMesh::CalculateNormals()
- {
- // temporary normal buffer
- float *pNormals = new float[ m_dwIndexCount ];
- for( int i=0; i<m_dwIndexCount/3; i++ )
- {
- CVertex v1 = m_pVertices[ m_pIndices[i*3+0] ];
- CVertex v2 = m_pVertices[ m_pIndices[i*3+1] ];
- CVertex v3 = m_pVertices[ m_pIndices[i*3+2] ];
- float x1, y1, z1;
- float x2, y2, z2;
- // two edges
- x1 = v1.x - v2.x;
- y1 = v1.y - v2.y;
- z1 = v1.z - v2.z;
- x2 = v1.x - v3.x;
- y2 = v1.y - v3.y;
- z2 = v1.z - v3.z;
- // crossproduct
- float nx = y1*z2 - z1*y2;
- float ny = z1*x2 - x1*z2;
- float nz = x1*y2 - y1*x2;
- // normalize
- float len = sqrtf( (nx*nx) + (ny*ny) + (nz*nz) );
- nx /= len;
- ny /= len;
- nz /= len;
- pNormals[ i*3 + 0 ] = nx;
- pNormals[ i*3 + 1 ] = ny;
- pNormals[ i*3 + 2 ] = nz;
- }
- for( int v=0; v<m_dwVertexCount; v++ )
- {
- float nx, ny, nz;
- int count;
- nx = ny = nz = 0.0f;
- count = 0;
- for( int i=0; i<m_dwIndexCount/3; i++ )
- {
- int idx = i * 3;
- if ((m_pIndices[idx+0] == v) ||
- (m_pIndices[idx+1] == v) ||
- (m_pIndices[idx+2] == v) )
- {
- nx += pNormals[ idx + 0 ];
- ny += pNormals[ idx + 1 ];
- nz += pNormals[ idx + 2 ];
- count++;
- }
- }
- if (count>0)
- {
- nx /= count;
- ny /= count;
- nz /= count;
- }
- float len = sqrtf( (nx*nx) + (ny*ny) + (nz*nz) );
- if (len<0.1f)
- {
- nx = 0;
- ny = 0;
- nz = 0;
- }
- m_pVertices[ v ].nx = nx;
- m_pVertices[ v ].ny = ny;
- m_pVertices[ v ].nz = nz;
- }
- delete[] pNormals;
- }
- //****************************************
- // CObject
- //****************************************
- CObject::CObject()
- {
- }
- CObject::~CObject()
- {
- // delete all meshes and materials
- for( int i=0; i<m_vMesh.size(); i++ )
- delete m_vMesh[i];
- for( i=0; i<m_vMaterials.size(); i++ )
- delete m_vMaterials[i];
- }
- bool CObject::LoadFrom3DS( std::string strFile )
- {
- CLoader3DS* pLoad = new CLoader3DS();
- // attempt loading..
- if (!pLoad->Load( strFile.c_str(), this ))
- {
- // failed,... return error
- delete pLoad;
- return false;
- }
- delete pLoad;
- if (!ParseMeshesAndMaterials())
- return false;
- Log::Print( "Mesh loaded "%s"...", strFile.c_str() );
- return true;
- }
- bool CObject::Render()
- {
- for( int i=0; i<m_vMesh.size(); i++ )
- m_vMesh[i]->Render();
- return true;
- }
- void CObject::AddMesh( CMesh* pMesh )
- {
- if (pMesh)
- {
- m_vMesh.push_back( pMesh );
- }
- }
- void CObject::AddMaterial( CMaterial* pMat )
- {
- if (pMat)
- {
- m_vMaterials.push_back( pMat );
- }
- }
- bool CObject::ParseMeshesAndMaterials()
- {
- // set mesh material properties
- for( int iMesh=0; iMesh<m_vMesh.size(); iMesh++ )
- {
- // find corresponding material
- for( int iMat=0; iMat<m_vMaterials.size(); iMat++ )
- {
- if (m_vMaterials[iMat]->m_strName.compare(m_vMesh[iMesh]->m_strMaterialName)==0)
- {
- m_vMesh[iMesh]->m_pMaterial = m_vMaterials[iMat];
- break;
- }
- }
- if (m_vMesh[iMesh]->m_pMaterial)
- {
- // scale texture coordinates
- for( int i=0; i<m_vMesh[iMesh]->m_dwVertexCount; i++ )
- {
- m_vMesh[iMesh]->m_pVertices[i].tu *= m_vMesh[iMesh]->m_pMaterial->m_fUScale;
- m_vMesh[iMesh]->m_pVertices[i].tv *= - m_vMesh[iMesh]->m_pMaterial->m_fVScale;
- }
- }
- for( int i=0; i<m_vMesh[iMesh]->m_dwVertexCount; i++ )
- {
- //m_vMesh[iMesh]->m_pVertices[ i ].x *= -1;
- //m_vMesh[iMesh]->m_pVertices[ i ].y *= -1;
- m_vMesh[iMesh]->m_pVertices[ i ].z *= -1;
- }
- m_vMesh[iMesh]->CalculateNormals();
- }
- // load textures if needed
- Texture* tm = Texture::GetInstance();
- for( int iMat=0; iMat<m_vMaterials.size(); iMat++ )
- {
- if (m_vMaterials[iMat]->m_bHasTexture)
- {
- m_vMaterials[iMat]->m_iTextureID = tm->LoadTexture( m_vMaterials[iMat]->m_strTextureName );
- if(m_vMaterials[iMat]->m_iTextureID==0xffff)
- return false;
- }
- }
- return true;
- }