vtex_idx - themeldingwars/Documentation GitHub Wiki
Virtual texture index.
static.vtex_idx is the index for the static.vtex0 .. static.vtex6 virtual texture
files. It answers two questions: which texture assets exist in the virtual texture and where
they sit in it, and where an individual tile lives inside a given static.vtexN.
010 Editor Templates
- vtex_idx.bt
- vtex_idx.tileInfo.bt - run this on a decompressed tile info block
Format
Little endian.
Header
| Field | Type | Notes |
|---|---|---|
version |
uint32 |
|
imageInfoCount |
uint32 |
ImageInfo
imageInfoCount of these, 60 bytes each:
| Field | Type | Notes |
|---|---|---|
hash |
uint32[3] |
Three texture file hashes, see Image info hashes |
transform |
float[9] |
|
bounds |
uint16[4] |
|
offset |
uint32[4] |
|
crc |
uint32 |
TileInfo blocks
Exactly seven blocks follow the image infos, one for each static.vtexN, in order from 0
to 6:
| Field | Type | Notes |
|---|---|---|
compressedLength |
uint32 |
|
compressedData |
byte[compressedLength] |
FastLZ, same as CHUNK_GEOMETRY uses |
Each block decompresses to a flat array of 16 byte rows, with no count in front of it, so the row count is simply the decompressed length divided by 16:
| Field | Type | Notes |
|---|---|---|
offset |
uint64 |
Offset of the tile inside static.vtexN |
crc |
uint32 |
|
size |
uint32 |
Size of the tile data |
So to pull a single tile out of the virtual texture, decompress the tile info block for the
mip level you want, take the row for the tile, and slice size bytes at offset out of the
matching static.vtexN.
Image info hashes
Each imageinfo entry contains three hashes, each pointing to a different texture file. The
hash is a rotate-and-add over the ascii of the asset's path in the 00113000\00113473
form, i.e. the folder is the id rounded down to the nearest thousand:
public static uint GenerateHash(int textureAssetId)
{
string str = textureAssetId.ToString().PadLeft(8, '0');
str = str.Substring(0, str.Length - 3) + "000" + "\\" + str;
byte[] bytes = Encoding.ASCII.GetBytes(str);
uint hash = 0;
foreach (byte b in bytes)
{
hash = (hash << 7) | (hash >> (32 - 7));
hash += b;
}
return hash;
}
// assault
uint h1 = GenerateHash(113473);
uint h2 = GenerateHash(113475);
uint h3 = GenerateHash(113476);
Since the hash is over a fixed shape of string derived from a number, it can be reversed by brute force over the plausible asset id range rather than by cracking the hash.