So after you got the format parameters for the first submesh you very likely would code some maxscript
to get the whole model.
If you don't own 3dsmax but know "C" here's another way to get the submeshes (bones/weights not handled).
It's a crash course in three parts:
1. part: How to analyse simple 3D formats with multiple submeshes
2. part: How to write a "collect multiMeshes" function in "C" for Make_H2O
3. part: How to create and import the obj files
We will use Make_H2O, hex2obj and blender (v2.49b or v2.69 and above).
requirements:
Basic understanding of "C" coding
Basic knowledge about 3D models
Part 1: "How to analyse simple 3D formats"
--------
As always you've to analyse the format and create a H2O file for the first submesh using hex2obj.
Some formats like MLX for example use tables which contain the counts for all submeshes.
But often formats use repeating structures to define a submesh header. For Sly Cooper TiT
you can get the required params from this picture: 1807_MDL.jpg:

Part 2: How to write a "collect multiMeshes" function in "C" for Make_H2O
--------
subject: "Sly Cooper: Thieves in Time" mdl model
abstract: After we've understood the mdl format we're going to create H2O files
for all submeshes contained in the sample mdl to be found here:
viewtopic.php?f=16&t=11229&p=93788&hili ... ves#p93788
(Thx to o0demonboy0o)
(If you want to skip the coding part just head to Part 3 now.)
Introduction: What is Make_H2O? - It's a Codeblocks 13.12 project written in "C"
to create H2O files for hex2obj.
preparations: To get the count of submeshes search for "MHDR" in the Mesh_1807.mdl file.
It's found 5 times.
vertex stride is 26 (gained by basic knowledge)
Though "SMSH" is probably the start of the submesh headers we will use "MHDR".
start of first submesh block: 0x30 ("MHDR")
offset to vertex count: 9
relative offset to face indices count: 2
That's all to know.
Now we simply have to use the above infos and implement the two formulaes shown in 1807_MDL.jpg
The following code is used to get the submeshes from Mesh_1807.mdl.
We are using a pointer to char (char *pFBuf) to scan the file data in a static buffer.
(You don't need to care for create_H2O(): It should be useable with all models hex2obj can handle.)
remark: the code of this function is updated in the zip
Code: Select all
void SM_of_SlyC_mdl_loop(HWND hwnd, char szPathname[], DWORD dwStart) // scanning the submeshes params for Mesh_1807
{
char * pFBuf ;
BYTE * pByte, cnt, i ;
int cnt1, nValue[16] ; //
WORD wFaceIndCnt, wVertsCnt ;
DWORD addrFI, addrUV, addrV, j, offs2, oldJ ; //
// ### line to be changed for other models than MLX! ###
//char lines[6][20]= {"","Vb1","76 40","","021000","0x0 255"} ; // [6][16] sollte reichen?
//char lines[6][20]= {"","Vb1","12 99","","120300",""} ; // Capt'n A.
char lines[6][20]= {"","Vb1","26 10","","120201",""} ; // Sly Cooper TiT
//0x124D0 1469 this is the ref H2O file for the first submesh of "DL020A_SD002J.MLX"
//Vb1 -> lines[1] which you'll get after having found out the format and saving the H2O in hex2obj
//76 40 -> [2]
//0x1BC20 701 this line's contents varies (same with first line)
//021000 -> [4]
//0x0 255- > [5]
pFBuf = (char *) lpFBuf ; j= 0 ;
pFBuf += dwStart ; j += dwStart ; // dwStart: start of first submesh at 0x30, from editbox
addrUV = 0 ; // zero for VB mode (hex2obj)
for (cnt=0;cnt<5;cnt++) { // 5: count of submeshes
pFBuf += 9 ; j += 9 ; // point to vertex count
pByte = (BYTE*) &wVertsCnt ; // get vertex count
for (i=0;i<2;i++) { //
*pByte = *pFBuf &255 ; pByte++; pFBuf++; j++ ;
}
pByte = (BYTE*) &wFaceIndCnt ; //
for (i=0;i<2;i++) { //
*pByte = *pFBuf &255 ; pByte++; pFBuf++; j++ ;
}
// with cnt==0, first submesh, we are at file offset 0x3D now. We have to skip 123 bytes to vertex start: 0xB8
pFBuf += 123 ; j += 123 ;
addrV = j ; // parameter (start of vertices) for create_H2O()
offs2 = wVertsCnt*26 ; // use vertex stride to calculate size of vertex data block
pFBuf += offs2 ; j += offs2 ; oldJ = j ; //
cnt1 = j/4 ; cnt1++ ;
if ((j%4)!=0) j = cnt1*4 ; // 4 byte alignment
pFBuf += (j-oldJ) ; // yeah, don't forget to update the pointer
//fprintf( stream, "debug: pos of MDIX=%x?\n", j) ;
pFBuf += 8 ; j += 8 ; // skip 8 bytes ("MIDX" and DWORD)
addrFI = j ;
offs2 = wFaceIndCnt*2 ; // size of face indices block with word indices
pFBuf += offs2 ; j += offs2 ; //
// we could do a simple byte alignment here, then skip another 8 bytes
// but I would like to introduce a search feature; we search for "MHDR"
// j is the current position in the model file
nValue[0]= 0x4D; nValue[1]= 0x48; nValue[2]= 0x44; nValue[3]= 0x52; // "MHDR": signature start of submesh block
offs2 = FindBytes(lpFBuf, j, dwFileSize-j, nValue, 4) ;
if (offs2!=0) {
pFBuf += offs2 ; j += offs2 ;
//fprintf( stream, " pos of MHDR=%x?\n", j) ;
create_H2O(szPathname, cnt, lines, addrFI, wFaceIndCnt, addrUV, 255, addrV, wVertsCnt, 2) ;
}
else {
if (cnt!=4) { // last submesh? -> no error
chMB("Damn', MHDR header signature not found\nhave to break here...") ; return ; }
else create_H2O(szPathname, cnt, lines, addrFI, wFaceIndCnt, addrUV, 255, addrV, wVertsCnt, 2) ;
}
}
if (strlen(szErrMess)>17) MessageBox(NULL, szErrMess, "error", MB_ICONINFORMATION);
}
Feedbacks on this crash course are welcome. Is there any vagueness?
But keep in mind: this is not a basic tutorial for beginners.
Make_H2O - Codeblocks 13.12 project