00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "KeosMesh.h"
00023 #include "KeosException.h"
00024 #include "KeosRoot.h"
00025 #include "KeosRenderSystem.h"
00026 #include "KeosUtil.h"
00027
00028 namespace Keos
00029 {
00030 #define Renderer CRoot::Instance().GetRenderSystem()
00031
00032
00033
00034
00035
00036
00037
00038 CMesh::CMesh()
00039 {}
00040
00041
00042 CMesh::~CMesh()
00043 {
00044 std::for_each(m_MeshGeomList.begin(), m_MeshGeomList.end(), Delete());
00045 std::for_each(m_MaterialList.begin(), m_MaterialList.end(), Delete());
00046 }
00047
00048
00049 void CMesh::Render() const
00050 {
00051 CMeshGeom* pTemp;
00052 for (uint i = 0; i < m_MeshGeomList.size(); i++)
00053 {
00054 pTemp = m_MeshGeomList[i];
00055 if (pTemp->GetMaterialIndex() != -1)
00056 {
00057 CMaterial* pMaterial = m_MaterialList[pTemp->GetMaterialIndex()];
00058 if (pMaterial->HasTexture())
00059 {
00060
00061
00062 Renderer->SetTexture(0, pMaterial->GetTexture()->GetTextureBase());
00063 }
00064 else Renderer->SetTexture(0, NULL);
00065 }
00066 Renderer->SetDeclaration(pTemp->m_pDeclaration);
00067 if (pTemp->m_bUseSharedVertexBuffer)
00068 Renderer->SetVertexBuffer(0, m_SharedVertexBuffer);
00069 else Renderer->SetVertexBuffer(0, pTemp->m_VertexBuffer);
00070 Renderer->SetIndexBuffer(pTemp->m_IndexBuffer);
00071 Renderer->DrawIndexedPrimitives(pTemp->m_PrimitiveType, 0, pTemp->m_nPrimitivesCount);
00072
00073 }
00074 }
00075
00076
00077 uint CMesh::GetTrianglesCount(void)
00078 {
00079 uint nRes = 0;
00080 for (uint i = 0; i < m_MeshGeomList.size(); i++)
00081 {
00082 nRes += m_MeshGeomList[i]->GetTrianglesCount();
00083
00084 }
00085 return nRes;
00086 }
00087
00088
00089 void CMesh::CreateSharedVertexBuffer(const CMeshGeom::TVertex* pVertices, ulong nVerticesCount)
00090 {
00091 Assert(pVertices != NULL);
00092 m_SharedVertexBuffer = Renderer->CreateVertexBuffer(nVerticesCount, 0, pVertices);
00093 }
00094
00095
00096 void CMesh::ComputeNormals()
00097 {
00101
00102 TVector3F vVector1, vVector2, vNormal, vPoly[3];
00103
00104
00105
00106
00107
00108 for (uint index = 0; index < m_MeshGeomList.size(); index++)
00109 {
00110 uint i;
00111
00112
00113 CMeshGeom* pMeshGeom = m_MeshGeomList[index];
00114
00115
00116 TVector3F *pNormals = new TVector3F [pMeshGeom->GetTrianglesCount()];
00117 TVector3F *pTempNormals = new TVector3F [pMeshGeom->GetTrianglesCount()];
00118
00119
00120 uint nVertexBufferSize;
00121 CMeshGeom::TVertex* Vertices;
00122 if (pMeshGeom->m_bUseSharedVertexBuffer)
00123 {
00124 Vertices = m_SharedVertexBuffer.Lock(0, 0, LOCK_WRITEONLY);
00125 nVertexBufferSize = m_SharedVertexBuffer.GetCount();
00126 }
00127 else
00128 {
00129 Vertices = pMeshGeom->m_VertexBuffer.Lock(0, 0, LOCK_WRITEONLY);
00130 nVertexBufferSize = pMeshGeom->m_VertexBuffer.GetCount();
00131 }
00132 CMeshGeom::TIndex* Indicies = pMeshGeom->m_IndexBuffer.Lock(0, 0, LOCK_READONLY);
00133
00134
00135 for (i = 0; i < pMeshGeom->GetTrianglesCount(); i++)
00136 {
00137
00138 vPoly[0] = Vertices[Indicies[i*3+0]].Position;
00139 vPoly[1] = Vertices[Indicies[i*3+1]].Position;
00140 vPoly[2] = Vertices[Indicies[i*3+2]].Position;
00141
00142
00143
00144 vVector1 = VectorBetweenTwoPoints(vPoly[0], vPoly[2]);
00145 vVector2 = VectorBetweenTwoPoints(vPoly[2], vPoly[1]);
00146
00147 vNormal = VectorCross(vVector1, vVector2);
00148 pTempNormals[i] = vNormal;
00149 vNormal.Normalize();
00150
00151 pNormals[i] = vNormal;
00152 }
00153
00154
00155 TVector3F vSum = TVector3F(0.0, 0.0, 0.0);
00156 TVector3F vZero = vSum;
00157 int shared = 0;
00158
00159 for (i = 0; i < nVertexBufferSize; i++)
00160 {
00161 for (uint j = 0; j < pMeshGeom->GetTrianglesCount(); j++)
00162 {
00163 if (Indicies[j*3+0] == i ||
00164 Indicies[j*3+1] == i ||
00165 Indicies[j*3+2] == i)
00166 {
00167 vSum += pTempNormals[j];
00168 shared++;
00169 }
00170 }
00171
00172
00173 if (pMeshGeom->m_bUseSharedVertexBuffer && (Vertices[i].Normal.LengthSq() != 0))
00174 Vertices[i].Normal = (vSum + Vertices[i].Normal / float(-(shared + 1)));
00175 Vertices[i].Normal = (vSum / float(-shared));
00176
00177
00178 Vertices[i].Normal.Normalize();
00179
00180 vSum = vZero;
00181 shared = 0;
00182 }
00183
00184
00185 if (pMeshGeom->m_bUseSharedVertexBuffer)
00186 m_SharedVertexBuffer.Unlock();
00187 else pMeshGeom->m_VertexBuffer.Unlock();
00188 pMeshGeom->m_IndexBuffer.Unlock();
00189
00190
00191 delete [] pTempNormals;
00192 delete [] pNormals;
00193 }
00194 }
00195
00196
00197 CMeshGeom* CMesh::GetMeshGeom(const String& strName) const
00198 {
00199 ushort nIndex = _GetMeshGeomIndex(strName);
00200 return GetMeshGeom(nIndex);
00201 }
00202
00203
00204 CMeshGeom* CMesh::GetMeshGeom(ushort nIndex) const
00205 {
00206 TMeshGeomList::const_iterator i = m_MeshGeomList.begin();
00207 return const_cast<CMeshGeom*>(i[nIndex]);
00208 }
00209
00210
00211 ushort CMesh::_GetMeshGeomIndex(const String& strName) const
00212 {
00213 TMeshGeomNameMap::const_iterator i = m_MeshGeomNameMap.find(strName) ;
00214 if (i == m_MeshGeomNameMap.end())
00215 throw new CException("No MeshGeom named " + strName + " found.");
00216
00217 return i->second;
00218 }
00219
00220 }