Hello, I'm a french student, I decided to explain you the structure of MilkShape 3d file's format (ms3d), version 4 of course.
First, I'm going to describe variables which will be used along explanation, then I will explain how the file is structured.

Bytes
Visual basic
C ++
1 byte
Byte
Byte
2 bytes
Integer
Word
4 bytes
Long
DWord
4 bytes floating
Single
Float
8 bytes floating
Double
Double
Multiple text size
String
Char

A vector is in fact a compound of three compononents : x = 4 bytes floating, y = 4 bytes floating and z = 4 bytes floating.

MilkShape 3d File structure :

Now, I shall say you how a ms3d is writen, or how you can read it.

The firts bytes in a ms3d file describes the header

10 bytes are reserved for identification, the value is = MS3D000000
in vb it's Dim Id as String * 10 and in c++ char Id[10]

2 bytes are used for the file's version, here the value is = 8

Then you can get the vertices :

2 bytes are reserved for an uknown use (in the most case the value is 0)
First 2 bytes decribe the vertices' numbers
Then, for each vertices :
a flag As Byte
x As Single
y As Single
z As Single
Bone As Byte
reference As Byte

After vertices you can retrieve the triangles :

Firsts 2 bytes are use for the number of vertices
Then, for each vertices :
flag As Integer
IndiceVertex0 As Integer
IndiceVertex1 As Integer
IndiceVertex2 As Integer
a little sophisticated, you can put in order the next bytes in a table :

NormalVertex_0_X NormalVertex_0_Y NormalVertex_0_Z
NormalVertex_1_X NormalVertex_1_Y NormalVertex_1_Z
NormalVertex_2_X NormalVertex_2_Y NormalVertex_2_Z

In fact it's 3 vectors for the normal of the triangle, with Single property
s1 As Single
s2 As Single
t1 As Single
t2 As Single
SmoothingGroup As Byte
IndexGroup As Byte

You have got the triangles, now groups :

Like other parts, the number of groups is reffered on 2 bytes
Then for each vertex :
Flag As Integer
Name as string (32 bytes max)
NumberTriangles As Integer
TrianglesIndices as Integer, it's also a large table he have the dimension of NumberTriangles - 1
MaterialIndex as byte, if is equal to -1 then no material

Now material "chunk" :

Number of Material As Integer
Only if the number is > 1 then for each vertices :
Name As String (32 bytes max)
AmbientX As Single
AmbientY As Single
AmbientZ As Single
DiffusX As Single
DiffusY As Single
DiffusZ As Single
SpeculaireX As Single
SpeculaireY As Single
SpeculaireZ As Single
EmetteurX As Single
EmetteurY As Single
EmetteurZ As Single
Glow As Single
Transparency As Single
Mode As String
Texture As String (128 bytes max)
MapAlpha As String (128 bytes max)

You have got the material, you have few information about animation :

Frame per Seconde As Single
Current Time for the animation (the frame selected ??) As Single
Frame's Number As Integer

You ARE almost finished, remains the bones :

Number of Bone in the scene As Integer
Flag As Byte
Name As String (32 byte max)
Parent's Name As String (32 byte max)
RotationX As Single
RotationY As Single
RotationZ As Single
PositionX As Single
PositionY As Single
PositionZ As Single
Number of key frame for rotation As Integer
Number of key frame for translation As Integer

A last accuracy, for all flags, in fact it's an information about selected or hidden.

I hope you have succeeded in your project and that my english is not too bad or weird ... If you have any question you can mail me at :

ciberrique@cegetel.net