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; }