Engineer roocker666 Posted April 30 Engineer Share Posted April 30 (edited) Hi guys, I was trying to extract models from MKSM PS2, it seems like models are compressed in one of these files: GAMEDATA.WAD, GAMEDATA.WAE, GAMEDATA.WAF, GAMEDATA.WAG, GAMEDATA.WAH, GAMEDATA.WAI, GAMEDATA.WAJ(Some are actually .AFS but these have sounds or music) but after extracting the content of GAMEDATA.WAD, I ended with 2K files without names, that sucks, lol. So I just dumped PCSX2 memory and it was easier to find models. OK, I analyzed the models and I found two different mesh formats, the only difference is in vertex buffer. One is size 32 and the other is size 48, both have a header that looks the same, you can see a tag for meshes there" 04 04 00 01" So with this info is there a way to extract models? It looks like vertex buffer 32 does not have Normals, weird.. Here are two model samples: Kitana and Scorpion And here a few images of vbuf32 and vbuf48 meshes(from Scorpion model): BTW, faces are autogenerated so there is no faces data. Edited April 30 by roocker666 1 Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 1 Engineer Share Posted May 1 (edited) 22 hours ago, roocker666 said: So with this info is there a way to extract models? Hi, isn't it almost always the same with those PS2 models using 4 bytes signature? Autocreating faces is always a little bit tricky with PS2 models. But I didn't remember to have so many weird superfluous faces. Edited May 1 by shak-otay Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 1 Author Engineer Share Posted May 1 (edited) 7 hours ago, shak-otay said: Hi, isn't it almost always the same with those PS2 models using 4 bytes signature? A lot of PS2 models use a 4 bytes signature in submeshes. Just the header changes depending on the game. Mmmh, maybe" Mesh format1" uses triangles and "Mesh format2" uses tristrip. Just guessing.. but that would be very strange, This is weird Edited May 1 by roocker666 Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 1 Engineer Share Posted May 1 (edited) I used tristrips in my previous post (standard triangles don't do). Maybe it's required to remove double vertices before? (I always forget about this.) Edited May 1 by shak-otay Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 1 Author Engineer Share Posted May 1 I did not notice those double vertices, lol. Maybe that is the problem but I really don't know.. I was checking XBOX version but models are in those WAD files too but quickbms script only works on PS2 WAD, so we can't use XBOX files, that sucks. Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 2 Engineer Share Posted May 2 (edited) Seems my vStride detection is faulty. How to decide from data what is 32 and what is 48? edit: improved detection, still extra faces... Edited May 2 by shak-otay Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 2 Author Engineer Share Posted May 2 32 minutes ago, shak-otay said: Seems my vStride detection is faulty. How to decide from data what is 32 and what is 48? Exaclty, that is the big question. I don't see a clue on how to identify meshes with 32 and 48. Your image looks like something but maybe is still reading wrong vertex size in some meshes. I tried to check each mesh just by a quick look, I cut all meshes and made two files, one has all meshes with vertex 32 and the other file has all meshes with vertex 48. But then I noticed that there are two models for each character, Maybe one is used for fatalities. So here is Kitana for fatalities(original model, vertex 32 gorup and vertex 48 group): model3_kitana_fatality.rar Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 2 Engineer Share Posted May 2 Hi, I didn't check your rar since I got a result which seems similar to those I got from former PS2 tests. I always had to delete superfluous faces: Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 2 Engineer Share Posted May 2 (edited) Here's the logged obj file for reference (there's 14 error messages inside which I think can be ignored;-) (And the faces list ends at 4000 instead of 4205, sorry.) Makeobj_log-kitana (3).zip Edited May 2 by shak-otay Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 2 Author Engineer Share Posted May 2 (edited) 10 minutes ago, shak-otay said: Here's the logged obj file for reference (there's 14 error messages inside which I think can be ignored;-) NIce, that looks A LOT better! thanks. So how do you know what mesh is 32 and what mesh is 48? Edited May 2 by roocker666 Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 2 Engineer Share Posted May 2 Well, the code for deciding whether vstride is 32 or 48 is ugly. Basically it checks for 0404 at a certain offset: pFBuf += 16; j += 16; // start of v-block pTmp= pFBuf ; pTmp += vCntB*32 +4; if ((*pTmp==0)&&(*(pTmp+1)==0)) pTmp += 24 ; cnt2=0; while ((*pTmp!=4)&&(cnt2<32)) {pTmp++; cnt2++;} if (*pTmp!=4) { pTmp= pFBuf ; pTmp += vCntB*48 +4; if ((*pTmp==0)&&(*(pTmp+1)==0)) pTmp += 24 ; cnt2=0; while ((*pTmp!=4)&&(cnt2<48)) {pTmp++; cnt2++;} if (*pTmp!=4) fprintf( stream, "# error!\n"); if (*(pTmp+1)==4) vStride= 48; else fprintf( stream, "# error missing 2nd 4!\n"); } else { if (*(pTmp+1)==4) vStride= 32 ; else fprintf( stream, "# error missing 2nd 4!\n"); } Scorpion looks like so: 1 Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 2 Author Engineer Share Posted May 2 (edited) 1 hour ago, shak-otay said: Well, the code for deciding whether vstride is 32 or 48 is ugly. Basically it checks for 0404 at a certain offset... Ok, ok. I think I found a clue, when a mesh ends(at the end of all its vertex buffers) next bytes are zeros and number 17. So if mesh has vbuf32 those bytes are 00 00 00 17(4 bytes). If mesh has vbuf48 those bytes are 00 00 00 00 00 00 00 17(8 bytes). That is the only difference that I found, don't know if that helps 🤔 Edited May 2 by roocker666 1 Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 2 Engineer Share Posted May 2 (edited) I see, thanks. Might result in less confusing code but there's 108 findings in kitana of 0000000000000017 (which 4 of them are counts) -> 104. Atm I've 100x [32] and 83x [48]. I'll check this. Edited May 2 by shak-otay Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 2 Author Engineer Share Posted May 2 (edited) 53 minutes ago, shak-otay said: I see, thanks. Might result in less confusing code but there's 108 findings in kitana of 0000000000000017 (which 4 of them are counts) -> 104. Atm I've 100x [32] and 83x [48]. I'll check this. Got it, just one more thing; At the end of the model there are a lot of tiny submeshes with count 4 and 8, those are the 5 little cubes that appear on top of the model(like in your image of scorpion). So you can delete those submeshes from the file. In Kitana those submeshes start at 0x2A400. So delete the code from 0x2A400 to 0x2BA10, that is useless. It should be same with scorpion. Edited May 2 by roocker666 Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 2 Engineer Share Posted May 2 (edited) There are smaller meshes all in the file, for example at # 1. 0x72c 8 [32] I'm not sure how deleting them would affect the creation of faces. For the 0000000000000017 thingie, it improves but gives some false results, too, for example for the block at 0x27dd0, which has a stride of 32. This was easy to correct and I think I can upload the tool after some more checks. edit: tool for testing (no uv support so far), kitana after extra faces being erased Make_obj_ShaolinMonksPS2.zip Edited May 2 by shak-otay 1 Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 2 Author Engineer Share Posted May 2 (edited) 9 hours ago, shak-otay said: There are smaller meshes all in the file, for example at # 1. 0x72c 8 [32] I'm not sure how deleting them would affect the creation of faces. For the 0000000000000017 thingie, it improves but gives some false results, too, for example for the block at 0x27dd0, which has a stride of 32. Those 5 cubes are always at the end of the model so you don't need to delete small meshes before those. About block 0x27dd0, the search 0000000000000017 is reading the last four bytes of the last vertex buffer of that specific mesh. SO false results is because of that(I think) Thanks for tool, I will test it right now Edited May 2 by roocker666 Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 2 Author Engineer Share Posted May 2 (edited) Ok, I used other model "Rayden" it seems like the model is fine(besides those extra faces lol). So the tool works 🙂 I guess you can add UVs later, according to my 2 first images: UVaddress = Vertaddress + 16(in both vertex formats 32 and 48) The problem are Normals becasue vbuf32 does not have Normals, in vbuf48 Normals address = Vertaddress + 32. Thanks for the effort man, here is a picture of Rayden: Edited May 2 by roocker666 1 Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 2 Engineer Share Posted May 2 Well, the uvs. There was always a problem with PS2 uvs, afair. (Maybe I solved a similar problem on Xentax but not for autocreated faces?) I've created sub meshes in the obj file to get more overview (without them the uvs cannot be separated). Makeobj_log-kitana_uvs.zip 1 Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 2 Author Engineer Share Posted May 2 (edited) 2 hours ago, shak-otay said: Well, the uvs. There was always a problem with PS2 uvs, afair. (Maybe I solved a similar problem on Xentax but not for autocreated faces?) I've created sub meshes in the obj file to get more overview (without them the uvs cannot be separated). Makeobj_log-kitana_uvs: Well, UVs look good but you need to delete all those extra faces(I did not delete extra faces of the head, that is why UVs look messy). And you need to group specific meshes according to textures. I grouped all meshes of the head and used the texture; BTW, here are Kitana textures if you want to check(4 textures): kitana_textures.rar Edited May 2 by roocker666 1 Link to comment Share on other sites More sharing options...
Engineer Solution shak-otay Posted May 3 Engineer Solution Share Posted May 3 6 hours ago, roocker666 said: Makeobj_log-kitana_uvs: Well, UVs look good If you say so, here's the app expanded by uvs: Make_obj_ShaolinMonks_uvs.zip 1 Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 3 Author Engineer Share Posted May 3 21 minutes ago, shak-otay said: If you say so, here's the app expanded by uvs.. Yep but you need to delete all extra faces and group meshes. It takes some time but the result is great! Thanks for the tool and all your help man. 😃 This is the result: Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 3 Engineer Share Posted May 3 (edited) 2 hours ago, roocker666 said: Yep but you need to delete all extra faces Maybe the standard tri strips algo isn't the best choice. They probably use a special one. edit: here another algo is used - don't see an improvement: Edited May 3 by shak-otay Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 3 Author Engineer Share Posted May 3 1 hour ago, shak-otay said: Maybe the standard tri strips algo isn't the best choice. They probably use a special one. Probably but this is better than nothing, lol Link to comment Share on other sites More sharing options...
Engineer roocker666 Posted May 3 Author Engineer Share Posted May 3 (edited) 11 hours ago, shak-otay said: edit: here another algo is used - don't see an improvement: I remember that I asked to Leeao about extracting Haunting ground PS2 maps years ago. As you know, PS2 maps don't have faces(like characters) so he wrote a plugin for Noesis. He read vertices buffer(UVs are in other separate block) and then created a Tri List, vertices buffer had this format: XXXX YYYY ZZZZ 0000803F XXXX YYYY ZZZZ 0000803F XXXX YYYY ZZZZ 0000803F XYZ are 3 Floats then 4 bytes of padding. Here are some images, I know it was made using Python but maybe you can do something similar using C++ Edited May 3 by roocker666 1 Link to comment Share on other sites More sharing options...
Engineer shak-otay Posted May 3 Engineer Share Posted May 3 (edited) Hi, basically the code in the 2nd picture is "standard" tri strips algo (at least I'd call it so:-). The interesting part is skiplist[ i ] which is filled in the code from the fst picture. The question is, "can we create a flag from the vertex block values?" I have my doubts when looking at your mesh format pictures above. But this is the path we need to follow, I guess. If skipflag is true the face is not written. Thus he skips the superfluous ones, afaics. Edited May 3 by shak-otay Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now