#include "ThMD2Object.h"
using namespace Th;
#include <fstream>
//-------------------------------------------------------------
IMPLEMENT_STATIC_RTTI_MEMBER(MD2Object,Geometry)
IMPLEMENT_IS_DERIVED_FROM(MD2Object)
//-------------------------------------------------------------
MD2Object::MD2Object()
:
Geometry(), m_akFrames(NULL), m_akTriangle(NULL)
{
}
//-------------------------------------------------------------
MD2Object::MD2Object(const String& rkFilename)
:
Geometry()
{
if (LoadObject(rkFilename) != true)
assert(false);
}
//-------------------------------------------------------------
MD2Object::~MD2Object()
{
if (m_akFrames != NULL)
delete[] m_akFrames;
if (m_akTriangle != NULL)
delete[] m_akTriangle;
if (m_akTextureCoords != NULL)
delete[] m_akTextureCoords;
}
//-------------------------------------------------------------
bool MD2Object::LoadObject(const String& rkFilename)
{
//Loads the file given as parameter
//Load file
std::ifstream kFile;
kFile.open(rkFilename, std::ios::binary | std::ios::in);
if (!kFile)
{kFile.close(); return false;}
//Loading header
kFile.read((char *)&m_kHeader, sizeof(MD2Header));
//Check magic number
if (m_kHeader.iMagic != 0x32504449 ||m_kHeader.iVersion != 8)
{kFile.close(); return false;} //wrong magic number
//Load the frames
kFile.seekg(m_kHeader.iOffsetFrames, std::ios::beg); //seek to start
m_akFrames = new char[m_kHeader.iFrameSize * m_kHeader.iNumFrames];
kFile.read((char *)m_akFrames, m_kHeader.iFrameSize * m_kHeader.iNumFrames);
//Read in to vertex array
m_akVertex = new Vector3[m_kHeader.iNumFrames*m_kHeader.iNumVertices];
for (int i = 0; i < m_kHeader.iNumFrames; i++)
{
for (int j = 0; j < m_kHeader.iNumVertices; j++)
{
int iVertexIndex = i*m_kHeader.iNumVertices+j;
int iFrameIndex = i*m_kHeader.iFrameSize;
m_akVertex[iVertexIndex].x = (float)(((MD2Frame*)&m_akFrames[iFrameIndex])->akVertices[j].abVertex[0]);
m_akVertex[iVertexIndex].y = (float)(((MD2Frame*)&m_akFrames[iFrameIndex])->akVertices[j].abVertex[1]);
m_akVertex[iVertexIndex].z = (float)(((MD2Frame*)&m_akFrames[iFrameIndex])->akVertices[j].abVertex[2]);
m_akVertex[iVertexIndex].x *= ((MD2Frame*)&m_akFrames[iFrameIndex])->afScale[0];
m_akVertex[iVertexIndex].y *= ((MD2Frame*)&m_akFrames[iFrameIndex])->afScale[1];
m_akVertex[iVertexIndex].z *= ((MD2Frame*)&m_akFrames[iFrameIndex])->afScale[2];
//scale them:
m_akVertex[iVertexIndex].x += ((MD2Frame*)&m_akFrames[iFrameIndex])->afTranslate[0];
m_akVertex[iVertexIndex].y += ((MD2Frame*)&m_akFrames[iFrameIndex])->afTranslate[1];
m_akVertex[iVertexIndex].z += ((MD2Frame*)&m_akFrames[iFrameIndex])->afTranslate[2];
}
}
//Read triangles
m_akTriangle = new MD2Triangle[m_kHeader.iNumTriangles];
kFile.seekg(m_kHeader.iOffsetTriangles, std::ios::beg);
kFile.read((char *)m_akTriangle, m_kHeader.iNumTriangles * sizeof(MD2Triangle));
//Read texture coordinates
m_akTextureCoords = new MD2TextureCoord[m_kHeader.iNumTexCoords];
kFile.seekg(m_kHeader.iOffsetTexCoords, std::ios::beg);
kFile.read((char *)m_akTextureCoords, sizeof(MD2TextureCoord)*m_kHeader.iNumTexCoords);
//Build bounding volume
m_kModelBound.ComputeFromData(m_akVertex, m_kHeader.iNumVertices);
kFile.close(); //close up nicely
return true;
}
//-------------------------------------------------------------
void MD2Object::Draw(Renderer &rkRenderer)
{
Geometry::Draw(rkRenderer);
rkRenderer.Render(this);
}
//-------------------------------------------------------------
const MD2Object::MD2Header& MD2Object::Header() const
{
return m_kHeader;
}
//-------------------------------------------------------------
const MD2Object::MD2Triangle* MD2Object::Triangles() const
{
return m_akTriangle;
}
//-------------------------------------------------------------
const MD2Object::MD2TextureCoord* MD2Object::TextureCoords() const
{
return m_akTextureCoords;
}
//-------------------------------------------------------------