📄 ms3d.cpp
字号:
/*
GcModel.cpp
Loads and renders a Milkshape3D model.
Author: Brett Porter
Email: brettporter@yahoo.com
Website: http://rsn.gamedev.net
Copyright (C)2001, Brett Porter. All Rights Reserved.
This file may be used only as long as this copyright notice remains intact.
*/
//#include <iostream>
#include <fstream>
#include "ms3d.h"
using namespace std;
///////////////////////////////////////////////////////////////////////////////////////
GcMS3D::GcMS3D()
{
m_numMeshes = 0;
m_meshes = NULL;
m_numMaterials = 0;
m_materials = NULL;
m_numTriangles = 0;
m_triangles = NULL;
m_numVertices = 0;
m_vertices = NULL;
// { NEW }
m_numJoints = 0;
m_joints = NULL;
}
///////////////////////////////////////////////////////////////////////////////////////
GcMS3D::~GcMS3D()
{
Destroy();
}
///////////////////////////////////////////////////////////////////////////////////////
bool GcMS3D::Load(char *filename)
{
ifstream inputFile( filename, ios::in | ios::binary );
if( inputFile.fail() )
{
//cerr << "Couldn't open the model file." << endl;
return false;
}
char pathTemp[PATH_MAX+1];
int pathLength;
for ( pathLength = strlen( filename ); --pathLength; ) {
if ( filename[pathLength] == '/' || filename[pathLength] == '\\' ) {
break;
}
}
strncpy(pathTemp, filename, pathLength);
int i;
if ( pathLength > 0 ) {
pathTemp[pathLength++] = '/';
}
inputFile.seekg(0, ios::end);
long fileSize = inputFile.tellg();
inputFile.seekg(0, ios::beg);
byte * pBuffer = new byte[fileSize];
inputFile.read((char *)pBuffer, fileSize);
inputFile.close();
const byte *pPtr = pBuffer;
MS3DHeader *pHeader = ( MS3DHeader* )pPtr;
pPtr += sizeof( MS3DHeader );
if(strncmp( pHeader->m_ID, "MS3D000000", 10 ) != 0)
{
//cerr << "Not an MS3D file." << endl;
return false;
}
if( pHeader->m_version < 3 )
{
//cerr << "I know nothing about MS3D v1.2" << endl;
return false;
}
int nVertices = *(word*)pPtr;
m_numVertices = nVertices;
m_vertices = new Vertex[nVertices];
pPtr += sizeof(word);
for(i = 0; i < nVertices; i++)
{
MS3DVertex * pVertex = (MS3DVertex*)pPtr;
m_vertices[i].m_boneID = pVertex->m_boneID;
memcpy( m_vertices[i].m_location, pVertex->m_vertex, sizeof(float)*3);
//m_vertices[i].m_location.x = pVertex->m_vertex[0];
//m_vertices[i].m_location.y = pVertex->m_vertex[1];
//m_vertices[i].m_location.z = pVertex->m_vertex[2];
pPtr += sizeof(MS3DVertex);
}
int nTriangles = *(word*)pPtr;
m_numTriangles = nTriangles;
m_triangles = new Triangle[nTriangles];
pPtr += sizeof(word);
for ( i = 0; i < nTriangles; i++ )
{
MS3DTriangle *pTriangle = ( MS3DTriangle* )pPtr;
int vertexIndices[3] = { pTriangle->m_vertexIndices[0], pTriangle->m_vertexIndices[1], pTriangle->m_vertexIndices[2] };
float t[3] = { 1.0f-pTriangle->m_t[0], 1.0f-pTriangle->m_t[1], 1.0f-pTriangle->m_t[2] };
memcpy( m_triangles[i].m_vertexNormals, pTriangle->m_vertexNormals, sizeof(float)*3*3 );
memcpy( m_triangles[i].m_s, pTriangle->m_s, sizeof(float)*3 );
memcpy( m_triangles[i].m_t, t, sizeof(float)*3 );
memcpy( m_triangles[i].m_vertexIndices, vertexIndices, sizeof(int)*3 );
pPtr += sizeof( MS3DTriangle );
}
int nGroups = *(word*)pPtr;
m_numMeshes = nGroups;
m_meshes = new Mesh[nGroups];
pPtr += sizeof(word);
for ( i = 0; i < nGroups; i++ )
{
pPtr += sizeof(byte); // flags
pPtr += 32; // name
word nTriangles = *(word*)pPtr;
pPtr += sizeof(word);
int *pTriangleIndices = new int[nTriangles];
for ( int j = 0; j < nTriangles; j++ )
{
pTriangleIndices[j] = *(word*)pPtr;
pPtr += sizeof(word);
}
char materialIndex = *(char*)pPtr;
pPtr += sizeof(char);
m_meshes[i].m_materialIndex = materialIndex;
m_meshes[i].m_numTriangles = nTriangles;
m_meshes[i].m_triangleIndices = pTriangleIndices;
}
int nMaterials = *(word*)pPtr;
m_numMaterials = nMaterials;
m_materials = new Material[nMaterials];
pPtr += sizeof(word);
for(i = 0; i < nMaterials; i++)
{
MS3DMaterial *pMaterial = ( MS3DMaterial* )pPtr;
memcpy( m_materials[i].m_ambient, pMaterial->m_ambient, sizeof(float)*4 );
memcpy( m_materials[i].m_diffuse, pMaterial->m_diffuse, sizeof(float)*4 );
memcpy( m_materials[i].m_specular, pMaterial->m_specular, sizeof(float)*4 );
memcpy( m_materials[i].m_emissive, pMaterial->m_emissive, sizeof(float)*4 );
m_materials[i].m_shininess = pMaterial->m_shininess;
if(strncmp(pMaterial->m_texture, ".\\", 2) == 0)
{
// MS3D 1.5.x relative path
strcpy(pathTemp + pathLength, pMaterial->m_texture + 2);
//m_materials[i].m_textureFilename = new char[strlen( pathTemp )+1];
//strcpy(m_materials[i].m_textureFilename, pa
strcpy( m_materials[i].m_textureFilename, pathTemp );
m_materials[i].texture.Create(pathTemp);
}
else
{
// MS3D 1.4.x or earlier - absolute path
//m_materials[i].m_textureFilename = new char[strlen( pMaterial->m_texture )+1];
strcpy( m_materials[i].m_textureFilename, pMaterial->m_texture );
m_materials[i].texture.Create(pathTemp);
}
pPtr += sizeof(MS3DMaterial);
}
// Load Skeletal Animation Stuff
float animFPS = *(float*)pPtr;
pPtr += sizeof(float);
// skip currentTime
pPtr += sizeof(float);
int totalFrames = *(int*)pPtr;
pPtr += sizeof(int);
m_totalTime = totalFrames*1000.0/animFPS;
delete[] pBuffer;
GcVector3 extreme(0, 0, 0);
for( i = 0; i < m_numMeshes; i++ )
{
for( int j = 0; j < m_meshes[i].m_numTriangles; j++ )
{
int triangleIndex = m_meshes[i].m_triangleIndices[j];
const Triangle * pTri = &m_triangles[triangleIndex];
for ( int k = 0; k < 3; k++ )
{
int index = pTri->m_vertexIndices[k];
if( m_vertices[index].m_location[0] > extreme.x )
extreme.x = m_vertices[index].m_location[0];
if( m_vertices[index].m_location[1] > extreme.y )
extreme.y = m_vertices[index].m_location[1];
if( m_vertices[index].m_location[2] > extreme.z )
extreme.z = m_vertices[index].m_location[2];
}
}
}
g_Debug->Log("Extreme x: %f - y: %f - z: %f\n", extreme.x, extreme.y, extreme.z );
SetExtents(extreme);
return true;
}
///////////////////////////////////////////////////////////////////////////////////////
bool GcMS3D::RenderKeyFrame(int frame)
{
glPushMatrix();
static int loop = 0;
loop++;
if(loop > 360) {
loop = 0;
}
glMultMatrixf(m_worldMatrix);
glScalef(GetWorldScaling().x, GetWorldScaling().y, GetWorldScaling().z );
/* if(settings.ShowDebug())
{
glBegin(GL_LINES);
glColor3f(0.5, 0.0, 0.0);
glVertex3f(-2000, 0.0, 0.0);
glVertex3f( 2000, 0.0, 0.0);
glColor3f(0.5, 0.0, 0.0);
glVertex3f( 0, -2000, 0.0);
glVertex3f( 0, 2000, 0.0);
glColor3f(0.5, 0.0, 0.0);
glVertex3f( 0, 0, -2000);
glVertex3f( 0, 0, 2000);
glEnd();
}*/
glColor3f(1.0, 1.0, 1.0);
// Draw by group
for(int i = 0; i < m_numMeshes; i++)
{
int materialIndex = m_meshes[i].m_materialIndex;
if(materialIndex >= 0)
{
glMaterialfv( GL_FRONT, GL_AMBIENT, m_materials[materialIndex].m_ambient );
glMaterialfv( GL_FRONT, GL_DIFFUSE, m_materials[materialIndex].m_diffuse );
glMaterialfv( GL_FRONT, GL_SPECULAR, m_materials[materialIndex].m_specular );
glMaterialfv( GL_FRONT, GL_EMISSION, m_materials[materialIndex].m_emissive );
glMaterialf( GL_FRONT, GL_SHININESS, m_materials[materialIndex].m_shininess );
if(m_materials[materialIndex].texture.IsLoaded())
{
glEnable(GL_TEXTURE_2D);
m_materials[materialIndex].texture.Bind();
}
}
glBegin( GL_TRIANGLES );
{
for ( int j = 0; j < m_meshes[i].m_numTriangles; j++ )
{
int triangleIndex = m_meshes[i].m_triangleIndices[j];
const Triangle * pTri = &m_triangles[triangleIndex];
for ( int k = 0; k < 3; k++ )
{
int index = pTri->m_vertexIndices[k];
// same as before
glTexCoord2f( pTri->m_s[k], pTri->m_t[k] );
glNormal3fv( pTri->m_vertexNormals[k] );
glVertex3fv( m_vertices[index].m_location );
}
}
}
glEnd();
}
glPopMatrix();
//glDisable(GL_TEXTURE_2D);
return true;
}
///////////////////////////////////////////////////////////////////////////////////////
void GcMS3D::Destroy()
{
int i;
for ( i = 0; i < m_numMeshes; i++ )
delete[] m_meshes[i].m_triangleIndices;
//for ( i = 0; i < m_numMaterials; i++ )
//delete[] m_materials[i].m_pTextureFilename;
m_numMeshes = 0;
if ( m_meshes != NULL )
{
delete[] m_meshes;
m_meshes = NULL;
}
m_numMaterials = 0;
if ( m_materials != NULL )
{
delete[] m_materials;
m_materials = NULL;
}
m_numTriangles = 0;
if ( m_triangles != NULL )
{
delete[] m_triangles;
m_triangles = NULL;
}
m_numVertices = 0;
if ( m_vertices != NULL )
{
delete[] m_vertices;
m_vertices = NULL;
}
// { NEW }
for ( i = 0; i < m_numJoints; i++ )
{
delete[] m_joints[i].m_rotationKeyframes;
delete[] m_joints[i].m_translationKeyframes;
}
m_numJoints = 0;
if ( m_joints != NULL )
{
delete[] m_joints;
m_joints = NULL;
}
// { end NEW }
}
///////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -