I'm very interested in getting my hands on SC3 models as well, and I could barely found anything about its model format, so I've been cracking at it for the last few days. Here's what I've documented so far... (massive infodump incoming)
At the start of each model file is some unknown data, then shader/material data which are float arrays, then more unknown data, then the start of the mesh data, which takes up the majority of the file.
01010001 = Start of object
There are 2 different types of mesh data.
Type 1 has multiple sets of data separated by data type as follows:
0380xx6C = Vertices (xx = Number of entries of the specified type)
0480xx68 = Normals
-or- = ? (xx is the same as the number of verts and normals)
0180xx64 = Texture coords
With the 0280xx60 type, all entries are 00000043 (just 4 bytes).
With the 0280xx6C type, entries are 16 bytes and always end with 00000043, but the preceding three sets of 4 bytes are
a. Always identical
b. Either 00000043 OR
where xxxxxx a value like 000080, CDCCCC, 9A9999, etc.
and yy is either 42 or 41.
The complete header is as follows:
01010001 0080016C xx800000 00403E30 12040000 yy000000 04010001 DataType
xx is some non-unique integer; my initial guess was that it's a shader/texture reference, but changing it either had no result or created strange rendering glitches, so I'm not sure.
yy is either 0F or 0E. Not sure if it's significant.
DataType is one of the various 0x80yy6z formats above.
Type 2 objects always have the data type 0080xx6C.
Type 2 is used for the majority of mesh data, and puts the normal, texture, bone index, and bone weight data together with each vertex in chunks like so (each line is 16 bytes):
VertX VertY VertZ Weight
NormX NormY NormZ BoneIndex? [ChunkEnd]
TexX TexY 1.0 Connection
00000043 00000043 00000043 00000043
BoneIndex is weird. At first glance it appears to be a one-byte int bone index, however the values are always multiples of four; knowing this I figured it might actually be a 6-bit integer just shifted left. However, changing this to non-multiples of 4 resulted in the vertices attaching to other, valid bones, so it must be getting translated somehow. Also, there aren't enough indices being used versus the number of bones in the model; for example, in Tira's model there are only 28 different indices used, which is maybe enough for one complete arm.
(ChunkEnd explained in a second)
The texture coordinates are always followed by a 0000803f, and then either a 00 or 01. This is simply connection data; polygons are connected in order for vertices (i-1,i,i+1) except when the connection data for i+1 is 01. (Vertices with 01 as connection data always come in pairs.)
Each chunk simply ends with 00000043 00000043 00000043 00000043.
It would be nice and simple if it stuck to this format, but when multiple bone weights are defined per vertex, suddenly the chunks have multiple vertex/normal line pairs, like so:
In this case, the vertices and normals are actually different
in each line pair. This is really bizarre, but looking at the weight data it's apparent that they always add up to one for each chunk. So, the different vertices and normals must somehow be relational to the bones they reference. From what I can tell from tweaking these positions, each vertex position is actually local to the bone referenced, using the bone's local coordinate space as well; this was obvious since modifying the x value of each coordinate resulted in different movements in world space. This is pretty much verified if you try to read the verts as being in world space, as you end up with a mass that's twisted and curled in on itself around the origin:
(That's Tira's torso.) But look, the UVs are perfect!
Finally, ChunkEnd simply notes the end of the vert/normal pairs in each chunk; it is 80 on the last pair, otherwise it is 00.
The complete header for this type of object is shorter than the first:
01010001 DataType xx800000 00403E30 12040000 yy000000
xx is presumably the same as in the header for the first object type (whatever it is).
yy, instead of 0F or 0E, is either 00 or 01.
Here's where stuff gets hazy. First of all, the bone data starts immediately after the model data without any apparent header, so I'm not sure if there's something that tells how many mesh pieces there are or what. As for the joint format… I have no idea what most of this stuff is, so here's an example of one joint's data chunk:
F90609B3 CA9100B3 1F03B3B1 0000803F
00000000 00000000 04ADC08A 0000803F
00000000 00000080 0000803E xxxx1400
0000803F 0000803F 00000000 ??aabbcc
Line 1: Don't know.
Line 2: Position in local coordinate space
Line 3: Don't know. xxxxxx is some non-unique integer, generally counts upward over length of bone data
Line 4: This is bone bb, whose parent is aa. Root bones have a parent of FF. It seems that if this bone is physics-enabled, ?? is filled with another integer. cc appears to be some sort of group value, as related joints have the same value here (eg. 02 = hands, 03 = face).
After the bone data there's some more unknown data (more increasing integers), and then what I assume is texture data.
OK, so what's really stumping me right now is how the bone indices given in the model data are related to the skeleton. If anyone has ideas, I'm all ears. I'm pretty sure this is the only (big) thing left to solve before I can take a stab at writing a proper translator for the meshes. (I already wrote a crappy one, which is how I obtained the mess above.) Also this is the first time I've ever done this sort of stuff, so there's a good chance I'm missing some really obvious things :)