Jump to content
  • Advertisement
Sign in to follow this  
GavRobbs

sscanf and MD5

This topic is 3665 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

I've finally gotten OBJ and MD2 to work, so now I'm going to try my hand at skeletal animation. I've written some code to simply read and output the data into a console window. No rendering yet, I just want to make sure the file is being read properly. The header reads fine, and the required number of meshes and joints too, but the data INSIDE the meshes and joints don't read properly. I've found my issue to be with sscanf I think. MD5Version 10 ------>(indent here)numverts 494 The difference between those 2 lines up there is that one is indented and one isn't. Thats why the version info is being properly read, but the vertex count isn't. I'm trying to read the vertex count using the following line: sscanf(tmpline,"numverts %d",&temp_mesh.numVertices); Can someone please suggest a modification to my formatting string so that it will read the number of vertices properly? Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Not sure about MD5. But when i download .md5 file i saw TABs before "numverts",
probably thats why not interpreting this?

maybe you can try like this ?:

char *line = readline();
char *s = strstr(line,"numverts");
if(s) {
if(sscaf(s,"numverts %d",&num_vert) == 1) {
printf("num vertices are now %d\n",num_vert);
};
};

Share this post


Link to post
Share on other sites
you can skip the leading spaces/tabs and go to the first character:

char *ptr = str;
while(*ptr && (*ptr == ' ' || *ptr == '\t')) ptr++;


something like that...

Share this post


Link to post
Share on other sites
@ferdekk: Thanks for the advice, but I can already accurately identify which line belongs to which element of the file. The problem is that numVerts, in fact, most subdata chunks, won't load properly.

$Tobio: I've tried. It ain't workin. lol. Any other suggestions people? Please and thank you.

Share this post


Link to post
Share on other sites
Here is some more code, so you can have an idea of whats going on.

[source lang = "cpp"]
struct MD5HeaderInfo
{
int version;
int numJoints;
int numMeshes;
};

struct MD5Vec2
{
float x,y;
};

struct MD5Vec3
{
float x,y,z;
};

struct MD5Vec4
{
float x,y,z,w;
};

struct MD5MeshVertex
{
int index;
MD5Vec2 texcoords;
int start_weight;
int count_weight;
};

struct MD5MeshTriangle
{
int triangle_index;
int vertex_indices[3];
};

struct MD5MeshVertexWeight
{
int index;
int joint;
float bias;
MD5Vec3 weight_position;
};

struct MD5JointInfo
{
char * name;
int parent;
MD5Vec3 joint_position;
MD5Vec4 joint_orientation;
};

struct MD5Mesh
{
int numVertices;
int numTriangles;
int numWeights;
std::vector<MD5MeshVertex> mesh_vertices;
std::vector<MD5MeshTriangle> mesh_triangles;
std::vector<MD5MeshVertexWeight> mesh_vertex_weights;
};

struct MD5Model
{
MD5HeaderInfo header;
std::vector<MD5Mesh> meshes;
std::vector<MD5JointInfo> joints;
};

MD5Mesh ProcessMesh(FILE * mfile)
{
MD5Mesh temp_mesh;
MD5MeshVertex temp_vert;
MD5MeshTriangle temp_tri;
MD5MeshVertexWeight temp_weight;
char tmpline[256];
while(fgets(tmpline,256,mfile) != NULL)
{
if(feof(mfile))
{
break;
};
if(strncmp(tmpline,"}",1) == 0)
{
break;
}
else if(strncmp(tmpline,"numverts",8) == 0)
{
sscanf(tmpline,"numverts %d",&temp_mesh.numVertices);
}
else if(strncmp(tmpline,"numtris",7) == 0)
{
sscanf(tmpline,"numtris %d",&temp_mesh.numTriangles);
}
else if(strncmp(tmpline,"numweights",10) == 0)
{
sscanf(tmpline,"numweights %d",&temp_mesh.numWeights);
}
else if(strncmp(tmpline,"vert",4) == 0)
{
sscanf(tmpline,"vert %d ( %f %f ) %d %d",&temp_vert.index,&temp_vert.texcoords.x,&temp_vert.texcoords.y,&temp_vert.start_weight,&temp_vert.count_weight);
temp_mesh.mesh_vertices.push_back(temp_vert);
}
else if(strncmp(tmpline,"tri",3) == 0)
{
sscanf(tmpline,"tri %d %d %d %d",&temp_tri.triangle_index,temp_tri.vertex_indices[0],temp_tri.vertex_indices[1],temp_tri.vertex_indices[2]);
temp_mesh.mesh_triangles.push_back(temp_tri);
}
else if(strncmp(tmpline,"weight",6) == 0)
{
sscanf(tmpline,"weight %d %d %f ( %f %f %f )",&temp_weight.index,&temp_weight.joint,&temp_weight.bias,&temp_weight.weight_position.x,&temp_weight.weight_position.y,&temp_weight.weight_position.z);
temp_mesh.mesh_vertex_weights.push_back(temp_weight);
};
memset(tmpline,0,256);
};
return temp_mesh;
};

std::vector<MD5JointInfo> ProcessJoints(FILE * file)
{
char tmpline[256];
MD5JointInfo temp;
MD5Vec3 orient;
std::vector<MD5JointInfo> mdji;
while(fgets(tmpline,256,file) != NULL)
{
if(feof(file))
{
break;
};
if(strncmp("}",tmpline,1) == 0)
{
break;
}
else
{
sscanf(tmpline,"%s %d ( %f %f %f ) ( %f %f %f)",&temp.name,&temp.parent,&temp.joint_position.x,&temp.joint_position.y,&temp.joint_position.z,&orient.x,&orient.y,&orient.z);
temp.joint_orientation = calculate_quat_w(orient);
mdji.push_back(temp);
};
};
return mdji;
};


Share this post


Link to post
Share on other sites
Here is some source code of a modified md5 loader.
I found a great one on the net, but it didn't make use of classes, so I rewrote it:


if (!ifs.is_open())
throw_exception( "Input stream not opened!", LIB_EXCEPTION );

std::string token, buffer, shader;
int _numVerts, _numTris, _numWeights;

m_fBumpheight = 1.0f;

do
{
// Read first token line from file
ifs >> token;

if( token == "shader" )
{
ifs >> shader;

// Remove quote marks from the shader string
m_strTexture = shader.substr(shader.find_first_of('\"') + 1, shader.find_last_of('\"') - 1);

// Get mesh name from shader string
m_strMesh = m_strTexture.c_str() + m_strTexture.find_last_of ('/') + 1;
}
else if( token == "bumpheight" )
{
ifs >> m_fBumpheight;
}
else if( token == "numverts" )
{
ifs >> _numVerts;
m_Vertices.reserve( _numVerts );
}
else if( token == "numtris" )
{
ifs >> _numTris;
m_Triangles.reserve( _numTris );
}
else if( token == "numweights" )
{
ifs >> _numWeights;
m_Weights.reserve( _numWeights );
}
else if( token == "vert" )
{
static int index = 0;
CMD5Vertex vert;

if( numVerts() >= _numVerts )
throw_exception( "model is damaged", LIB_ERROR );

// Read vertex data
ifs >> token; // index
ifs >> token; // "("
ifs >> vert.tu;
ifs >> vert.tv;
ifs >> token; // ")"
ifs >> vert.WeightIndex;
ifs >> vert.Weightcount;

vert.Index = index;
vert.tv = 1 - vert.tv;

m_Vertices.push_back( vert );
index++;
}

// Eat up rest of the line
std::getline( ifs, buffer );
}
while((token != "}") && !ifs.eof ());




If you use c++ to open the md5 mesh, you don't have to worry about the possbile tabs. std::ifstream just doesn't read them and continues at the next character.
A big plus of using the c++ filestream classes is, that reading and writing strings becomes quite easy.

If you want the source code of my loader, write me a pm, I'm happy to share it :)

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!