Jump to content
  • Advertisement
Sign in to follow this  
GavRobbs

To MD2 or not MD2

This topic is 3699 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
Advertisement
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 = 0
0 * 3 + 1 = 1
0 * 3 + 2 = 2


after that, i == 3

3 * 3 = 9
3 * 3 + 1 = 10
3 * 3 + 2 = 11


where are indices 3 to 8 ???

hope that helps

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 !

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!