Textures are in .dds so can be opened easily
3D models are in .gbx files instead, can something be done for them?
Trackmania .gbx
-
- Posts: 71
- Joined: Sun Aug 10, 2014 1:13 pm
Trackmania .gbx
Last edited by AMG on Sat Jan 30, 2016 3:06 pm, edited 1 time in total.
-
- Posts: 34
- Joined: Sun Nov 09, 2014 2:40 pm
Re: Trackmania .gbx
I tried to make a MAXScript for this format a while ago. There's two most common model types for cars (you can see which one it is by opening the model in a hex editor and looking at the first few bytes - BUCR (Binary - Compressed) and TUUE (Text - Uncompressed). BUCR models use LZO compression. My script works on a few TUUE files, and since it was complete enough to extract the model I wanted I didn't bother with it anymore. Maybe it'll be useful for some models:
Code: Select all
fGBX = getOpenFileName caption:"Choose Model File:" \
types:"TrackMania Gamebox Container (*.gbx)|*.gbx|"
fn readByteAsChar binstr = -- not necessary, but looks nicer in my opinion
(
return bit.intAsChar(readbyte binstr)
)
fn readTextLine binstr = -- reads a string until a newline character is found
(
str = ""
while c != 13 do
(
c = readbyte binstr #unsigned
if c != 13 do str += bit.intAsChar(c)
)
readbyte binstr
return str
)
fn readTextBool binstr = -- as above but returns boolean
(
return readTextLine binstr as booleanClass
)
fn readTextInt binstr = -- as above but returns integer
(
return readTextLine binstr as integer
)
fn readTextFloat binstr = -- as above but returns float
(
return readTextLine binstr as float
)
fn readStr binstr strLen = --reads a fixed-size string
(
str = ""
for w=1 to strLen do(str += (bit.intasChar(readByte binstr #unsigned)))
return str
)
if fGBX != undefined then (
f = fopen fGBX "rb"
clearlistener()
fArr=#()
vArr=#()
nArr=#()
tArr=#()
propertyCount = 7
firstMesh = true
modelPath = getFilenamePath fGBX
diffusePath = modelPath+"diffuse.dds"
detailsPath = modelPath+"details.dds"
diffMaterial = standard showInViewport:true Name:"diffuse"
detMaterial = standard showInViewport:true Name:"details"
diffMaterial.diffuseMap = Bitmaptexture fileName:diffusePath name:"diffuse"
detMaterial.diffuseMap = Bitmaptexture fileName:detailsPath name:"details"
header = readStr f 3
if header != "GBX" do return messageBox "This is not a TrackMania GBX Container."
version = readshort f
if version != 6 do messageBox "GBX file isn't version 6. There might be problems."
fileFormat = readByteAsChar f -- Binary or Text
refTable = readByteAsChar f -- Compressed or Uncompressed
fileBody = readByteAsChar f -- Compressed or Uncompressed
unknown = readByteAsChar f -- R or E (unknown purpose)
classID = readTextLine f -- in car models this should be 09005000
userData = readTextInt f -- length of user data
numRefs = readTextInt f -- number of chunks ? (unverified)
numExtRefs = readTextInt f -- number of external chunks ? (usually 0 - not used)
numMeshes = 0
for i=1 to 4 do -- totally the wrong way to do it
(
chunkID = readTextLine f
case chunkID of
(
default:
(
return messageBox "Unknown ID " + mainID + "."
)
"9005000":
(
readTextInt f
)
"9005007":
(
readTextBool f
)
"900500d":
(
readTextBool f
readTextBool f
readTextInt f
)
"904f000":
(
-- do nothing
)
"904f006":
(
readTextInt f
numMeshes = readTextInt f
readTextInt f
)
"904f006":
(
readTextInt f
numMeshes = readTextInt f
readTextInt f
)
"904f00d":
(
if firstMesh do
(
readTextInt f
firstMesh = false
)
)
"40000000":
(
objectName = readTextLine f
)
)
)
-- estimated beginning of submeshes
for i = 1 to numMeshes do
(
for x=1 to propertyCount do readTextLine f
objectName = readTextLine f
for x=1 to 23 do readTextLine f
count = readTextInt f
for x=1 to 2 do readTextLine f
free tArr
for x = 1 to count do
(
tu=readfloat f
tv=readfloat f
append tArr[tu,tv,0]
)
for x=1 to 10 do readTextLine f
free vArr
free nArr
for x = 1 to count do
(
vx=readfloat f
vy=readfloat f
vz=readfloat f
nx=readfloat f
ny=readfloat f
nz=readfloat f
unk1=readfloat f
unk2=readfloat f
unk3=readfloat f
unk4=readfloat f
append vArr[vx,-vz,vy]
append nArr[nx,-nz,ny]
)
for x=1 to 5 do readTextLine f
unk=readlong f
count=readTextInt f
free fArr
for x = 1 to count/3 do
(
fa=1+readshort f #unsigned
fb=1+readshort f #unsigned
fc=1+readshort f #unsigned
append fArr[fa,fb,fc]
)
for x=1 to 10 do readTextLine f
fseek f 8 #seek_cur
for x=1 to 4 do readTextLine f
fseek f 88 #seek_cur
for x=1 to 4 do readTextLine f
readlong f
for x=1 to 6 do readTextLine f
readlong f
tmatrix = matrix3 1
tmatrix.row1 = [readTextFloat f, readTextFloat f, readTextFloat f]
tmatrix.row2 = [readTextFloat f, readTextFloat f, readTextFloat f]
tmatrix.row3 = [readTextFloat f, readTextFloat f, readTextFloat f]
tmatrix.row4 = [readTextFloat f, readTextFloat f, readTextFloat f]
for x=1 to 2 do readTextLine f
max modify mode
cui.expertModeOn()
with redraw off
(
amesh = mesh vertices:vArr faces:fArr name:objectName
meshop.setMapSupport amesh 1 true
setMesh amesh tverts:tarr
for face = 1 to amesh.numfaces do setFaceSmoothGroup amesh face 1
select amesh
addmodifier amesh (Edit_Normals ()) ui:off
amesh.Edit_Normals.MakeExplicit selection:#{1..nArr.count}
EN_convertVS = amesh.Edit_Normals.ConvertVertexSelection
EN_setNormal = amesh.Edit_Normals.SetNormal
normID = #{}
--apply normals
for v = 1 to nArr.count do
(
free normID
EN_convertVS #{v} &normID
for id in normID do EN_setNormal id nArr[v]
)
collapseStack amesh
max select none
amesh.transform = tMatrix
--rotate amesh (eulerangles 90 0 0)
matType = objectName[1]
case matType of
(
default:
(
--return messageBox "Uknown material type."
)
"S":
(
amesh.material = diffMaterial
)
"s":
(
amesh.material = diffMaterial
)
"d":
(
amesh.material = detMaterial
)
"D":
(
amesh.material = detMaterial
)
"g":
(
amesh.material = detMaterial
)
)
)
propertyCount = 6
)
gc()
fclose f
cui.expertModeOff()
)
else
(
clearlistener()
)
-
- Posts: 46
- Joined: Sat Sep 27, 2014 10:24 pm
Re: Trackmania .gbx
barti wrote:I tried to make a MAXScript for this format a while ago. There's two most common model types for cars (you can see which one it is by opening the model in a hex editor and looking at the first few bytes - BUCR (Binary - Compressed) and TUUE (Text - Uncompressed). BUCR models use LZO compression. My script works on a few TUUE files, and since it was complete enough to extract the model I wanted I didn't bother with it anymore. Maybe it'll be useful for some models:Code: Select all
-code snipped for short reply-
So say if I have a BUCR model downloaded, which LZO decompression tool/scanner would I use? (probably simple question plus importing a BUCR model in the MAXscript throws errors). After investigation of Trackmania mods, this has me interested aswell..
-
- Posts: 34
- Joined: Sun Nov 09, 2014 2:40 pm
Re: Trackmania .gbx
There's no LZO scanner that I'm aware of. One way of going about it would be writing a QuickBMS script. But a better solution would be to decompress the LZO file within MAXScript - there's some info on the internet about that, but I haven't looked into it.
Also even if you extract a Binary - Compressed file, it's still not a Text file. My script only supports Text files so far, and even then only some of them will actually import - this script still needs a lot of work.
Also which version of Trackmania are you trying to import?
Also even if you extract a Binary - Compressed file, it's still not a Text file. My script only supports Text files so far, and even then only some of them will actually import - this script still needs a lot of work.
Also which version of Trackmania are you trying to import?
-
- Posts: 71
- Joined: Sun Aug 10, 2014 1:13 pm
Re: Trackmania .gbx
If I'm not wrong, the latest Trackmania games use the same format for these models, because in the readme I can't see any specification for this mod, if it is related to Nations, Sunrise, etc.
Of course, please correct me if my guess is wrong!
Of course, please correct me if my guess is wrong!
-
- Posts: 34
- Joined: Sun Nov 09, 2014 2:40 pm
Re: Trackmania .gbx
Automotive Gaming wrote:If I'm not wrong, the latest Trackmania games use the same format for these models, because in the readme I can't see any specification for this mod, if it is related to Nations, Sunrise, etc.
Of course, please correct me if my guess is wrong!
You're right, all TrackMania games (Nations, Sunrise, etc.) use similar model formats (with a few different versions). But I was wondering if TrackMania 2 uses this format as well.
From what I saw, cars for TrackMania 2 are packed in "NadeoPak" format, uses some kind of encryption.