Saturday, 6 August 2016

And a bit more I76 - Higher Resolution Geometry

Getting Slightly Better Models...


The higher resolution car meshes in i76 are distributed throughout the .geo files, each of which can hold a different section of the car.

To assemble the full model you need to select the right group of .geo files, extract the meshes and plug them together in the correct way.

The root definitions for these groupings are in the vehicle VDF files, and these files open with the "BWD2" signature.

A quick note on the BWD2 files

The "BWD2" files (vdf, cdf, wdf, etc) are all arranged in a Tag-Length-Data format.

The first four bytes are a simple tag string (e.g. “VDFC”, “VSHL”, “VGEO”)

The next four bytes are the length of this data field (including the tag). The shortest length here is 8 (the four byte tag and four byte length). The BWD2 marker itself and “EXIT” fields, which appear to be used as section delimiters in the files, have this length.

Following this is the data, formatted with a layout specific to the tag.

So the BWD2 Header is:
  •   4 Bytes BWD2
  •   4 Bytes Length of this field. This is always 8 (The tag & length only)

Then a revision tag follows, as:
  •   4 byte “REV “ tag
  •   4 byte Length, Always 12
  •   4 Byte of revision data (Always 8 in the version of i76 I have)

And the remaining fields vary between files. So in car definitions (vdf) the next label is (always?):
  •   4 byte “VDFC”
  •   4 byte Length, always 72 for the i76 files
  •   64 byte data – a car description

Putting together the cars

When assembling geometry we initially care about the VGEO fields. These tell us how the various .geo files are combined to form the car views.

So the VGEO field is formatted :
  •   4 byte header, which is “VGEO”
  •   4 byte length
  •   A single uint32_t (unknown?)

Then a number of 100 byte entries, each of which is:
  •   8 byte part label
  •   48 bytes, which are 12 four byte floats
  •   8 byte position root label
  •   36 bytes “unknown stuff”

Either the main or geometry label can be replaced with the string “NULL ” in which case this entry is empty.

The first label specifies the object name, which tells us the .geo file we should load for this piece of geometry.

The "position root label" specifies the thing that this item is positioned in relation to. For items which are placed with global co-ordinates then this is “WORLD”.

So for example the main car body is placed globally, i.e. has the position label “WORLD”, but the side mirror co-ordinates are offsets from the main car body itself, and have the position label "PP11BDYM".

The 12 floats give the offset co-ordinates to use. In the vehicle case the last three are interesting, since we can use them as “X” “Z” and “-Y” respectively to place imported objects in blender. The first 9 values are (always?) “1 0 0 0 1 0 0 0 1”  - I'd guess at a set of three scaling vectors which map 1:1 into X, Y & Z, but with uniform values it's hard to tell.


The Results

For the piranha from vppirnha.vdf then parsing the first 14 values in the VGEO section gives us the geometry files for a slightly higher resolution version of the car.

So we get this from the first VGEO sections:

VGEO: "PP11BDYM" "WORLD" "1 0 0 0 1 0 0 0 1 X:-5.32866e-05 Z:0.656801 -Y:-0.00405699 "
VGEO: "PP11BDYF" "WORLD" "1 0 0 0 1 0 0 0 1 X:-5.31375e-05 Z:0.645133 -Y:1.51002 "
VGEO: "PP11BDYB" "WORLD" "1 0 0 0 1 0 0 0 1 X:-4.19021e-05 Z:0.694423 -Y:-1.56466 "
VGEO: "PP11BDYT" "WORLD" "1 0 0 0 1 0 0 0 1 X:2.08616e-07 Z:1.17125 -Y:-0.341815 "
VGEO: "PP11BLGT" "WORLD" "1 0 0 0 1 0 0 0 1 X:-0.00209564 Z:0.853375 -Y:-2.32971 "
VGEO: "PP11BWLL" "PP11BDYB" "1 0 0 0 1 0 0 0 1 X:0.000834048 Z:-0.225637 -Y:0.263154 "
VGEO: "PP11FWLL" "PP11BDYF" "1 0 0 0 1 0 0 0 1 X:0.000631988 Z:-0.175059 -Y:-0.134667 "
VGEO: "PP11HLGT" "WORLD" "1 0 0 0 1 0 0 0 1 X:0.00434026 Z:0.716669 -Y:2.32806 "
VGEO: "PP11MIRL" "PP11BDYM" "1 0 0 0 1 0 0 0 1 X:-0.831573 Z:0.39666 -Y:0.452536 "
VGEO: "PP11MIRR" "PP11BDYM" "1 0 0 0 1 0 0 0 1 X:0.846213 Z:0.3966 -Y:0.452659 "
VGEO: "PP11PIPL" "PP11BDYM" "1 0 0 0 1 0 0 0 1 X:-0.727008 Z:-0.454351 -Y:-0.734841 "
VGEO: "PP11PIPR" "PP11BDYM" "1 0 0 0 1 0 0 0 1 X:0.718643 Z:-0.451539 -Y:-0.728832 "
VGEO: "PP11RTCL" "PP11BDYF" "1 0 0 0 1 0 0 0 1 X:-0.412791 Z:0.427997 -Y:-0.579116 "
VGEO: "PP11TLGT" "PP11HLGT" "1 0 0 0 1 0 0 0 1 X:-0.0064359 Z:0.136707 -Y:-4.65002 "
 


We can see mostly these are global co-ords (WORLD), but for example PP11BWLL, which is the back wheel well, is placed relative to PP11BDYB, the back body.

And converting those .geo files to obj and assembling the pieces into blender according to the values here gets....

Hooray!

I've tweaked the mirror positions, hidden the light emitters (which seem to hover away from the body) and everything is left/right transposed, but those are fairly minor issues – this looks good enough to be mostly correct.

There are a number of different resolution versions of the vehicle in the subsequent VGEO sections, presumably for LOD switching, and I suppose those details are hidden in the 36 bytes of "other" stuff that trail the geometry label, but that would take a bit more work to pull out.