SKM (3D Skeletal Model) File Format Specs

Discussion in '3D Modeling' started by Agetian, Jul 29, 2006.

Remove all ads!
  1. Agetian

    Agetian Attorney General Administrator

    Joined:
    Aug 14, 2004
    Messages:
    2,526
    Likes Received:
    0
    SKM - SKeletal Model

    SKM is a file format used to define the in-game 3D meshes (models), such as critters, items, scenery objects, and so on. This is a Troika's proprietary format and it's not used directly in any known 3D suite (3ds Max, Maya, etc.). All 3D models for ToEE were originally made in Maya and then exported into SKM. Therefore, it may be (relatively) easy to write a Maya plugin that would export and import SKM files.

    The SKM file is subject to the following limitations: there can be a maximum of 1024 bones per SKM, a maximum of
    32767 vertices per SKM, and a maximum of 65535 triangles per SKM.

    1. The Header.
    The SKM header is as follows (I will use the C++ notation for the sake of simplicity of writing a plugin, if someone wil agree to make one in the future):

    int BoneCount; // the number of bones in the SKM
    int BoneOffset; // the offset to the bones' definition
    int MaterialCount; // the number of materials in the SKM
    int MaterialOffset; // the offset to the materials' definition
    int VertexCount; // the number of vertices in the SKM
    int VertexOffset; // the offset to the vertices' definition
    int TriangleCount; // the number of triangles in the SKM
    int TriangleOffset; // the offset to the triangles' definition
    unsigned UNUSED_1; // padding, unused
    unsigned UNUSED_2; // padding, unused

    2. The Bone Definitions.
    The bone definitions are located at the BoneOffset and can be represented by the following structure:

    unsigned short BoneFlags; // the bone flags, see below
    short BoneParent; // the parent of this bone
    char BoneName[48]; // the name of the bone, a maximum of 48 chars, all symbols after the first zero char (0x00) are ignored
    mat4x3 WorldInverse; // the 4x3 matrix for the WorldInverse. I'm not personally sure what this means, my friend who's a 3D modeller was telling me about this, so 3D modellers will probably have more idea about what this is. :)

    The bone flags can be as follows:
    0x00000000 - The Bone is non-static?
    0x00000001 - The Bone is Static
    Other flags may be in there, but they are unknown to me at the moment.

    3. The Material Definitions.
    The material definitions are located at the MaterialOffset and can be represented by the following structure:

    char MaterialName[128]; // the name of the material, a maximum of 128 chars, all symbols after the first zero char (0x00) are ignored

    4. The Vertex Definitions.
    The vertex definitions are located at the VertexOffset and can be represented by the following structure:

    vec3 Position; // the vertex position (vec3 = a combination of four floats; x,y,z, and an unused float value that may be coming from the fact that the structure is aligned to 128bits for SSE - thx to Leksey for finding out this extra padding that was missing!)
    vec3 Normal; // the vertex normal (position normal?)
    vec2 Texture; // the position of the texture (vec2 = a combination of two floats)
    short UNUSED; // padding, is ignored
    short WeightCount; // the count of weights for this vertex to follow (defines the number of associated bones and their weights to follow)
    short Bones[6]; // the list of bones associated with this vertex; always six entries.
    float Weights[6]; // the array of weights for the associated bones; always six entries.

    5. The Triangle Definitions.
    The triangle definitions are located at the TriangleOffset and can be represented by the following structure:

    unsigned short MaterialID; // the ID of a material for this vertex, per the Material Definitions.
    unsigned short Vertices[3]; // the three vertices comprising the triangle, per the Triangle Definitions.

    -------------------
    And that comprises the SKM file format. Hopefully these specifications will be of help to someone some day.

    I'd like to say thanks to Steve Moret for clarifications made on this file format, and to SVZ for explaining some 3D stuff to me that helped me understand the contents of the SKM files.

    NOTE: SKA (animation) specs are to follow shortly, as soon as I figure out some of its details. It appears to be harder than the SKM format, and needs some stuff to be sorted out before I can understand it completely and post the specs.

    - Agetian
     
    Last edited: Aug 8, 2006
  2. Leksey

    Leksey Member

    Joined:
    Mar 28, 2006
    Messages:
    51
    Likes Received:
    0
    I am really not sure that Vertex Defenition is really correct. I loaded triangle Definitions, material Definitions, Bone Definitions and they contain valid information. I founded a simple .SKM file necklace_red_gem.SKM .It contains only 4 vertexes and one bone.
    So due to vertexDefenition record for one contains only 40 bytes.But in HEX editor it is 80 bytes.I tried to find out what is wrong but useless:(. Maybe I made mistake or something....

    P.S. Waiting for SKA description :).
     
  3. Agetian

    Agetian Attorney General Administrator

    Joined:
    Aug 14, 2004
    Messages:
    2,526
    Likes Received:
    0
    @ Everyone: I fixed the specs. Thanks to Leksey for pointing out a big mistake!

    @ Leksey: Oops, my bad, I don't know where I was looking when I wrote those out.. ;) Seems like I copied them out of my older blueprint which was totally wrong. Check them out again, I fixed them. Note that the last two elements always contain 6 entries, and the Weight is actually an array of floats, not shorts. Try to match this up, lemme know if it doesn't match again and I'll dig it some further. ;)

    SKA: this file format definition is progressing steadily but slowly, because I have some tough time decyphering some of the data in there. But it'll be released soon. ;)

    P.S. What are you using the SKM specs for? Are you willing to write a plugin? Please say yes, we definitely need a good 3D plugin. :D ;)

    - Agetian
     
  4. Leksey

    Leksey Member

    Joined:
    Mar 28, 2006
    Messages:
    51
    Likes Received:
    0
    Agetian thanks.Will try to use new specs.

    I am not sure about plugin, because I can't found Maya or 3DS Max SDK for writing plugins.For now I just want to write converter to .Mesh format of Ogre Engine http://ogre3d.org/. For this format there is a lot of plugins for different 3D editors. So If I create this converter, there will be converters to different formats.

    But it will be more uefull,if I can find Maya or 3DS max SDK, so I can write plugin directly.
     
  5. Agetian

    Agetian Attorney General Administrator

    Joined:
    Aug 14, 2004
    Messages:
    2,526
    Likes Received:
    0
    Sweet, good job! It'll be nice to see a converter like that. Personally I'm not sure where to get the SDKs for Maya/3ds, so sorry - can't help with that. :( I'll let you know once I have some solid info on the .SKA format as well.

    - Agetian
     
  6. Leksey

    Leksey Member

    Joined:
    Mar 28, 2006
    Messages:
    51
    Likes Received:
    0
    BTW: It seems new specs also not full.

    In Vertex Defenitions there are two extra 8 bytes(I suppose 2 floats) between the normal and texture coordinates. So I for now just ignore them, and all works fine(Vertex defenitions are correct), but may be they have any meaning.....
     
  7. Agetian

    Agetian Attorney General Administrator

    Joined:
    Aug 14, 2004
    Messages:
    2,526
    Likes Received:
    0
    Hmm, maybe those are padding bytes necessary for the code to align structures to a certain boundary (and useless for the model itself). When I decyphered most of the ToEE file formats I noticed that there's a lot of room for padding because the structures that are written to disk are not packed, and therefore get padded according to the standards of the x86 architecture. If I'll be able to trace the data through a disassembler and if it proves to be meaningful, I'll update the specs. As far as I can see it by tracing the code, there's virtually nothing between the normal and texture coords. It may just be that the normal coords is a vec3, while the texture coords is a vec2, so it gets padded somewhere in-between. Also, note how a 'short' value follows a 'vec2' value. Short is 16bit, while a vec2 is a 32+32bit value. So, there's certainly room for another, rather large padding there.

    As usual, I'll be on the lookout for some info on what this may be. For now, it's rather safe to assume that they are unused and serve the x86 padding purpose.

    - Agetian
     
    Last edited: Aug 5, 2006
  8. Leksey

    Leksey Member

    Joined:
    Mar 28, 2006
    Messages:
    51
    Likes Received:
    0
    Some new info on format specs.
    I found out exact format of The Vertex Definitions(Defenition in C++):
    struct SKMVertex
    {
    float positionX,positionY,positionZ,float unused;
    float normalX,normalY,normalZ,float unused;
    float textureU,textureV;
    short UNUSED;
    short WeightCount;
    short Bones[6];
    float Weights[6];
    };

    *Note about texture coordinates:
    As I know different 3D editors use diifferent representation of texture coordinates. So when I tried to convert .SKM format to .Mesh I found out that second texture coordinate should be {C++ code}float textureV = 1 - textureVfromFile;{C++ code}.May be it will be helpfull for someone.
    Sometimes in 3D programming it is convinient to use 4-dimensional vectors instead of 3.
    That is why I think there is two unused floats(first for position Vertex,next for NormalVertex).
     
  9. Agetian

    Agetian Attorney General Administrator

    Joined:
    Aug 14, 2004
    Messages:
    2,526
    Likes Received:
    0
    Hey, good job! This is exactly how I suppose it is, thanks for the clarification! Updating the specs... ;)

    - Agetian
     
  10. XVicious

    XVicious Established Member

    Joined:
    Jun 21, 2013
    Messages:
    427
    Likes Received:
    5
    here is a pick of a render of only points from an SKM file i loaded givin the specs for it
    descirbed

    this is the fire snake skm
    http://www.co8.org/forum/picture.php?albumid=5&pictureid=14


    but I am having a problem with the triangle indexes given the data format

    when drawing the triangles, maybe there there is something im missing..



    http://www.co8.org/forum/picture.php?albumid=5&pictureid=18

    celtic sword

    bones: 2 materials: 1 points: 82 faces: 68

    @bit : 40 @bit : 240 @bit : 368 @bit : 6928

    count: 205
    Press any key to continue . . .

    index list

    0 : 0 : 1 : 2 : 0 : 0 : 2 : 3 : 0 : 4 : 5 : 6 : 0 : 7 : 8 : 9 : 0 : 4 : 10 : 5
    : 0 : 11 : 9 : 8 : 0 : 11 : 12 : 9 : 0 : 7 : 9 : 12 : 0 : 5 : 10 : 13 : 0 : 5 :
    13 : 6 : 0 : 14 : 15 : 16 : 0 : 16 : 15 : 17 : 0 : 18 : 19 : 20 : 0 : 18 : 21 :
    19 : 0 : 22 : 21 : 23 : 0 : 18 : 23 : 21 : 0 : 24 : 18 : 20 : 0 : 24 : 25 : 26 :
    0 : 26 : 18 : 24 : 0 : 27 : 28 : 29 : 0 : 30 : 29 : 28 : 0 : 28 : 31 : 30 : 0 :
    32 : 30 : 31 : 0 : 31 : 33 : 32 : 0 : 34 : 32 : 33 : 0 : 33 : 35 : 34 : 0 : 36
    : 37 : 38 : 0 : 37 : 39 : 40 : 0 : 40 : 38 : 37 : 0 : 39 : 41 : 42 : 0 : 42 : 40
    : 39 : 0 : 41 : 34 : 35 : 0 : 35 : 42 : 41 : 0 : 19 : 43 : 20 : 0 : 44 : 43 : 1
    9 : 0 : 44 : 45 : 46 : 0 : 46 : 43 : 44 : 0 : 43 : 47 : 20 : 0 : 48 : 47 : 49 :
    0 : 43 : 49 : 47 : 0 : 50 : 51 : 52 : 0 : 50 : 53 : 51 : 0 : 54 : 53 : 55 : 0 :
    50 : 55 : 53 : 0 : 56 : 50 : 52 : 0 : 56 : 57 : 58 : 0 : 58 : 50 : 56 : 0 : 59 :
    60 : 61 : 0 : 62 : 61 : 60 : 0 : 60 : 63 : 62 : 0 : 64 : 62 : 63 : 0 : 63 : 65
    : 64 : 0 : 66 : 64 : 65 : 0 : 65 : 67 : 66 : 0 : 68 : 69 : 70 : 0 : 69 : 71 : 72
    : 0 : 72 : 70 : 69 : 0 : 71 : 73 : 74 : 0 : 74 : 72 : 71 : 0 : 73 : 66 : 67 : 0
    : 67 : 74 : 73 : 0 : 51 : 75 : 52 : 0 : 76 : 75 : 51 : 0 : 76 : 77 : 78 : 0 : 7
    8 : 75 : 76 : 0 : 75 : 79 : 52 : 0 : 80 : 79 : 81 : 0 : 75 : 81 : 79 :
    count: 545
     
    Last edited: Jun 24, 2013
  11. XVicious

    XVicious Established Member

    Joined:
    Jun 21, 2013
    Messages:
    427
    Likes Received:
    5
    [​IMG]
    beholder picture ink

    http://www.co8.org/forum/picture.php?albumid=5&pictureid=17

    I was using this file format for points :

    //these are vec3 size float types
    //they contain x,y,z or only x,y for textures
    //float is 4 bytes * (3)


    dfile.read(reinterpret_cast<char *>(&tempxyz),4*3);
    GData.Vertdata_.enQueue(tempxyz);

    dfile.read(reinterpret_cast<char *>(&tempxyz),3*4);
    GData.Normdata_.enQueue(tempxyz);

    dfile.read(reinterpret_cast<char *>(&TempTexel),4*2);
    GData.TexelCoords_.enQueue(TempTexel);

    this data was read in sequance respective order from offset @points
    too offset @faces -1

    this example showed

    "eyeOfTheDeep.SKM"
    bones: 122 materials: 1 points: 1335 faces: 1514

    @bit : 40 @bit : 12240 @bit : 12368 @bit : 119168

    count: 1336
    Press any key to continue . . .



    just FYI, When I model and animate my own models, I would usually make simular reference points sunch as in the images, just for references per way points and collission detection also clipping.

    :dizzy:
     
    Last edited: Jun 26, 2013
  12. XVicious

    XVicious Established Member

    Joined:
    Jun 21, 2013
    Messages:
    427
    Likes Received:
    5
    I have had moderate successful progress in Loading and rendering SKM models from TOEE data

    [​IMG]

    i have found the way the data should be read
    bytes are ordered in the following sequance

    16 bytes (vector)(x,y,z,s)
    16 bytes(Normal)(x,y,z,s)
    8 bytes (texture)(x,y)

    as the data is read from the bit offset until the next offset
    my Data is queued every other time this is so I skip
    the reoccuring 00 data or unknown obect data

    every other 40 byte block is my render data referenced by the index offsets
    (triangles or faces)

    dfile.read(reinterpret_cast<char *>(&tempxyz),4*4);
    if(count % 2 == 1)
    GData.Vertdata_.enQueue(tempxyz);


    dfile.read(reinterpret_cast<char *>(&tempxyz),4*4);
    if(count % 2 == 1)
    GData.Normdata_.enQueue(tempxyz);


    dfile.read(reinterpret_cast<char *>(&TempTexel),4*2);
    if(count % 2 == 1)
    GData.TexelCoords_.enQueue(TempTexel);

    :yes:

    I will be working on a similar Loader that leksey has goin, exceptions are
    they wont be animated + side is that
    you will not need any OGRE tools or install dll or LIBS to load them
    you will only need a video card cap of OPen GL 1.0 and I am loading and
    rendering the SKM files directly, so no conversions are needed to view them.

    this will make it possible to load any TOEE SKM file in the game directly fast an ez.

    I will also add an export for Anim8or, and then attempt an import for TOEE
    only for adding new models, or editing current ones.

    if any Developers are interested in my Source code to render them in there own dev tools for TOEE, just PM me.

    i added the texture to this model, hydra.skm
    [​IMG]
     
    Last edited: Jun 22, 2013
Our Host!