Page 1 of 8

Rage (idTech5) model format md6

Posted: Tue Oct 11, 2011 2:27 pm
by Skykila
Hello! Does anyone know how to open a model of Rage? Here are some examples of models:

Re: Rage (idTech5) model format md6

Posted: Wed Oct 12, 2011 6:17 am
by Qartar
Formats are proprietary and the game was just released a week ago, it may take some time. You provided four different formats, one is the animated mesh format .bmd6model, a static geometry format .bmodel, a collision model format .bcm, and I'm not sure what the .dmodel is without diving into the data. (Also the animation file .bmd6anim).

Re: Rage (idTech5) model format md6

Posted: Wed Oct 12, 2011 6:26 am
by Toji
Thanks for posting those. I've been meaning to extract some and take a look at it.

Looking at hands.bmd6model I can tell you immediately that I can see some very clear blocks of data that look like they represent bone names, index data and vertex data. Interestingly, the hand model looks like it has two blocks of vertex+index data each followed by a what looks like a mesh name and material path, so I'm guessing that each material gets it's own data block in the file.

I don't know if I'll have any time to do much with this, but the basics of the format look pretty clear. I'll see if I can post a more detailed analysis later.

(Going to bed now, but a quick item of interest: every single ASCII string that I've seen in these files is preceded by an int32 that gives the string length. Makes reading them easy!)

Re: Rage (idTech5) model format md6

Posted: Sun Oct 16, 2011 8:50 am
by howfie
format of vertices and index buffer are pretty clear. however, without more models it's impossible to tell where the data starts. thus, for now you gotta hard code offsets. i don't have $60 to spend on a game at the moment so maybe someone else can pick it up. here is code idea for the hand model. BE_ means big endian. Sample must be from PS3?

Image

Code: Select all

 ifstream ifile("hands.bmd6model", ios::binary);
 if(!ifile) return error("Could not open file.");

 // use offset #1 = 0x0151C for arms
 // use offset #2 = 0x3C15F for gauntlet

 // open file
 ofstream ofile("output2.ls");
 ofile << "main" << endl;
 ofile << "{" << endl;
 ofile << " editbegin();" << endl;
 ofile << " uvmap = VMap(\"texture\", \"" << "texture" << "\", 2);" << endl;

 ifile.seekg(0x151C);
 size_t n_points = BE_read_uint16(ifile); // number of points (2524)
 BE_read_uint16(ifile);
 size_t n_triangles = BE_read_uint16(ifile); // number of triangles (4602)
 BE_read_float(ifile);
 BE_read_float(ifile);
 BE_read_float(ifile);
 BE_read_float(ifile);
 BE_read_float(ifile);
 BE_read_float(ifile);
 cout << endl;
 
 for(size_t i = 0; i < n_points; i++)
    {
     float x = BE_read_float(ifile);
     float y = BE_read_float(ifile);
     float z = BE_read_float(ifile);
     float u = BE_read_float(ifile);
     float v = BE_read_float(ifile);
     BE_read_uint16(ifile);
     BE_read_uint16(ifile);
     BE_read_uint16(ifile);
     BE_read_uint16(ifile);
     BE_read_uint16(ifile);
     BE_read_uint16(ifile);
     cout << endl;

     ofile << " pointlist[" << i + 1 << "]" << " = " << "addpoint(" << x << "," << y << "," << z << ");" << endl;
     ofile << " uvmap.setValue(pointlist[" << (i + 1) << "]," << "@" << u << "," << v << "@);" << endl;
    }

 // read triangles
 boost::shared_array<unsigned short> data(new unsigned short[n_triangles*3]);
 ifile.read((char*)&data.get()[0], n_triangles*3*sizeof(unsigned short));
 for(size_t i = 0; i < 3*n_triangles; i++) reverse_byte_order(&data.get()[i]);

 size_t index = 0;
 for(size_t i = 0; i < n_triangles; i++) {
     unsigned short a = data.get()[index++] + 1;
     unsigned short b = data.get()[index++] + 1;
     unsigned short c = data.get()[index++] + 1;
     ofile << " addtriangle(pointlist[" << a << "], pointlist[" << c << "], pointlist[" << b << "]);" << endl;
    }

 ofile << " editend();" << endl;
 ofile << "}" << endl;

Re: Rage (idTech5) model format md6

Posted: Sun Oct 16, 2011 10:26 am
by Skykila
howfie wrote:format of vertices and index buffer are pretty clear. however, without more models it's impossible to tell where the data starts. thus, for now you gotta hard code offsets. i don't have $60 to spend on a game at the moment so maybe someone else can pick it up. here is code idea for the hand model. BE_ means big endian. Sample must be from PS3?
no, this is PC version

This is ALL models
http://www.multiupload.com/FQYQXSR2RM

Re: Rage (idTech5) model format md6

Posted: Sun Oct 16, 2011 7:46 pm
by Qartar
-types in capital letters are big endian
-all floating point types are big endian
-by "always" I mean "I haven't seen any models where this isn't the case" so beware
-offsets are from the end of the main file header

Code: Select all

.BMD6MODEL

File header:
0x00 - 0x04 : [ tag ] - file id
0x04 - 0x08 : [ -?- ] - unknown
0x08 - 0x20 : [FLOAT] - model bounds, [min3,max3]
0x20 - 0x24 : [ int ] - unknown, always '1'*
0x24 - 0x28 : [ -?- ] - unknown, always '0'
0x28 - 0x29 : [char ] - unknown, possibly version id, always '5'
0x29 - 0x2a : [SHORT] - unknown, always '0'
0x2a - 0x2d : [SHORT] - offset to joint names
*It's possible that the int at 0x20 is the beginning of an n-string with a length of 1, which would explain the odd length of the file header but n-strings don't generally contain a null-term. Could also be the number of sub-models in the file, but I've only seen values of 1. Caveat emptor.

Code: Select all

Model header:
0x2d - 0x2f : [SHORT] - offset to joint names again
0x2f - 0x31 : [SHORT] - number of joints*
0x31 - 0x33 : [SHORT] - unknown, always '0'
0x33 - 0x35 : [SHORT] - unknown, roughly points to the mesh data but is off by enough to be an unusable link
0x35 - 0x37 : [SHORT] - offset to default pose data
0x37 - 0x39 : [SHORT] - offset to joint hierarchy
0x39 - 0x5d : [SHORT] - more offsets, several joint channel structures, many repeats
*The number of joints is rounded up to the nearest multiple of 8 in all of the data structures.

Default Pose:
4 big endian floats for each joint as quaternions (xyzw). then:
3 big endian floats for each joint as scale data (possibly, almost all 1.0). then:
3 big endian floats for each joint as translation data (xyz).

Default pose is in joint local space.

Joint Hierarchy:
One big endian short for each joint indicating the index of its parent. -1 for root.
Following this is another set of short values for each joint, the meaning is unclear.

Joint Channels:
A series of bytes, either -1 or 0, for each joint indicating whether it belongs to a channel. Several channels. Until the header is better understood you should probably just skip to the joint names.

Joint Names:
A series of nstrings for each joint. That is a little endian int followed by that many characters, does not contain null termination.
Following that is a byte for each joint, again not sure what it represents.
Following that is a 3x4 joint matrix for each joint.
Following that is another set of bounds. (6 floats).

Following that is the surface data:

Code: Select all

Surfaces:
0x00 - 0x04 : [ INT ] - number of surfaces

ea. surface:
  [nstring] - surface name
  [nstring] - material name
  [char ] - flags, 1 appears to indicate deformable surface but does not change structure
  [ INT ] - number of vertices
  [ INT ] - number of triangles
  [bounds] - bounds for this surface (6 floats).

  ea. vertex:
    0x00 - 0x0c : [FLOAT] - vertex xyz
    0x0c - 0x14 : [FLOAT] - vertex tex coordinates
    0x14 - 0x20 : [ -?- ] - weight data, unknown format

  ea. triangle:
    0x00 - 0x06 : [SHORT] - vertex indices 

  following vertex and triangle data:
  0x00 - 0x04 : [ INT ] - unknown, always 0
  0x04 - 0x08 : [ INT ] - unknown, always numJoints
  0x08 - 0x09 : [char ] - unknown, always 0 or 1
  [4 bytes of data for each vertex] (only if previous field is 1!)
  0x09 - 0x0d : [ INT ] - unknown, always 0

(next surface)
At the very end of the file there is a footer with a list of materials, generally more materials than there are surfaces so I'm not sure what it represents. You should be able to parse any bmd6model file with what's here.

Image

You can probably see I'm having problems with just a few of the quaternions, incorrect sign or something.
Don't do that. You don't have the rights to distribute that content, even for 'academic' purposes.

Re: Rage (idTech5) model format md6

Posted: Mon Oct 17, 2011 1:54 pm
by howfie
Cool, thanks for finishing the parts I couldn't figure out. Tool time now!

As a test, try this (must have visual studio 2010 distributables and lightwave):
1.) Put exe file in models root directory.
2.) Run it and it will process all bmd6model files in all directories and subdirectories.
3.) You will find a bunch of new .ls files.
4.) Load ls file into lightwave.

Let me know if it works. I only had one file to work with so no textures. Only model and UVs are currently supported. Going to buy the game next week (since it has coop).

I will add bones next and process bmodels if program works for you guys.

Re: Rage (idTech5) model format md6

Posted: Mon Oct 17, 2011 4:39 pm
by howfie
works with bmodel now too.

Re: Rage (idTech5) model format md6

Posted: Tue Oct 18, 2011 11:17 am
by Skykila
howfie wrote:works with bmodel now too.
COOL!!! It's work!!!
But, don't work with level static meshes :(
sample
http://www.multiupload.com/GGZFEC4ZFJ

Re: Rage (idTech5) model format md6

Posted: Tue Oct 18, 2011 5:35 pm
by howfie
ok i'll check it out. still seems like they use tristrips, just the data is moved around a little bit. is there a file that mentions where all the models are placed in a level so we can export levels?

Re: Rage (idTech5) model format md6

Posted: Wed Oct 19, 2011 3:44 am
by howfie
There are 4 different bmodel types, some use tristrips and some use triangle lists. 2 down, 2 to go. After the material text, there is a 0x00000000 followed by three 4-byte values. The first two values are the number of points and number of indices. The third number appears to be the type of bmodel file. Types 0x0263 and 0x0277 use a strange vertex format that I cannot figure out just yet. They tend to contain a lot of 0x7FFFs in them.

EDIT: getting close I think. vertices appear to be normalized signed shorts. without having a sample texture I won't be able to tell if I am scaling the UV coordinates (which are also shorts) correctly though.

Re: Rage (idTech5) model format md6

Posted: Thu Oct 20, 2011 12:02 am
by howfie
done. now try.
can't fix uv normalization or automatically apply texture maps until i get the game and rip the textures.

Re: Rage (idTech5) model format md6

Posted: Thu Oct 20, 2011 2:24 am
by 652845095
hi.howfie,i got a problem,after i run the template.exe,the bmd6model file became a huge ls file,what's wrong with it?

Re: Rage (idTech5) model format md6

Posted: Thu Oct 20, 2011 2:25 am
by 652845095
one more screenshot

Re: Rage (idTech5) model format md6

Posted: Thu Oct 20, 2011 2:29 am
by howfie
Ok. I will look at it right now.