To MD2 or not MD2

Started by
3 comments, last by matchu 15 years, 8 months ago
Well, I'm currently having problems with a MD2 loader. I've written one before, but I can't find the code. Now, I'm having problems with the one I'm trying to write. Here is a code sample, can someone please look it over and tell me whats going wrong. My specific problem is that, the program will not draw the data. It crashes right as its about to render it. I'm guessing its an invalid data problem, but I can't seem to find a solution.
[source lang = "cpp"]
struct Frame
{
	std::string name;
	vector3d * positions;
	vector3d * normals;
};

class CModelAnimated
{
public:
	vector2d * texcoords;
	unsigned int * indices;
	Frame * frames;
	unsigned int numVertices;
	unsigned int numIndices;
	int numFrames;
	int currentFrame, startFrame,endFrame;
	float time_tobetaken,time_elapsed;
	CModelAnimated()
	{
		frames = NULL;
		texcoords = NULL;
		indices = NULL;
	};
	~CModelAnimated()
	{
	};
	void Delete()
	{
			for(int i = 0; i < numFrames;i++)
			{
				delete [] frames.normals;
				delete [] frames.positions;
			};
			delete [] frames;
			delete [] indices;
			if(texcoords != NULL)
			{
				delete [] texcoords;
			};
	};
	vector2d * GetVertexTexCoords()
	{
		return texcoords;
	};
	unsigned int * GetIndices()
	{
		return indices;
	};
	unsigned int GetVertexCount()
	{
		return numVertices;
	};
	unsigned int GetIndexCount()
	{
		return numIndices;
	};
	vector3d * GetCurrentFrameVertices()
	{
		return frames[currentFrame].positions;
	};
	int GetCurrentFrame()
	{
		return currentFrame;
	};
	void SetCurrentFrame(int frame)
	{
		currentFrame = frame;
	};
	void SetAnimation(int start,int end,float total)
	{
		startFrame = start;
		endFrame = end;
		time_tobetaken = total;
		time_elapsed = 0.0f;
	};
	int SearchFrameID(std::string name)
	{
		for(int i = 0;i < numFrames;i++)
		{
			if(frames.name == name)
			{
				return i;
			}
			else
			{
				return -1;
			};
		};
	};
	void SetAnimation(std::string start,std::string end,float total_time)
	{
		startFrame = SearchFrameID(start);
		endFrame = SearchFrameID(end);
		time_tobetaken = total_time;
		time_elapsed = 0.0f;
	};	
};

struct MD2Header
	{
		int identifier;
		int version;
		int skinWidth;
		int skinHeight;
		int frameSize;
		int numSkins;
		int numVertices;
		int numTexCoords;
		int numTriangles;
		int numGLcmds;
		int numFrames;
		int skin_offset;
		int uv_offset;
		int triangles_offset;
		int frames_offset;
		int glcmds_offset;
		int end_offset;
	};
	struct MD2TriangleVertex
	{
		unsigned char vertices[3];
		unsigned char normal_index;
	};
	struct MD2Frame
	{
		vector3d scale;
		vector3d translation;
		char name[16];
	};
	struct MD2Triangle
	{
		unsigned short point[3];
		unsigned short uv[3];
	};
	struct MD2UV
	{
		short s,t;
	};
	vector3d CalculatePos(unsigned char pos[3],vector3d sca,vector3d trans)
	{
		return vector3d(((float)pos[0] * sca.x) + trans.x,
				((float)pos[1] * sca.y) + trans.y,
				((float)pos[2] * sca.z) + trans.z);
						
	};
	vector2d CalculateUV(MD2UV texcoord,MD2Header header)
        {
             return vector2d((float)texcoord.s/(float)header.skinWidth,						(float)texcoord.t/(float)header.skinHeight);
	};
	public:
	CModelAnimated * LoadAnimatedModel(std::string name)
	{
		FILE * file = fopen(name.c_str(),"rb");
		MD2Header md2_header;
		MD2UV md2_texcoord;
		MD2Triangle triangle;
		MD2Frame frame;
		CModelAnimated * model;
		vector2d * texcoords;

		fread(&md2_header,1,sizeof(MD2Header),file);

		model = new CModelAnimated;
		model->indices = new unsigned int[md2_header.numTriangles * 3];
		model->frames = new Frame[md2_header.numFrames];
		model->numFrames = md2_header.numFrames;
		model->numVertices = md2_header.numVertices;
		model->numIndices = md2_header.numTriangles;
		model->texcoords = new vector2d[md2_header.numTriangles * 3];
		texcoords = new vector2d[md2_header.numTexCoords];

		fseek(file,md2_header.uv_offset,SEEK_SET);
		for(int i = 0;i < md2_header.numTexCoords;i++)
		{
			fread(&md2_texcoord,1,sizeof(MD2UV),file);
			texcoords = CalculateUV(md2_texcoord,md2_header);
		};
		
		fseek(file,md2_header.triangles_offset,SEEK_SET);
		for(i = 0;i < md2_header.numTriangles;i += 3)
		{
			memset(&triangle,0,sizeof(MD2Triangle));
			fread(&triangle.point,3,sizeof(unsigned short),file);
			fread(&triangle.uv,3,sizeof(unsigned short),file);
			model->indices[(i * 3)] = triangle.point[0];
			model->indices[(i * 3) + 1] = triangle.point[1];
			model->indices[(i * 3) + 2] = triangle.point[2];
			model->texcoords[(i * 3)] = texcoords[triangle.uv[0]];
			model->texcoords[(i * 3) + 1] = texcoords[triangle.uv[1]];
			model->texcoords[(i * 3) + 2] = texcoords[triangle.uv[2]];
		};

		fseek(file,md2_header.frames_offset,SEEK_SET);
		for(i = 0; i < md2_header.numFrames;i++)
		{
			char tmpname[16];
			fread(&frame.scale,1,sizeof(vector3d),file);
			fread(&frame.translation,1,sizeof(vector3d),file);
			fread(tmpname,16,sizeof(char),file);
			model->frames.name = tmpname;
			model->frames.normals = new vector3d[md2_header.numVertices];
			model->frames.positions = new vector3d[md2_header.numVertices];

			unsigned char thepos[3];
			unsigned char thenorm;

			for(int j = 0;j < md2_header.numVertices;j++)
			{
				fread(thepos,3,sizeof(unsigned char),file);
				fread(&thenorm,1,sizeof(unsigned char),file);
				model->frames.positions[j] = CalculatePos(thepos,frame.scale,frame.translation);
				model->frames.normals[j] = normal_list[thenorm];
			};
		};
	
		delete [] texcoords;

		fclose(file);
		return model;
	};

//I'm using simple drawing code,since I'm having problems.
void DrawPlainAnimatedModel(CModelAnimated * model)
{
		glBegin(GL_TRIANGLES);
		for(unsigned int i = 0;i < model->numIndices;i++)
		{
			glVertex3f(model->frames[0].positions[model->indices].x,
					   model->frames[0].positions[model->indices].y,
					   model->frames[0].positions[model->indices].z);
		};
		glEnd();
};

Thanks in advance.



[Edited by - GavRobbs on August 1, 2008 9:37:48 PM]
Advertisement
What line causes the crash? What's the exception you get? That will make diagnosing your problem much easier.
this looks very strange in your load function...

for(i = 0;i < md2_header.numTriangles;i += 3){	memset(&triangle,0,sizeof(MD2Triangle));	fread(&triangle.point,3,sizeof(unsigned short),file);	fread(&triangle.uv,3,sizeof(unsigned short),file);	model->indices[(i * 3)] = triangle.point[0];	model->indices[(i * 3) + 1] = triangle.point[1];	model->indices[(i * 3) + 2] = triangle.point[2];	model->texcoords[(i * 3)] = texcoords[triangle.uv[0]];	model->texcoords[(i * 3) + 1] = texcoords[triangle.uv[1]];	model->texcoords[(i * 3) + 2] = texcoords[triangle.uv[2]];};


you use i*3 as the index in the array, but you have i += 3

so when i == 0, you have:
0 * 3     = 00 * 3 + 1 = 10 * 3 + 2 = 2


after that, i == 3
3 * 3     = 93 * 3 + 1 = 103 * 3 + 2 = 11


where are indices 3 to 8 ???

hope that helps

Thanks for that. It doesn't render at all now, although it doesn't crash.

[source lang = "cpp"]glBegin(GL_TRIANGLES);		for(unsigned int i = 0;i < model->numIndices;i++)		{			glVertex3f(model->frames[0].positions[model->indices].x,					   model->frames[0].positions[model->indices].y,					   model->frames[0].positions[model->indices].z);		};		glEnd();



Thats my rendering code for reference. I'm keeping it simple. After this loads, I'll add in texcoords and normals and make it use vertex arrays. Can someone please help me out? This is getting annoying.
Hi again !
i found something else in your code that can be the problem

unsigned char thepos[3];unsigned char thenorm;for(int j = 0;j < md2_header.numVertices;j++){	fread(thepos,3,sizeof(unsigned char),file);	fread(&thenorm,1,sizeof(unsigned char),file);	model->frames.positions[j] = CalculatePos(thepos,frame.scale,frame.translation);	model->frames.normals[j] = normal_list[thenorm];};


here thepos is an array of 3 unsigned char, but in CalculatePos you cast every unsigned char in the array as a float which, i guess, doesn't give you good coordinates for your model.

Hope that helps !

This topic is closed to new replies.

Advertisement