All pastes #953937 Raw Edit

Miscellany

public cpp v1 · immutable
#953937 ·published 2008-03-23 14:53 UTC
rendered paste body
#include "MilkShapeModel.h"/* MS3D STRUCTURES  */// byte-align structures#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#endiftypedef unsigned char byte;typedef unsigned short word;// File headerstruct MS3DHeader{	char m_ID[10];	int m_version;} PACK_STRUCT;// Vertex informationstruct MS3DVertex{	byte m_flags;	float m_vertex[3];	char m_boneID;	byte m_refCount;} PACK_STRUCT;// Triangle informationstruct 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;// Material informationstruct MS3DMaterial{	char m_name[32];	float m_ambient[4];	float m_diffuse[4];	float m_specular[4];	float m_emissive[4];	float m_shininess;	// 0.0f - 128.0f	float m_transparency;	// 0.0f - 1.0f	byte m_mode;	// 0, 1, 2 is unused now	char m_texture[128];	char m_alphamap[128];} PACK_STRUCT;//	Joint informationstruct 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;// Keyframe datastruct MS3DKeyframe{	float m_time;	float m_parameter[3];} PACK_STRUCT;// Default alignment#ifdef _MSC_VER#	pragma pack( pop, packing )#endif#undef PACK_STRUCTMilkShapeModel::MilkShapeModel(){	m_numMeshes = 0;	m_pMeshes = NULL;	m_numMaterials = 0;	m_pMaterials = NULL;	m_numTriangles = 0;	m_pTriangles = NULL;	m_numVertices = 0;	m_pVertices = NULL;	m_numJoints = 0;	m_pJoints = NULL;}MilkShapeModel::~MilkShapeModel(){	int i;	for ( i = 0; i < m_numMeshes; i++ )		delete[] m_pMeshes[i].m_pTriangleIndices;	for ( i = 0; i < m_numMaterials; i++ )		delete[] m_pMaterials[i].m_pTextureFilename;	m_numMeshes = 0;	if ( m_pMeshes != NULL )	{		delete[] m_pMeshes;		m_pMeshes = NULL;	}	m_numMaterials = 0;	if ( m_pMaterials != NULL )	{		delete[] m_pMaterials;		m_pMaterials = NULL;	}	m_numTriangles = 0;	if ( m_pTriangles != NULL )	{		delete[] m_pTriangles;		m_pTriangles = NULL;	}	m_numVertices = 0;	if ( m_pVertices != NULL )	{		delete[] m_pVertices;		m_pVertices = NULL;	}		m_numJoints = 0;		if (m_pJoints != NULL)	{		delete[] m_pJoints;		m_pJoints = NULL;	}}bool MilkShapeModel::load(const char* filename) {	string file = "data/";	file.append(filename);	ifstream inputFile(file.c_str(), ios::in | ios::binary);	if (inputFile.fail()) {		cout << "could not load model" << endl;		return false;	}	else cout << "loaded model " << filename << " into buffer"  << endl;	// Check filesize	inputFile.seekg(0, ios::end);	long fileSize = inputFile.tellg();	inputFile.seekg(0, ios::beg);	// Load complete file into buffer	char* buffer = new char[fileSize];	inputFile.read(buffer, fileSize);	inputFile.close();	// Check header information	const char* pPtr = buffer;	MS3DHeader  *pHeader = (MS3DHeader *) pPtr;	pPtr+=sizeof(MS3DHeader);	if ( strncmp( pHeader->m_ID, "MS3D000000", 10 ) != 0 )		return false;// "Not A Valid Milkshape3D Model File."	if ( pHeader->m_version < 3 || pHeader->m_version > 4 )		return false;// "Unhandled File Version. Only Milkshape3D Version 1.3 And    1.4 Is Supported."	cout << "VERSION: " << pHeader->m_version << endl;	// Load vertices	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 );	}	// Load Triangles	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 );	}	// Load Meshes	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;	}	// Load Materials	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 );	}	// Load AnimationFPS	float foo = *( float* )pPtr;	fAnimationFPS = foo;	pPtr += sizeof(float);	// Load currentTime	float fAnim = *(float*)pPtr;	fCurrentTime = fAnim;	pPtr += sizeof(float);	// Load total frames	int tot = *(int*)pPtr;	iTotalFrames = tot;	pPtr += sizeof(int);	// Load joints and keyframes	int joints = *(word*)pPtr;	m_numJoints = joints;	m_pJoints = new Joint[m_numJoints];	pPtr += sizeof ( word );	for ( i = 0; i < m_numJoints; i++ ) 	{		MS3DJoint *pJoint = ( MS3DJoint* )pPtr;		m_pJoints[i].numKeyFramesRot = pJoint->m_numRotationKeyframes;		m_pJoints[i].numKeyFramesTrans = pJoint->m_numTranslationKeyframes;		memcpy(m_pJoints[i].name, pJoint->m_name, sizeof(char)*32);		pPtr += sizeof( MS3DJoint );		m_pJoints[i].rotKeyframes = new RotKeyFrame[m_pJoints[i].numKeyFramesRot];		m_pJoints[i].posKeyframes = new PosKeyFrame[m_pJoints[i].numKeyFramesTrans];		for (int j = 0; j < m_pJoints[i].numKeyFramesRot; j++) {			MS3DKeyframe *pKey = ( MS3DKeyframe*)pPtr;			memcpy( m_pJoints[i].rotKeyframes[j].rotation, pKey->m_parameter, sizeof( float )*3 );			m_pJoints[i].rotKeyframes[j].time = pKey->m_time;			pPtr += sizeof(MS3DKeyframe);		}		for (int j = 0; j < m_pJoints[i].numKeyFramesTrans; j++) {			MS3DKeyframe *pKey = ( MS3DKeyframe*)pPtr;			memcpy( m_pJoints[i].posKeyframes[j].position, pKey->m_parameter, sizeof( float )*3 );			m_pJoints[i].posKeyframes[j].time = pKey->m_time;			pPtr += sizeof(MS3DKeyframe);		}	}	reloadTextures();	delete [] buffer;	return true;}void MilkShapeModel::draw() {	GLboolean texEnabled = glIsEnabled( GL_TEXTURE_2D );	// Draw by group	for ( int i = 0; i < m_numMeshes; i++ )	{		int materialIndex = m_pMeshes[i].m_materialIndex;		if ( materialIndex >= 0 )		{			glMaterialfv( GL_FRONT, GL_AMBIENT, m_pMaterials[materialIndex].m_ambient );			glMaterialfv( GL_FRONT, GL_DIFFUSE, m_pMaterials[materialIndex].m_diffuse );			glMaterialfv( GL_FRONT, GL_SPECULAR, m_pMaterials[materialIndex].m_specular );			glMaterialfv( GL_FRONT, GL_EMISSION, m_pMaterials[materialIndex].m_emissive );			glMaterialf( GL_FRONT, GL_SHININESS, m_pMaterials[materialIndex].m_shininess );			if ( m_pMaterials[materialIndex].m_texture > 0 )			{								glBindTexture( GL_TEXTURE_2D, m_pMaterials[materialIndex].m_texture );				glEnable( GL_TEXTURE_2D );			}			else				glDisable( GL_TEXTURE_2D );		}		else		{			// Material properties?			glDisable( GL_TEXTURE_2D );		}		glBegin( GL_TRIANGLES );		{			for ( int j = 0; j < m_pMeshes[i].m_numTriangles; j++ )			{				int triangleIndex = m_pMeshes[i].m_pTriangleIndices[j];				const Triangle* pTri = &m_pTriangles[triangleIndex];				for ( int k = 0; k < 3; k++ )				{					int index = pTri->m_vertexIndices[k];					glNormal3fv( pTri->m_vertexNormals[k] );					glTexCoord2f( pTri->m_s[k], pTri->m_t[k] );					glVertex3fv( m_pVertices[index].m_location );				}			}		}		glEnd();	}	if ( texEnabled )		glEnable( GL_TEXTURE_2D );	else		glDisable( GL_TEXTURE_2D );}void MilkShapeModel::SetupJoints() {		}void MilkShapeModel::reloadTextures(){	for ( int i = 0; i < m_numMaterials; i++ )		if ( strlen( m_pMaterials[i].m_pTextureFilename ) > 0 ) {			string name = "data/";			name.append(m_pMaterials[i].m_pTextureFilename);			Image *image = loadBMP(name.c_str());			image->outputData();			m_pMaterials[i].m_texture = loadTexture(image);			delete image;		}		else			m_pMaterials[i].m_texture = 0;}//Makes the image into a texture, and returns the id of the textureGLuint MilkShapeModel::loadTexture(Image *image) {	GLuint textureId;	glGenTextures(1, &textureId);	glBindTexture(GL_TEXTURE_2D, textureId);	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, image->width, image->height, 			0, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	return textureId;}void MilkShapeModel::outputData() {	for (int i = 0; i < m_numMeshes; i++) {		cout << "Mesh: " << i << " materialindex: " << m_pMeshes[i].m_materialIndex << endl;	}	cout << "Number of Materials: " << m_numMaterials << endl;	for (int i = 0; i < m_numMaterials; i++) {		cout << "Material: " << i << " textureID: " << m_pMaterials[i].m_texture;		cout << " filename: " << m_pMaterials[i].m_pTextureFilename << endl;	}		for (int i = 0; i < m_numJoints; i++)		cout << "joinname: " << m_pJoints[i].name << endl;	}