Skip to main content
gamedev.net
🔒 Locked

.ms3d file loading

Started by OrangyTang Sep 25, 2002 at 1:31 PM 1 replies 1.7k views
Original Post
OrangyTang
OrangyTang
I''ve been tinking with Milkshape as a modeler and now i''d like to load the .ms3d format into my openGL app. Unfortunatly all the info on this format seems to refere to the 1.4.0 version, but the version i''m using is 1.6.4. Theres a nice well laid out spec that i''ve come across for 1.4, and after loading just the version number (should be 3 in 1.4) i''m getting 4, so maybe something has changed, but maybe not. Can anyone offer some more concrete advice on this? I''m about to start trawling though the sdk from the official site (ick, C code, i prefer Java..) but that seems mainly to do with creating plugins not the actual file format. Cheers.
Mete
Mete
The changes from version 3 to 4 are that some animation data is stored. Note, that the SDK version is 1.4.0, which doesn''t mean, that it only works for 1.4.0 and below. It also works for 1.6.4.

Make sure, that you use 1-byte aligned structs. #include <pshpack1.h> and #include <poppack.h>

Here is the file format spec:


//
// MilkShape 3D 1.6.4 File Format Specification
//
//
// This specifcation is written in C style.
//
//
// The data structures are defined in the order as they appear in the .ms3d file.
//
//
//
//
//



//
// max values
//
#define MAX_VERTICES 8192
#define MAX_TRIANGLES 16384
#define MAX_GROUPS 128
#define MAX_MATERIALS 128
#define MAX_JOINTS 128
#define MAX_KEYFRAMES 216 // increase when needed



//
// flags
//
#define SELECTED 1
#define HIDDEN 2
#define SELECTED2 4
#define DIRTY 8



//
// types
//
#ifndef byte
typedef unsigned char byte;
#endif // byte

#ifndef word
typedef unsigned short word;
#endif // word


// force one byte alignment
#include <pshpack1.h>

//
// First comes the header.
//
typdef struct
{
char id[10]; // always "MS3D000000"
int version; // 4
} ms3d_header_t;

//
// Then comes the number of vertices
//
word nNumVertices;

//
// Then comes nNumVertices * sizeof (ms3d_vertex_t)
//
typedef struct
{
byte flags; // SELECTED | SELECTED2 | HIDDEN
float vertex[3]; //
char boneId; // -1 = no bone
byte referenceCount;
} ms3d_vertex_t;

//
// number of triangles
//
word nNumTriangles;

//
// nNumTriangles * sizeof (ms3d_triangle_t)
//
typedef struct
{
word flags; // SELECTED | SELECTED2 | HIDDEN
word vertexIndices[3]; //
float vertexNormals[3][3]; //
float s[3]; //
float t[3]; //
byte smoothingGroup; // 1 - 32
byte groupIndex; //
} ms3d_triangle_t;

//
// number of groups
//
word nNumGroups;

//
// nNumGroups * sizeof (ms3d_group_t)
//
typedef struct
{
byte flags; // SELECTED | HIDDEN
char name[32]; //
word numtriangles; //
word triangleIndices[numtriangles]; // the groups group the triangles
char materialIndex; // -1 = no material
} ms3d_group_t;

//
// number of materials
//
word nNumMaterials;

//
// nNumMaterials * sizeof (ms3d_material_t)
//
typedef struct
{
char name[32]; //
float ambient[4]; //
float diffuse[4]; //
float specular[4]; //
float emissive[4]; //
float shininess; // 0.0f - 128.0f
float transparency; // 0.0f - 1.0f
char mode; // 0, 1, 2 is unused now
char texture[128]; // texture.bmp
char alphamap[128]; // alpha.bmp
} ms3d_material_t;

//
// save some keyframer data
//
float fAnimationFPS;
float fCurrentTime;
int iTotalFrames;

//
// number of joints
//
word nNumJoints;

//
// nNumJoints * sizeof (ms3d_joint_t)
//
//
typedef struct
{
float time; // time in seconds
float rotation[3]; // x, y, z angles
} ms3d_keyframe_rot_t;

typedef struct
{
float time; // time in seconds
float position[3]; // local position
} ms3d_keyframe_pos_t;

typedef struct
{
byte flags; // SELECTED | DIRTY
char name[32]; //
char parentName[32]; //
float rotation[3]; // local reference matrix
float position[3];

word numKeyFramesRot; //
word numKeyFramesTrans; //

ms3d_keyframe_rot_t keyFramesRot[numKeyFramesRot]; // local animation matrices
ms3d_keyframe_pos_t keyFramesTrans[numKeyFramesTrans]; // local animation matrices
} ms3d_joint_t;

#include <poppack.h>


//
// Mesh Transformation:
//
// 0. Build the transformation matrices from the rotation and position
// 1. Multiply the vertices by the inverse of local reference matrix (lmatrix0)
// 2. then translate the result by (lmatrix0 * keyFramesTrans)
// 3. then multiply the result by (lmatrix0 * keyFramesRot)
//
// For normals skip step 2.
//
//
//
// NOTE: this file format may change in future versions!
//
//
// - Mete Ciragan
//


- Mete
Xarragon
Xarragon
Hmmm... Personally, I like to make a sutom model format for whatever game/app Im making, unless it´s simple, like, say, a screensaver. Once you settled with a model format layout, you just write an exporter for your modelling program.

Granted, it´s a bit of extra work, but, as said, for larger projects it´s appropiate, since any change in a modelling-package specific format won´t wreck your loading code. A possible fix would be to save the finished model with the newest version, and then load it into an older version. This ONLY works if the older version somehow was prepared for the new format by an foreseeing app programmer. In short, you would use the older version as a kind of converter. There´s however, a big fat chance that the older modelling package version is incompatible as well, so...

The nice thing with exporters is that you don´t have to rewrite them unless the modelling package makes changes to the way it stores a loaded model in memory.

Martin "Xarragon" Persson
Xarragonxarragon@swipnet.se

Topic Locked

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

Sign in to reply to this topic.