Ski Files
This information is taken from resources for Perfect World. While Perfect World and other Angelica engine games are very similar there may be some differences. This information needs to be confirmed for Ether Saga.
General File Structure
Offset | Name | Data Size | Typ. Values | Meaning | Comments |
---|---|---|---|---|---|
0x0000 | moxbiksa[8] | CHAR | "MOXBIKSA" | file type identifier | Ski BMOX |
0x0008 | ski_type | DWORD | 8 or 9 | Type 9 has bone names listed, type 8 doesn't | |
0x000C | mesh_count[4] | DWORD | 1,0,0,0 or 2,0,0,0 | number of meshes | Defines a vertex_type as well. (index to mesh_count[]); so vertex_type goes (0,1,?,?) |
0x001C | tex_count | DWORD | 1 or 2 | number of textures | |
0x0020 | mat_count | DWORD | 1 or 2 | number of materials | |
0x0024 | num_bips | DWORD | 4 or more | number of “bones” | if ski_type=8, always no bips (but num_bips=4) |
0x0028 | (unknown_2) | DWORD | 0 | only value 0 spotted currently | |
0x002C | (type_mask) | DWORD | 41 or 43 or ... | num.Bones in *.bon | Seems to identify the type of Avatar; Human_Female=41, Demon_Female = 43, Human_Male = 35, ... |
0x0030 | zero_60 | DWORD | 0,0,0,... | just 15 zero DWORDs (or 60 zero BYTEs) |
IF ski_type == 9: {{{
Bone Names
0x006C Repeat [num_bips]: {{{
bone_len DWORD e.g. 12 string len (bone name)
bone_name[len] CHAR “Bip01 L Foot” the bone name string no trailing /0
}}} }}}
Textures
0x006C + (bones) Repeat [tex_count]: {{{
tex_len DWORD e.g. 16 number of bytes, not chinese letters
tex_name[len] CHAR "中式婚礼女鞋.dds” Texture file name (maybe unicode)
}}}
Materials
Repeat [mat_count]: {{{
MatHeader String-z “MATERIAL: “/0 Header for Mat.Block 10 bytes + trail-/0
mat_values[16] FLOAT 1, 1, 1, 1, 1, 1, 1, 1, (unknown) could be a matrix ...
0, 0, 0, 1, 0, 0, 0, 1 (unknown) ... or other float parameters
scale_param FLOAT 9.999 or 19,999 or 10.0 a scaling factor? (a “0” was spotted too)
is_clothing BYTE 0x00 or 0x01 if fashion or not? could be boolean
}}}
Meshes
Repeat [mesh_count]: <<<
obj_len DWORD e.g. 8 string len (mesh_obj)
mesh_obj[len] CHAR "萤火虫_0” name of the model no trailing /0
tex_index LONG_32 0 or 1 or ...? index to texture none if -1
mat_index LONG_32 0 index to materials
IF vertex_type == 1: {{{ vertex_type: (see “mesh_count[]” above)
extra_data[4] BYTE (unknown)
}}}
vertex_count DWORD 1235 number of vertices
faceverts_count DWORD 6084 number of faceverts faceverts_count = 3*face_count, because always triangles
Vertices
Repeat [vertex_count]: {{{
vertex_position[3] FLOAT (0.05, 1.0, -0.234) vertex coordinate -X, -Z, Y
IF vertex_type == 0: {{{
vertex_weight[3] FLOAT (0.7, 0.3, 0.0) bone influence ? seem 2nd value is always between 1st and 3rd
bone_index[4] BYTE (3, 12, 0, 27) list of 4 “bones” the order must be kept; don't sort!
}}}
vertex_normal[3] FLOAT vertex normal vector
vertex_UV_coord[2] FLOAT u/v-coordinate of vertex U, 1-V
}}}
Faces
Repeat [face_count]: {{{ face_count = faceverts_count / 3
vertex_index[3] USHORT_16 (123, 122, 144) 3 indices to vertices
}}}
(End Meshes) >>>
[EOF]