www.pudn.com > zfxcengine-0.1.0.zip > ceMeshFactory.cpp
// $Id: ceMeshFactory.cpp,v 1.1 2005/09/13 00:59:46 andreaskohn Exp $
////////////////////////////////////////////////////////////////////////////////
//
// Module: Core
// File: ceMeshFactory
// Created: 25.10.2004
// Author: Enrico
// Licence: See licence file in root
// Last Mod: $Id: ceMeshFactory.cpp,v 1.1 2005/09/13 00:59:46 andreaskohn Exp $
//
////////////////////////////////////////////////////////////////////////////////
#include "Core/ceExceptions.h"
#include "Geometry/ceMeshFactory.h"
#include "Core/ceResourceManager.h"
#include "Geometry/ceMesh.h"
#include "Core/ceDebug.h"
#include "Core/ceMemManager.h"
#include "Geometry/ceMeshFormatQ3BSP.h"
namespace ZFXCE {
//------------------------------------------------------------------------------
ceMeshFactory::ceMeshFactory(ceVFSystem* VFS, ceResourceManager *pResMgr)
: ceResourceFactory("ceMesh", pResMgr)
{
PUSH_FUNCTION;
ce_assert(NULL != VFS);
ce_assert(NULL != pResMgr);
m_VFS = VFS;
Init();
}
//------------------------------------------------------------------------------
ceMeshFactory::~ceMeshFactory()
{
PUSH_FUNCTION;
Release();
}
//------------------------------------------------------------------------------
void ceMeshFactory::Release()
{
PUSH_FUNCTION;
// Releasing allocated file format descriptors
m_VFS = NULL;
for (size_t f=0; f < m_SupportedFileFormats.size(); ++f)
delete m_SupportedFileFormats[f];
m_SupportedFileFormats.clear();
// Releasing allocated mesh instances
std::vector::iterator it;
for (it = m_vMeshArray.begin(); it != m_vMeshArray.end(); ++it) {
delete (*it);
}
m_vMeshArray.clear();
}
//------------------------------------------------------------------------------
void ceMeshFactory::Init()
{
PUSH_FUNCTION;
m_SupportedFileFormats.push_back(new ceMeshFormatMD2());
m_SupportedFileFormats.push_back(new ceMeshFormatMD3());
m_SupportedFileFormats.push_back(new ceMeshFormatD3Proc());
m_SupportedFileFormats.push_back(new ceMeshFormatQ3BSP());
}
//------------------------------------------------------------------------------
ceMesh* ceMeshFactory::Load(std::string filename)
{
PUSH_FUNCTION;
if (0 == m_SupportedFileFormats.size()) {
const std::string error = std::string(__FUNCTION__) + std::string(": Keine Dateiformate unterstützt!");
CE_EXCEPTION(error, CELS_ERROR);
}
// Checken, ob das Format unterstützt wird
const size_t nl = filename.length();
//std::string ext = filename[nl-3] + filename[nl-2] + filename[nl-1];
//std::string ext="md2";
std::string ext = "";
ext += filename[nl-3];
ext += filename[nl-2];
ext += filename[nl-1];
IMFI* formatinfo=NULL;
for (UINT i=0; i < m_SupportedFileFormats.size(); i++) {
if(ext == m_SupportedFileFormats[i]->FileExt) {
formatinfo = m_SupportedFileFormats[i];
// Ok, will be supported
break;
}
}
if(NULL == formatinfo) {
std::cout << "Cannot find file format : " << filename << std::endl;
return NULL;
}
INT FileID = m_VFS->OpenFile(filename, (ZFXCE::eFileType) formatinfo->FileType);
// Was a file found?
if (-1 == FileID) {
std::cout << __FUNCTION__ << ": Datei nicht gefunden: " << filename << endl;
return NULL;
}
const size_t FileSize = m_VFS->GetFileSize(FileID);
BYTE* FileData = new BYTE[ FileSize];
ce_assert(NULL != FileData);
memset(&FileData[0], 0, sizeof(BYTE) * FileSize );
m_VFS->GetFileData(FileID, &FileData[0], FileSize);
m_VFS->CloseFile(FileID);
return formatinfo->Load(FileData, FileSize);
}
//------------------------------------------------------------------------------
ceMesh* ceMeshFactory::Load(BYTE *pData, const size_t sSize,
std::string FileformatExt)
{
PUSH_FUNCTION;
ceResTypeID ResType;
ResType.m_uiResTypeID = m_uiResTypeID;
ceMesh *pMesh = NULL;
// Load specific mesh data
if (FileformatExt == "md2") {
// MD2 dormat
IMFI* format = new ceMeshFormatMD2();
ce_assert (NULL != format);
pMesh = format->Load(pData, sSize);
pMesh->SetResTypeID(ResType);
}
else if ("bsp" == FileformatExt) {
// Q3 format
IMFI *pFormat = new ceMeshFormatQ3BSP();
ce_assert (NULL != pFormat);
pMesh = pFormat->Load(pData, sSize);
pMesh->SetResTypeID(ResType);
}
m_vMeshArray.push_back(pMesh);
return pMesh;
}
//------------------------------------------------------------------------------
ceMesh *ceMeshFactory::CreateInstance(const std::string strMeshName)
{
PUSH_FUNCTION;
ceMesh *pMesh = new ceMesh();
ce_assert (NULL != pMesh);
pMesh->SetResName(strMeshName);
ceResTypeID ResType;
ResType.m_uiResTypeID = m_uiResTypeID;
m_vMeshArray.push_back(pMesh);
return pMesh;
}
//------------------------------------------------------------------------------
std::vector ceMeshFactory::GetSupportedFileFormats() const
{
return m_SupportedFileFormats;
}
//------------------------------------------------------------------------------
ceMesh *ceMeshFactory::BuildTriangle(ceVec3f V1, ceVec3f V2,
ceVec3f V3)
{
PUSH_FUNCTION;
// Build new mesh instance
ceMesh *pMesh = CreateInstance("tri");
// Generate basic data
vector Vecs;
Vecs.push_back(V1);
Vecs.push_back(V2);
Vecs.push_back(V3);
pMesh->SetVertices(Vecs);
vector vIndices;
vIndices.push_back(0);
vIndices.push_back(1);
vIndices.push_back(2);
pMesh->SetIndices(vIndices);
return pMesh;
}
//------------------------------------------------------------------------------
ceMesh *ceMeshFactory::BuildTriangleMesh(const std::string strName,
const ceVec3f V1, const ceVec3f V2, const ceVec3f V3, const ceColorRGBA color)
{
PUSH_FUNCTION;
ceMesh *pMesh = CreateInstance(strName);
return pMesh;
}
//------------------------------------------------------------------------------
ceMesh *ceMeshFactory::BuildCubeMesh(const string strName, const ceVec3f vPos,
const FLOAT fL, const FLOAT fB, const FLOAT fH, const ceColorRGBA color)
{
PUSH_FUNCTION;
ceMesh *pMesh = CreateInstance(strName);
// Calculate coordinates down
ceVec3f v[8];
v[0].x = vPos.x;
v[0].y = vPos.y;
v[0].z = vPos.z;
v[1].x = vPos.x + fL;
v[1].y = vPos.y;
v[1].z = vPos.z;
v[2].x = vPos.x + fL;
v[2].y = vPos.y + fB;
v[2].z = vPos.z;
v[3].x = vPos.x;
v[3].y = vPos.y + fB;
v[3].z = vPos.z;
v[4].x = vPos.x;
v[4].y = vPos.y;
v[4].z = vPos.z + fH;
v[5].x = vPos.x + fL;
v[5].y = vPos.y;
v[5].z = vPos.z + fH;
v[6].x = vPos.x + fL;
v[6].y = vPos.y + fB;
v[6].z = vPos.z + fH;
v[7].x = vPos.x;
v[7].y = vPos.y + fB;
v[7].z = vPos.z + fH;
// Set cooridnates and color
vector Vecs;
vector vIndices;
vector vColor;
for (size_t i=0; i<8; ++i) {
ceColorRGBA col = color;
Vecs.push_back(v[i]);
vColor.push_back(col);
v[i].Dump();
cout << "---"< vFaces;
// Face down
faces[0].UIIndices.push_back(2);
faces[0].UIIndices.push_back(1);
faces[0].UIIndices.push_back(0);
faces[0].UIIndices.push_back(2);
faces[0].UIIndices.push_back(0);
faces[0].UIIndices.push_back(3);
vFaces.push_back(faces[0]);
// Face front
faces[1].UIIndices.push_back(0);
faces[1].UIIndices.push_back(1);
faces[1].UIIndices.push_back(5);
faces[1].UIIndices.push_back(0);
faces[1].UIIndices.push_back(4);
faces[1].UIIndices.push_back(5);
vFaces.push_back(faces[1]);
// Face right
faces[2].UIIndices.push_back(1);
faces[2].UIIndices.push_back(2);
faces[2].UIIndices.push_back(6);
faces[2].UIIndices.push_back(6);
faces[2].UIIndices.push_back(5);
faces[2].UIIndices.push_back(1);
vFaces.push_back(faces[2]);
// Face back
faces[3].UIIndices.push_back(6);
faces[3].UIIndices.push_back(2);
faces[3].UIIndices.push_back(3);
faces[3].UIIndices.push_back(3);
faces[3].UIIndices.push_back(7);
faces[3].UIIndices.push_back(6);
vFaces.push_back(faces[3]);
// Face left
faces[4].UIIndices.push_back(0);
faces[4].UIIndices.push_back(3);
faces[4].UIIndices.push_back(7);
faces[4].UIIndices.push_back(7);
faces[4].UIIndices.push_back(4);
faces[4].UIIndices.push_back(0);
vFaces.push_back(faces[4]);
// Face top
faces[5].UIIndices.push_back(6);
faces[5].UIIndices.push_back(5);
faces[5].UIIndices.push_back(4);
faces[5].UIIndices.push_back(4);
faces[5].UIIndices.push_back(7);
faces[5].UIIndices.push_back(6);
vFaces.push_back(faces[5]);
// Set edges and faces
pMesh->SetVertices(Vecs);
pMesh->SetFaces(vFaces);
pMesh->SetColor(vColor);
return pMesh;
}
//------------------------------------------------------------------------------
ceMesh *ceMeshFactory::BuildCubeMesh(const string strName, const ceVec3f vPos,
const FLOAT fL, const FLOAT fB, const FLOAT fH, const ceColorRGBA color,
const std::string strTexture)
{
PUSH_FUNCTION;
ceMesh *pMesh = BuildCubeMesh(strName, vPos, fL, fB, fH, color);
if (0 != strTexture.size()) {
vector vTexNames;
vTexNames.push_back(strTexture);
pMesh->SetTextureNames(vTexNames);
ceVec2f t[8];
vector vTexCoords;
t[0].x = 0.0f;
t[0].y = 0.0f;
t[1].x = 0.0f;
t[1].y = 0.0f;
t[2].x = 0.0f;
t[2].y = 0.0f;
t[3].x = 0.0f;
t[3].y = 0.0f;
t[4].x = 0.0f;
t[4].y = 0.0f;
t[5].x = 0.0f;
t[5].y = 0.0f;
t[6].x = 0.0f;
t[6].y = 0.0f;
t[7].x = 0.0f;
t[7].y = 0.0f;
for (size_t i=0; i<8; ++i) {
vTexCoords.push_back(t[i]);
}
pMesh->SetTexCoordsByName(strTexture, vTexCoords);
}
return pMesh;
}
//------------------------------------------------------------------------------
ceMesh* ceMeshFormatMD2::Load(BYTE* Data, size_t sSize)
{
PUSH_FUNCTION;
struct md2header
{
UINT Magic;
UINT Version;
UINT SkinWidth;
UINT SkinHeight;
UINT FrameSize;
UINT NSkins;
UINT NVertices;
UINT NTexCoords;
UINT NTriangles;
UINT NGLCommands;
UINT NFrames;
UINT OffsetSkins;
UINT OffsetTexCoords;
UINT OffsetTriangles;
UINT OffsetFrames;
UINT OffsetGLCommands;
UINT OffsetEnd;
};
struct md2tc {
short tu,tv;
};
struct md2skin {
char Name[64];
};
struct md2triangle {
md2triangle() {
Vertex[0] = Vertex[1] = Vertex[2] = 0.0f;
Normal[0] = Normal[1] = Normal[2] = 1.0f;
}
FLOAT Vertex[3];
FLOAT Normal[3];
};
struct md2face {
short VertexIndex[3];
short TexCoordIndex[3];
};
struct md2aliastriangle {
BYTE Vertex[3];
BYTE Normal;
};
struct md2aliasframe {
FLOAT Scale[3];
FLOAT Translate[3];
CHAR Name[16];
md2aliastriangle AliasTriangles[1];
};
struct md2frame {
FLOAT Scale[3];
FLOAT Translate[3];
md2frame(void) { Triangles = NULL; }
~md2frame(void) { if(Triangles) delete[] Triangles; Triangles = NULL; }
char Name[16];
md2triangle* Triangles;
};
UINT DataOffset = 0;
// read header
struct md2header Header;
memcpy(&Header, &Data[DataOffset], sizeof(struct md2header) );
DataOffset += sizeof(struct md2header);
/*
if(FormatVersion != Header.Version)
{
std::string error = "ceMeshFormatMD2::Load(): Falsche Formatversion: "+Header.Version;
error += "\nBrauche aber: ";
error += FormatVersion;
CE_EXCEPTION(error, CELS_ERROR);
}
if(MagicNumber != Header.Magic)
{
std::string error = "ceMeshFormatMD2::Load(): Falsche Magic-Number: "+Header.Magic;
error += "\nBrauche aber: ";
error += MagicNumber;
CE_EXCEPTION(error, CELS_ERROR);
}
*/
cout << "Skins: " << Header.NSkins << endl;
cout << "Vertices: " << Header.NVertices << endl;
cout << "TexCoords: " << Header.NTexCoords << endl;
cout << "Triangles: " << Header.NTriangles << endl;
cout << "Frames: " << Header.NFrames << endl;
ceMesh* Mesh = new ceMesh();
// every mesh is a frame. so we make a huge list of connected meshes to represent the frames
md2tc* TC = new md2tc[Header.NTexCoords];
md2face* triangles = new md2face[Header.NTriangles];
md2frame* frames = new md2frame[Header.NFrames];
DataOffset = Header.OffsetTexCoords;
memcpy(&TC[0], Data+DataOffset, sizeof(md2tc) * Header.NTexCoords);
DataOffset = Header.OffsetTriangles;
memcpy(&triangles[0], Data+DataOffset, sizeof(md2face) * Header.NTriangles);
DataOffset = Header.OffsetFrames;
UCHAR* Buffer = new UCHAR[2];
memcpy(&Buffer[0], Data+DataOffset, Header.FrameSize);
md2aliasframe* pFrame = (md2aliasframe*) Buffer;
//strncpy(&frames[0].Name[0], &tempframe->Name[0], 16);
cout << "Framename: " << pFrame->Name << endl;
frames[0].Triangles = new md2triangle[Header.NVertices];
for (UINT t=0; t < Header.NVertices; t++)
{
frames[0].Triangles[t].Vertex[0] = pFrame->AliasTriangles[t].Vertex[0] * pFrame->Scale[0] + pFrame->Translate[0];
frames[0].Triangles[t].Vertex[1] = pFrame->AliasTriangles[t].Vertex[1] * pFrame->Scale[1] + pFrame->Translate[1];
frames[0].Triangles[t].Vertex[2] = pFrame->AliasTriangles[t].Vertex[2] * pFrame->Scale[2] + pFrame->Translate[2];
}
delete[]Buffer;
/*
for(int f=0; f < Header.NFrames; f++)
{
md2frame* frame = &frames[f];
cout << "Frame: " << frame->Name << endl;
frame->Triangles = new md2vertex[Header.NVertices];
memcpy(&frame, Data+DataOffset, Header.FrameSize);
DataOffset += Header.FrameSize;
}
*/
// Release allocated data
delete [] TC;
delete [] triangles;
delete [] frames;
delete[] Data;
Data = NULL;
return Mesh;
}
//------------------------------------------------------------------------------
} // Namespace ZFXCE