Skip to main content
GameDev.net gamedev.net
🔒 Locked

upper md3 model inverted

Started by Sfpiano Jan 10, 2004 at 3:01 PM 13 replies 750+ views
Original Post
Sfpiano
Sfpiano
When I load my md3 model, the lower part is fine, but the upper part is sideways. I tried switching the y and z axis, but that just switched everything around so that the upper was kind of coorrect but the lower was sideways. I''m using the lara croft model currently.
//------------------------------------------------------------------------------------------------------The great logician Bertrand Russell once claimed that he could prove anything if given that 1+1=1. So one day, some fool asked him, "Ok. Prove that you're the Pope." He thought for a while and proclaimed, "I am one. The Pope is one. Therefore, the Pope and I are one."
Puzzler183
Puzzler183
Poeple need to see code generally before they can diagnose problems, so please post your model loader (note, I did not intend to be condescending).
Sfpiano
Sfpiano
I really don't know which part to post, so here's the reading in of the data from the .md3 file.

bool MD3Model::LoadModel(char *filename)
{
FILE *fp = NULL;
int i;

// Check if file exists

if ((fp = fopen(filename, "rb"))==NULL)
{
ReportError("Unable to find MD3 Model file");
return false;
}
// Copy the filename

md3name = new char[strlen(filename)+1];
strcpy(md3name, filename);

// Read in the header

fread(&Header, 1, sizeof(MD3Header), fp);

// Check this is a valid MD3 file

static char ver[5];
sprintf(ver, "%c%c%c%c", Header.id[0], Header.id[1], Header.id[2], Header.id[3]);
if (strcmp(ver, "IDP3") || Header.version != MD3VERSION)
{
fclose(fp);
ReportError("Unable to load MD3 Model: [Incorrect File Type or Version]");
return false;
}

// Read in the bone frames

BoneFrames = new BoneFrame[Header.numBoneFrames];
fread(BoneFrames, sizeof(BoneFrame), Header.numBoneFrames, fp);

// Read in the tags

Tags = new Tag[Header.numBoneFrames * Header.numTags];
fread(Tags, sizeof(Tag), Header.numBoneFrames*Header.numTags, fp);

// Init Links

Links = new MD3Model*[Header.numTags];

for (i=0; i < Header.numTags; i++)
Links[i] = NULL;

// Read in the meshes

Meshes = new MD3Mesh[Header.numMeshes];

long mesh_offset = ftell(fp);

// for each mesh

for (i=0; i < Header.numMeshes; i++)
{
MD3Mesh *m = &Meshes[i];

// Load the mesh's header

fseek(fp, mesh_offset, SEEK_SET);
fread(&m->MeshH, sizeof(MeshHeader), 1, fp);

// allocate space for and load in the skins

m->Skins = new Skin[m->MeshH.numSkins];
fread(m->Skins, sizeof(Skin), m->MeshH.numSkins, fp);

// allocate space for and load in the faces

fseek(fp, mesh_offset+m->MeshH.tri_start, SEEK_SET);
m->Triangles = new Triangle[m->MeshH.numTriangles];
fread(m->Triangles, sizeof(Triangle), m->MeshH.numTriangles, fp);

// allocate space and load in the texture coordinates

fseek(fp, mesh_offset+m->MeshH.texvec_start, SEEK_SET);
m->TexCoords = new TexCoord[m->MeshH.numVertices];
fread(m->TexCoords, sizeof(TexCoord), m->MeshH.numVertices, fp);

// allocate space and load in the vertices

fseek(fp, mesh_offset+m->MeshH.vertex_start, SEEK_SET);
m->Vertices = new Vertice[m->MeshH.numVertices * m->MeshH.numMeshFrames];
fread(m->Vertices, sizeof(Vertice), m->MeshH.numMeshFrames*m->MeshH.numVertices, fp);

mesh_offset += m->MeshH.meshsize;

}

// we're done, close the file

fclose(fp);

Header.numBoneFrames -= 1;

return true;
}


[edited by - Sfpiano on January 11, 2004 12:00:37 PM]
//------------------------------------------------------------------------------------------------------The great logician Bertrand Russell once claimed that he could prove anything if given that 1+1=1. So one day, some fool asked him, "Ok. Prove that you're the Pope." He thought for a while and proclaimed, "I am one. The Pope is one. Therefore, the Pope and I are one."
Extrarius
Extrarius
You should enclose source in [source] [/source] tags to avoid problems with <, >, [ and ]
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Sfpiano
Sfpiano
Should I have posted a different part of the code?
//------------------------------------------------------------------------------------------------------The great logician Bertrand Russell once claimed that he could prove anything if given that 1+1=1. So one day, some fool asked him, "Ok. Prove that you're the Pope." He thought for a while and proclaimed, "I am one. The Pope is one. Therefore, the Pope and I are one."
Sfpiano
Sfpiano

void MD3Model::RenderFrame(int frame)
{
int au, av;

device->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1);
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);

MD3Vertex verts[3], v1, v2;
for (int i=0; i < Header.numMeshes; i++)
{
MD3Mesh *m = &Meshes[i];

int curr_offset_vertex = frame * m->MeshH.numVertices;

for (int j=0; j < m->MeshH.numTriangles; j++)
{
if (m->settexture) device->SetTexture(0, m->texture);

for (int k=0; k < 3; k++)
{
int vertidx = m->Triangles[j].vertex[k];

verts[k].pos.x = m->Vertices[curr_offset_vertex + vertidx].Vec[0] * 0.015625f;
verts[k].pos.y = m->Vertices[curr_offset_vertex + vertidx].Vec[1] * 0.015625f;
verts[k].pos.z = m->Vertices[curr_offset_vertex + vertidx].Vec[2] * 0.015625f;

au = m->Vertices[curr_offset_vertex + vertidx].Normal[0];
av = m->Vertices[curr_offset_vertex + vertidx].Normal[1];

verts[k].normal.x = anorms[au][av][0];
verts[k].normal.y = anorms[au][av][1];
verts[k].normal.z = anorms[au][av][2];

verts[k].uv.x = m->TexCoords[vertidx].texvec[0];
verts[k].uv.y = m->TexCoords[vertidx].texvec[1];
}
device->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1, &verts, sizeof(MD3Vertex));
}
}

device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
}


I''m aware not all of this code is as optimised as it should be, especially the DrawPrimUp, but I''m trying to get it working as is first. Thanks.
//------------------------------------------------------------------------------------------------------The great logician Bertrand Russell once claimed that he could prove anything if given that 1+1=1. So one day, some fool asked him, "Ok. Prove that you're the Pope." He thought for a while and proclaimed, "I am one. The Pope is one. Therefore, the Pope and I are one."
Omaha
Omaha
Did you remember to switch the axes in both your vertices AND the matrix formed by the TAG?
Sfpiano
Sfpiano
I''ve read about that, but I thought it odd that the lower part was upright while the top was sideways, instead of the entire model being sideways. Is that normal?
//------------------------------------------------------------------------------------------------------The great logician Bertrand Russell once claimed that he could prove anything if given that 1+1=1. So one day, some fool asked him, "Ok. Prove that you're the Pope." He thought for a while and proclaimed, "I am one. The Pope is one. Therefore, the Pope and I are one."
paradoxnj
paradoxnj
Check this out. It's for OpenGL, but it should still work with DrawPrimitiveUP().

[edited by - paradoxnj on January 15, 2004 3:30:00 AM]
Sfpiano
Sfpiano
Apparently now the problem is that the upper part isn't lining up with the lower part, which is why the lower part is upright, while the upper part is sideways through it.


void RenderSkeleton(MD3Model *mod, LPDIRECT3DDEVICE9 &device){
int i;
float pol;
MD3Model *link;

D3DXVECTOR3 position, nextposition;
D3DXMATRIX m, matrix, nextmatrix;
D3DXQUATERNION quat1, quat2;
static D3DXMATRIXA16 oldmat;

D3DXMatrixIdentity(&oldmat);

D3DMATRIX world;
device->GetTransform(D3DTS_WORLD, &world);

// Render this model

mod->Render();

// Render this model's links

for(i=0; i < mod->Header.numTags; i++){
link = mod->Links[i];

if(link){
pol = mod->pol; // interpolation factor


// Get this frame's position

position.x = mod->Tags[mod->Frame * mod->Header.numTags + i].position[0];
position.y = mod->Tags[mod->Frame * mod->Header.numTags + i].position[1];
position.z = mod->Tags[mod->Frame * mod->Header.numTags + i].position[2];

// Get this frame's rotation matrix (in row major form)

for(int row=0; row < 4; row++)
for(int col=0; col < 4; col++)
matrix.m[row][col] = mod->Tags[mod->Frame * mod->Header.numTags + i].rotation[col][row];

// Get the next frame's position

nextposition.x = mod->Tags[mod->NextFrame * mod->Header.numTags + i].position[0];
nextposition.y = mod->Tags[mod->NextFrame * mod->Header.numTags + i].position[1];
nextposition.z = mod->Tags[mod->NextFrame * mod->Header.numTags + i].position[2];

// Get the next frame's rotation matrix (in row major form)

for(row=0; row < 4; row++)
for(int col=0; col < 4; col++)
nextmatrix(row,col) = mod->Tags[mod->NextFrame * mod->Header.numTags + i].rotation[col][row];

// Convert the matrices to quaternions

D3DXQuaternionRotationMatrix(&quat1, &matrix);
D3DXQuaternionRotationMatrix(&quat2, &nextmatrix);

// Do a slerp between the quaternions

D3DXQUATERNION res;
D3DXQuaternionSlerp(&res, &quat1, &quat2, pol);

// Convert the interpolated quaternion into a matrix

D3DXMATRIXA16 fm;
D3DXMatrixRotationQuaternion(&fm, &res);
m = fm;

// Interpolate the frame positions and store it in the matrix

m._31 = SP_LERP(pol, position.x, nextposition.x);
m._32 = SP_LERP(pol, position.y, nextposition.y);
m._33 = SP_LERP(pol, position.z, nextposition.z);
m._34 = 1.0f;

m *= oldmat; // multiply the matrix by the previous transformation matrix


// Set the world matrix

D3DXMATRIXA16 d3dmat;
D3DXMatrixIdentity(&d3dmat);
device->SetTransform(D3DTS_WORLD, &d3dmat);
oldmat = m; // store this link's matrix


// Render the other links

RenderSkeleton(link, device);

// clear the stored matrix

D3DXMatrixIdentity(&oldmat);
}
}


If I don't set the world matrix at the end, everything lines up except that the upper part is partway inside the lower part.

[edited by - Sfpiano on January 15, 2004 11:19:11 AM]

[edited by - Sfpiano on January 15, 2004 9:06:02 PM]
//------------------------------------------------------------------------------------------------------The great logician Bertrand Russell once claimed that he could prove anything if given that 1+1=1. So one day, some fool asked him, "Ok. Prove that you're the Pope." He thought for a while and proclaimed, "I am one. The Pope is one. Therefore, the Pope and I are one."
paradoxnj
paradoxnj

// Get this frame's position

position.x = mod->Tags[mod->Frame * mod->Header.numTags + i].position[0];
position.y = mod->Tags[mod->Frame * mod->Header.numTags + i].position[2];
position.z = mod->Tags[mod->Frame * mod->Header.numTags + i].position[1];

// Get this frame's rotation matrix (in row major form)

for(int row=0; row < 4; row++)
for(int col=0; col < 4; col++)
matrix.m[row][col] = mod->Tags[mod->Frame * mod->Header.numTags + i].rotation[col][row];

// Get the next frame's position

nextposition.x = mod->Tags[mod->NextFrame * mod->Header.numTags + i].position[0];
nextposition.y = mod->Tags[mod->NextFrame * mod->Header.numTags + i].position[2];
nextposition.z = mod->Tags[mod->NextFrame * mod->Header.numTags + i].position[1];


Try that.


[edited by - paradoxnj on January 16, 2004 10:08:50 AM]
Sfpiano
Sfpiano
Nope the two parts are still mixed in each other. Actually that didn''t appear to do anything to alter teh model, which I thought was odd.
//------------------------------------------------------------------------------------------------------The great logician Bertrand Russell once claimed that he could prove anything if given that 1+1=1. So one day, some fool asked him, "Ok. Prove that you're the Pope." He thought for a while and proclaimed, "I am one. The Pope is one. Therefore, the Pope and I are one."
paradoxnj
paradoxnj
Apologies...after I read that code it seems that was to render the skeleton. Here is the correct code:


for (int k=0; k < 3; k++)
{
int vertidx = m->Triangles[j].vertex[k];
verts[k].pos.x = m->Vertices[curr_offset_vertex + vertidx].Vec[0];
verts[k].pos.y = m->Vertices[curr_offset_vertex + vertidx].Vec[2];
verts[k].pos.z = m->Vertices[curr_offset_vertex + vertidx].Vec[1];

au = m->Vertices[curr_offset_vertex + vertidx].Normal[1];
av = m->Vertices[curr_offset_vertex + vertidx].Normal[0];
verts[k].normal.x = anorms[au][av][0];
verts[k].normal.y = anorms[au][av][2];
verts[k].normal.z = anorms[au][av][1];
verts[k].uv.x = m->TexCoords[vertidx].texvec[1];
verts[k].uv.y = m->TexCoords[vertidx].texvec[0];
}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.