www.pudn.com > MissileTest.rar > MilkshapeModel.cpp


// MilkshapeModel.cpp: implementation of the MilkshapeModel class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "MissileTest.h" 
#include "MilkshapeModel.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
#include  
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
MilkshapeModel::MilkshapeModel() 
{ 
 
} 
 
MilkshapeModel::~MilkshapeModel() 
{ 
 
} 
 
//	MS3D 数据结构  
#ifdef _MSC_VER 
#	pragma pack( push, packing ) 
#	pragma pack( 1 ) 
#	define PACK_STRUCT 
#elif defined( __GNUC__ ) 
#	define PACK_STRUCT	__attribute__((packed)) 
#else 
#	error you must byte-align these structures with the appropriate compiler directives 
#endif 
 
typedef unsigned char byte; 
typedef unsigned short word; 
 
// 文件头 
struct MS3DHeader 
{ 
	char m_ID[10]; 
	int m_version; 
} PACK_STRUCT; 
 
// 顶点信息 
struct MS3DVertex 
{ 
	byte m_flags; 
	float m_vertex[3]; 
	char m_boneID; 
	byte m_refCount; 
} PACK_STRUCT; 
 
// 三角形信息 
struct MS3DTriangle 
{ 
	word m_flags; 
	word m_vertexIndices[3]; 
	float m_vertexNormals[3][3]; 
	float m_s[3], m_t[3]; 
	byte m_smoothingGroup; 
	byte m_groupIndex; 
} PACK_STRUCT; 
 
// 材质信息 
struct MS3DMaterial 
{ 
    char m_name[32]; 
    float m_ambient[4]; 
    float m_diffuse[4]; 
    float m_specular[4]; 
    float m_emissive[4]; 
    float m_shininess;	 
    float m_transparency;	 
    byte m_mode;	 
    char m_texture[128]; 
    char m_alphamap[128]; 
} PACK_STRUCT; 
 
//	关节连接信息 
struct MS3DJoint 
{ 
	byte m_flags; 
	char m_name[32]; 
	char m_parentName[32]; 
	float m_rotation[3]; 
	float m_translation[3]; 
	word m_numRotationKeyframes; 
	word m_numTranslationKeyframes; 
} PACK_STRUCT; 
 
// 关键帧数据 
struct MS3DKeyframe 
{ 
	float m_time; 
	float m_parameter[3]; 
} PACK_STRUCT; 
 
// 缺省对齐 
#ifdef _MSC_VER 
#	pragma pack( pop, packing ) 
#endif 
 
#undef PACK_STRUCT 
 
bool MilkshapeModel::loadModelData( const char *filename ) 
{ 
	ifstream inputFile( filename, ios::in | ios::binary | ios::nocreate ); 
	if ( inputFile.fail()) 
		return false;	// "不能打开模型文件." 
 
	inputFile.seekg( 0, ios::end ); 
	long fileSize = inputFile.tellg(); 
	inputFile.seekg( 0, ios::beg ); 
 
	byte *pBuffer = new byte[fileSize]; 
	inputFile.read( pBuffer, fileSize ); 
	inputFile.close(); 
 
	const byte *pPtr = pBuffer; 
	MS3DHeader *pHeader = ( MS3DHeader* )pPtr; 
	pPtr += sizeof( MS3DHeader ); 
 
	if ( strncmp( pHeader->m_ID, "MS3D000000", 10 ) != 0 ) 
		return false; // "不是一个合法的Milkshape3D模型文件." 
 
	if ( pHeader->m_version < 3 || pHeader->m_version > 4 ) 
		return false; // "只能处理Milkshape3D 1.3 和 1.4版本." ); 
 
	int nVertices = *( word* )pPtr;  
	m_numVertices = nVertices; 
	m_pVertices = new Vertex[nVertices]; 
	pPtr += sizeof( word ); 
 
	int i; 
	for ( i = 0; i < nVertices; i++ ) 
	{ 
		MS3DVertex *pVertex = ( MS3DVertex* )pPtr; 
		m_pVertices[i].m_boneID = pVertex->m_boneID; 
		memcpy( m_pVertices[i].m_location, pVertex->m_vertex, sizeof( float )*3 ); 
		pPtr += sizeof( MS3DVertex ); 
	} 
 
	int nTriangles = *( word* )pPtr; 
	m_numTriangles = nTriangles; 
	m_pTriangles = 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_pTriangles[i].m_vertexNormals, pTriangle->m_vertexNormals, sizeof( float )*3*3 ); 
		memcpy( m_pTriangles[i].m_s, pTriangle->m_s, sizeof( float )*3 ); 
		memcpy( m_pTriangles[i].m_t, t, sizeof( float )*3 ); 
		memcpy( m_pTriangles[i].m_vertexIndices, vertexIndices, sizeof( int )*3 ); 
		pPtr += sizeof( MS3DTriangle ); 
	} 
 
	int nGroups = *( word* )pPtr; 
	m_numMeshes = nGroups; 
	m_pMeshes = 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_pMeshes[i].m_materialIndex = materialIndex; 
		m_pMeshes[i].m_numTriangles = nTriangles; 
		m_pMeshes[i].m_pTriangleIndices = pTriangleIndices; 
	} 
 
	int nMaterials = *( word* )pPtr; 
	m_numMaterials = nMaterials; 
	m_pMaterials = new Material[nMaterials]; 
	pPtr += sizeof( word ); 
	for ( i = 0; i < nMaterials; i++ ) 
	{ 
		MS3DMaterial *pMaterial = ( MS3DMaterial* )pPtr; 
		memcpy( m_pMaterials[i].m_ambient, pMaterial->m_ambient, sizeof( float )*4 ); 
		memcpy( m_pMaterials[i].m_diffuse, pMaterial->m_diffuse, sizeof( float )*4 ); 
		memcpy( m_pMaterials[i].m_specular, pMaterial->m_specular, sizeof( float )*4 ); 
		memcpy( m_pMaterials[i].m_emissive, pMaterial->m_emissive, sizeof( float )*4 ); 
		m_pMaterials[i].m_shininess = pMaterial->m_shininess; 
		m_pMaterials[i].m_pTextureFilename = new char[strlen( pMaterial->m_texture )+1]; 
		strcpy( m_pMaterials[i].m_pTextureFilename, pMaterial->m_texture ); 
		pPtr += sizeof( MS3DMaterial ); 
	} 
 
	reloadTextures(); 
 
	delete[] pBuffer; 
 
	return true; 
}