/* BaseMeshMemory.cpp Written by Matthew Fisher BaseMesh is an abstract mesh class that defines basic mesh functionality. It also includes source for most of the manipulation (shape generation, file loading, etc.) that is possible under this generic structure. Each mesh must be associated with a graphics device before most operations can be performed. Because there are so many associated functions, they are grouped into various files. BaseMeshMemory.cpp contains functions surrounding memory management and AppendVertices */ BaseMesh::BaseMesh() { _GD = NULL; } UINT BaseMesh::Hash32() const { return Utility::Hash32((const BYTE *)Vertices(), VertexCount() * sizeof(MeshVertex)) + Utility::Hash32((const BYTE *)Indices(), IndexCount() * sizeof(DWORD)); } UINT64 BaseMesh::Hash64() const { return Utility::Hash64((const BYTE *)Vertices(), VertexCount() * sizeof(MeshVertex)) + Utility::Hash64((const BYTE *)Indices(), IndexCount() * sizeof(DWORD)); } GraphicsDevice& BaseMesh::GetGD() const { PersistentAssert(_GD != NULL, "Graphics device requested from a mesh that was not associated"); return *_GD; } void BaseMesh::SetGD(GraphicsDevice &GD) { _GD = &GD; } void BaseMesh::CopyMesh(BaseMesh &Copy) const { Copy._GD = _GD; Copy.Allocate(VertexCount(), FaceCount()); memcpy(Copy.Vertices(), Vertices(), sizeof(MeshVertex) * VertexCount()); memcpy(Copy.Indices(), Indices(), sizeof(DWORD) * IndexCount()); } BaseMesh& BaseMesh::operator = (const BaseMesh &O) { O.CopyMesh(*this); return *this; } void BaseMesh::operator += (const BaseMesh &O) { AppendVertices(O); } void BaseMesh::AppendVertices(const BaseMesh &O) { int vc = VertexCount(), ic = IndexCount(); MeshVertex *V = Vertices(), *OldV = new MeshVertex[vc]; DWORD *I = Indices(), *OldI = new DWORD[ic]; memcpy(OldV, V, vc * sizeof(MeshVertex)); memcpy(OldI, I, ic * sizeof(DWORD)); //store all the old vertices/indices Allocate(vc + O.VertexCount(), ic/3 + O.FaceCount()); //allocate space for the current vertices/indices and o's vertices/indices V = Vertices(); I = Indices(); memcpy(V, OldV, vc * sizeof(MeshVertex)); memcpy(I, OldI, ic * sizeof(DWORD)); //copy the old vertices/indices back into the mesh, memcpy(&(V[vc]), O.Vertices(), O.VertexCount() * sizeof(MeshVertex)); //copy the new vertices after the current ones, UINT oic = O.IndexCount(); const DWORD *oI = O.Indices(); for(UINT i = 0; i < oic; i++) { I[ic+i] = oI[i] + vc; //copy o's indices as well, except increasing the index by vc (since o's vertices start at vc, not 0) } delete[] OldV; delete[] OldI; } void BaseMesh::LoadMeshList(const Vector &Meshes) { UINT NewVertexCount = 0, NewFaceCount = 0; for(UINT MeshIndex = 0; MeshIndex < Meshes.Length(); MeshIndex++) { const BaseMesh &CurMesh = *(Meshes[MeshIndex]); NewVertexCount += CurMesh.VertexCount(); NewFaceCount += CurMesh.FaceCount(); } Allocate(NewVertexCount, NewFaceCount); UINT VertexBaseIndex = 0, IndexBaseIndex = 0; MeshVertex *V = Vertices(); DWORD *I = Indices(); for(UINT MeshIndex = 0; MeshIndex < Meshes.Length(); MeshIndex++) { const BaseMesh &CurMesh = *(Meshes[MeshIndex]); const MeshVertex *CurV = CurMesh.Vertices(); const UINT CurVertexCount = CurMesh.VertexCount(); const DWORD *CurI = CurMesh.Indices(); const UINT CurFaceCount = CurMesh.FaceCount(); for(UINT VertexIndex = 0; VertexIndex < CurVertexCount; VertexIndex++) { V[VertexBaseIndex + VertexIndex] = CurV[VertexIndex]; } for(UINT FaceIndex = 0; FaceIndex < CurFaceCount; FaceIndex++) { for(UINT LocalVertexIndex = 0; LocalVertexIndex < 3; LocalVertexIndex++) { I[IndexBaseIndex + FaceIndex * 3 + LocalVertexIndex] = CurI[FaceIndex * 3 + LocalVertexIndex] + VertexBaseIndex; } } VertexBaseIndex += CurMesh.VertexCount(); IndexBaseIndex += CurMesh.FaceCount() * 3; } } void BaseMesh::LoadMeshList(const Vector< pair > &Meshes) { UINT NewVertexCount = 0, NewFaceCount = 0; for(UINT MeshIndex = 0; MeshIndex < Meshes.Length(); MeshIndex++) { const BaseMesh &CurMesh = *(Meshes[MeshIndex].first); NewVertexCount += CurMesh.VertexCount(); NewFaceCount += CurMesh.FaceCount(); } Allocate(NewVertexCount, NewFaceCount); UINT VertexBaseIndex = 0, IndexBaseIndex = 0; for(UINT MeshIndex = 0; MeshIndex < Meshes.Length(); MeshIndex++) { const BaseMesh &CurMesh = *(Meshes[MeshIndex].first); Matrix4 Transform = Meshes[MeshIndex].second; for(UINT VertexIndex = 0; VertexIndex < CurMesh.VertexCount(); VertexIndex++) { Vertices()[VertexBaseIndex + VertexIndex] = CurMesh.Vertices()[VertexIndex]; Vertices()[VertexBaseIndex + VertexIndex].Pos = Transform.TransformPoint(Vertices()[VertexBaseIndex + VertexIndex].Pos); } for(UINT FaceIndex = 0; FaceIndex < CurMesh.FaceCount(); FaceIndex++) { for(UINT LocalVertexIndex = 0; LocalVertexIndex < 3; LocalVertexIndex++) { Indices()[IndexBaseIndex + FaceIndex * 3 + LocalVertexIndex] = CurMesh.Indices()[FaceIndex * 3 + LocalVertexIndex] + VertexBaseIndex; } } VertexBaseIndex += CurMesh.VertexCount(); IndexBaseIndex += CurMesh.FaceCount() * 3; } }