Jump to content

Crash Bandicoot Nitro Kart 2 - Track 3D model


Recommended Posts

Posted

Hello guys, I've wanted to extract a mesh from the files I found in the game. It's an old iphone game. So far I've only managed to notice that the file is divided into chunks: VERT, TCOR, TXTR, MATL, INDS etc and also after some trial and error I noticed that if I divide the data into short signed floats it spits out something comprehensible. However it only generates a small part of the map. If someone could help me extract a full mesh from the file I'd really appreciate it
 

obraz.png

Track Mesh.zip

  • Engineers
Posted

Is mesh.bin a file from game folder or was it extracted? (If so, how?)

There's some assumed face index blocks (starting with 000001000200) but no suiting vertex blocks so far. Wild guess: sub mehes are assumed to be small, vertex count around 266.

 

mesh_viewer_sRpzdKLG40.png

Posted
20 minutes ago, shak-otay said:

Is mesh.bin a file from game folder or was it extracted? (If so, how?)

There's some assumed face index blocks (starting with 000001000200) but no suiting vertex blocks so far. Wild guess: sub mehes are assumed to be small, vertex count around 266.

 

mesh_viewer_sRpzdKLG40.png

Here are all the files I extracted from the game, the tracks are presumably the 12 biggest .vram files

CNK2.zip

  • Engineers
Posted

Thanks. I found the face index block at 0x333B which results in a vertex count of 403. But the vertices are still a riddle to me. Using FVFsize of 12 and shorts.

  • Members
Posted
35 minutes ago, shak-otay said:

Thanks. I found the face index block at 0x333B which results in a vertex count of 403. But the vertices are still a riddle to me. Using FVFsize of 12 and shorts.

They are 3 x (4 bytes unsigned longs).

  • Thanks 1
Posted

obraz.thumb.png.ef58eb0b2ac9fd2d0f9f4b82927b7e02.png

Thanks a lot guys, I'm starting to crack how this thing works. I noticed in the INDS section that the map is divided into multiple meshes, the indice data helped me establish how many vertices each mesh has. I'm quite sure that each vertex has 6 bytes and the indices are 3 byte each. 

  • Members
Posted
7 hours ago, Gargantus said:

I noticed in the INDS section that the map is divided into multiple meshes, the indice data helped me establish how many vertices each mesh has. I'm quite sure that each vertex has 6 bytes and the indices are 3 byte each. 

The VERT chunk has

chunk size (4 bytes longint)

vertex counter (4 bytes longint)

vertex counter * 6 bytes vertices

 

chunk size / vertex counter = 6

 

I did try to read the vertices as 3 x 2 bytes integers or 3 x 2 bytes words or 3 x 2 bytes half-floats, but none of them worked for me.

 

How did you get the correct vertex datas?

  • Members
Posted
39 minutes ago, Gargantus said:

Here's a simple C++ script I made and the output

I don't use the C language, but as I see the values are 2 bytes integers.

I don't undestrand that if I read the first 1000 vertices I have got a good view, but if I read all vertices I have got a very bad view.

CBNK_2_VRAM_ea0560ab_first_1000_vertices.png

CBNK_2_VRAM_ea0560ab_all_vertices.png

  • Engineers
Posted (edited)

I think it's just samples with different FVFsizes. With SCENVERS in the header it's 6 bytes, with 3DOBHEADL it's 12 bytes (just a wild guess).

Gargantus' code searches for 5254 hex, to find (VE)RT in SCENVERS  samples.

Quote

Gargantus

What did you use?

Sorry, have overread this. I used hex2obj.

Edited by shak-otay
  • Members
Posted
1 hour ago, shak-otay said:

I think it's just samples with different FVFsizes. With SCENVERS in the header it's 6 bytes, with 3DOBHEADL it's 12 bytes (just a wild guess).

Gargantus' code searches for 5254 hex, to find (VE)RT in SCENVERS  samples.

It's OK. The uploaded mesh.bin and my (I extracted from the game's archive file) ea0560ab.vram files are the same.

The header is SCENVERS and first time I tried to load all vertices from this file and I was confused about the 6 bytes vertex format.

Posted (edited)

I did some work on my script, it roughly divides the file into different meshes. Though I've yet to find a way to make it 100% consistent. Most meshes are off by a few vertices. It would be cool if you looked up for any patterns here

vram converter.zip

Edited by Gargantus
  • Thanks 1
  • Engineers
Posted (edited)

Thanks! Can you tell your compiler settings?

(I use

-std=C++11
-Wsign-compare

and output.txt is different/wrong. edit: changed the compiler, now output.txt is the same.)

---------------------

Your output.txt contains invalid triangles, for mesh 11 for example:

f 1 2 1 <
f 3 1 4
f 1 2 1 <
f 5 1 6
f 1 7 1 <
f 8 1 9
f 1 10 1 <
f 11 1 11 <
f 1 10 1 <
f 12 1 13
f 1 2 1 <
f 14 1 6
f 1 8 1 <
f 15 1 11
f 1 12 1 <

This can be avoided by checking for v0<>v1<>v2 before creating faces.

 

Edited by shak-otay
Posted (edited)

I'm using C++14 with wsign enabled. Also I realise that some meshes are incorrect, the script is still WIP, I just wanted wanted to show what patterns I've noticed. There are still some things that prevent it from being 100% accurate. I think that some of the later indices are actually 16 bit and not 8 bit like the first ones

Edited by Gargantus
  • Engineers
Posted (edited)
1 hour ago, Gargantus said:

I think that some of the later indices are actually 16 bit and not 8 bit like the first ones

edit: yep, I see. (Didn't see that you're reading bytes.)

when comparing mesh 11 fis (read as bytes) from output.txt

f 1 2 1
f 3 1 4
f 1 2 1
f 5 1 6
f 1 7 1
f 8 1 9
f 1 10 1
f 11 1 11
f 1 10 1
f 12 1 13
f 1 2 1
f 14 1 6
f 1 8 1
f 15 1 11
f 1 12 1

to hex2obj output from assumed offset 0x61FB7 (reading 16 bit fis):

Faces are different then>

f 1 2 3
f 4 2 5
f 6 7 8
f 9 10 11
f 11 10 12

f 13 2 14
f 6 8 15
f 11 12 16

 

Hex2obj0.25b-FIS.png

Edited by shak-otay
Posted

What I'm curious about is why are the mesh vertices offset backwards or forwards, seemingly in a random way. There's clearly some extra data between those vertices. Or maybe I'm calculating the indices wrongly, the meshes make sense when you offset them a bit though

  • Engineers
Posted (edited)

There's two ways at least to tackle the problems: doing a deep analysis (see bt templates, 010 editor, which is not free, btw) or using tools like hex2obj, meshreaper (AMR) or ModelResearcher (MR) to get some meshes (maybe these two methods are similar to bottom up versa top down.).

For now I'd suggest to create two lists of counts, for vertex blocks and FI blocks, where for the FIs the "max FI count" is required (must match the vertex count, as you have calculated, maxVertexNumber).

These lists would grant an overview about matching blocks, hopefully.

The naming,

meshList[i].size() confused me, btw, isn't it FaceIndexList[i].size()? 

 

Edited by shak-otay
Posted

the meshlist is a list of meshes, which are lists containing indice data, meshList.size() refers to the number of indices in a referred mesh. I use them to get the number of vertices per mesh

  • Engineers
Posted (edited)
3 hours ago, Gargantus said:

meshList.size() refers to the number of indices in a referred mesh.

Seems the browser swalloed the square brackets?

meshList[i].size()
Quote

There's clearly some extra data between those vertices.

How about uv data?

btw, mesh 1 starts at 0x162? (0x24 +53x6 dec.)

edit 2: mesh 2 is where it breaks:

blender_M2break.png

Edited by shak-otay

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...