Xaymar / Hellextractor

A simple tool to extract things from Helldivers 2 for your 3D printing needs.
BSD 3-Clause "New" or "Revised" License
32 stars 5 forks source link

[Help]: .unit format discovery thread #1

Open Xaymar opened 6 months ago

Xaymar commented 6 months ago

Everything about the .unit file structure.

Known Information
Related links:
Xaymar commented 6 months ago

This mesh should have animation data: 0x990B45D5D75FFF3A, 28. File contains errors #4, #6 and #3. The values in 0x7, 0x1f suggest it is indeed (type_2b_wide)[4], but the order is not exactly described. It looks like it'd be half, though it is unclear what the 4th value is for. Most of the time, it is 0, but rarely it is non-zero in the "exact" amount that's missing from [nX, nY, nZ].

Xaymar commented 6 months ago

"Up" in the Mesh is X, "Forward" is unknown.

Xaymar commented 6 months ago

0xA1AD36AF446FCB7D, mesh 6: Position is offset by 8 bytes, but there's no noticable difference to other structures. In this file, offset 0x18C into the DataType structure is set to 1. The vertex stride here is still 1, so what is the difference?

It's 100% identical it terms of elements: image

The only noticable difference is the single bit set to 1 suddenly: image

Xaymar commented 6 months ago

The offset is exactly 8, and only necessary for the first vertex. After that, all data is consecutive again.

Xaymar commented 6 months ago

This difference is not present in the other variant of the same model, which does not have this offset. Not related to the datatype?

Xaymar commented 6 months ago

image

This dword is different at the end.

Xaymar commented 6 months ago

That same dword is different in every model, so probably not that?

Xaymar commented 6 months ago

Oh, there appears to be a lot more data for meshes that is currently ignored. Not quite sure how to parse it at all...

Xaymar commented 6 months ago

This may be a possible BMS export error, and not actually caused by my tool.

Xaymar commented 6 months ago

We've had the mesh structure all wrong, and didn't notice it until now.

  1. The "offsets" entry is not relative to count, but relative to the list.
  2. Each mesh starts with two uint32s.
  3. There can be multiple materials.
    • 0x64 is the number of materials, 0x68 is the offset into the structure -4.
  4. There can be multiple vertex groups.
    • 0x74 is the number of groups, 0x78 is the offset into the structure.

This is big. It means that several meshes were incomplete by default, since we assumed there was only one set of vertex/index information. I'm not sure why the vertex_offset and vertex_count repeat as well, but they haven't changed yet.

Xaymar commented 6 months ago

0xA1AD36AF446FCB7D = 0x7DCB6F44AF36ADA1. Original BMS script had this set to BigEndian, but it's all LittleEndian. There are three copies of this file throughout the various data files, and only one of them has the 8 extra bytes at the start. The other two are fine.

Is there something in the data file that tells us more about why this is happening maybe?

Xaymar commented 6 months ago

Original BMS script is correct, it's easier to work with when it's big endian since the file name matches the bytes in the file. It's more like the id is 8 bytes long, so when we read it as an uint64_t it just ends up flipped.

Xaymar commented 6 months ago

Hashes appear to be MurmurHash(2) 64bit version. Not quite sure how to implement it, but I'll focus on proper exports for now.

Xaymar commented 6 months ago

When Type 6 or 7 is encountered, the data does not fit into the vertex stride anymore. They cannot reasonably exist in the same space as everything else.

Xaymar commented 6 months ago

The matrices and vectors in __unk1 seem to be related to something. There's some kind of relationship tree happening there, but I don't quite understand how it works yet.

Xaymar commented 6 months ago

Similarly, __unk6 seems to belong to the same type of relationship.

Xaymar commented 6 months ago

The end of unk1 overlaps with unk5 if __unk5 is present.

Xaymar commented 6 months ago

No apparent relation between bones file and __unk1. Number of bones doesn't ever match up with the number stored in there.

Xaymar commented 6 months ago

I'm probably approaching this from the wrong angle. I'm assuming that the game engine uses a model format, but this is clearly multiple models in one. It could very well have merged all the meshes into one cluster. It doesn't quite explain where animation and bone data goes though.

As far as I can tell, each of these .unit files is usually accompanied by .bones, .state_machine, .physics and .dfde6a8797b4c0ea. For units without a .bones file, the ones that are present are .physics and .dfde6a8797b4c0ea. For units with a .bones files, the .dfde6a8797b4c0ea is replaced with .state_machine often.

Xaymar commented 6 months ago

We also see .336bdb8766bd591d accompanying the same file - possibly another part of the .unit file.

Xaymar commented 6 months ago

Also of note is that several of the files are very clearly Havok Physics, and they all seem to be related to the bones in the model.

Xaymar commented 6 months ago

May have found some sort of LoD or similar?

unk0.unk_data[].__unk_data[].data[] is always lower than the maximum amount of meshes. Seems to cluster together around meshes.

Xaymar commented 6 months ago

__unk5 appears to also limit itself to the number of meshes in the unit file.

Xaymar commented 6 months ago

Unfortunately my theory about type 7 and 6 not fitting in the vertex stride was destroyed by another file having a vertex stride where they fit again.

Xaymar commented 6 months ago

Format 24 might be "Bone Indices" and Format 25 is "Bone Weights". These both appear to be u8vec4_t

Xaymar commented 6 months ago

Format 24, 25 and 26 are still unknown. 25 is definitely not bone indices, as either there are 65535 possible bones, or most models refer to bone 255 and assign a weight of 0 to it - assuming 24 is bone weights.

Xaymar commented 6 months ago
Formats:
Types:
Xaymar commented 6 months ago
content/objectives/obj_common/gneeric_intel/generic_intel.unit
Xaymar commented 6 months ago
content/fac_helldivers/vehicles/lav/lav.unit
Xaymar commented 6 months ago
content/fac_helldives/vehicles/combat_walker/combat_walker.unit
Xaymar commented 6 months ago

We now have a reasonably deep understanding to reproduce a mesh tree in glTF format.