Skip to content

Instantly share code, notes, and snippets.

@uyjulian
Last active October 17, 2023 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uyjulian/192386639491057e92836d9cbbaf4d1b to your computer and use it in GitHub Desktop.
Save uyjulian/192386639491057e92836d9cbbaf4d1b to your computer and use it in GitHub Desktop.
# SPDX-License-Identifier: MIT
# fbxex_bin2json
# usage: /path/to/python3 /path/to/fbxex_bin2json.py /path/to/bg.fbx.bin
# Use with fbxex2gltf to convert to gltf
import sys
import json
import struct
def read_unpack(fmt, f):
return struct.unpack(fmt, f.read(struct.calcsize(fmt)))
def trim_null(s):
return s[:s.find(b"\x00")]
def convert_fbxex(f):
if f.read(16) != b"fbxex\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00":
raise Exception("Not fbxex format")
json_root = {}
fbxex_obj = {}
json_root["fbxex"] = fbxex_obj
f.read(4) # ???
texture_obj = {}
fbxex_obj["texture"] = texture_obj
texture_obj["count"] = int.from_bytes(f.read(4), byteorder="little")
for i in range(texture_obj["count"]):
texture_s_obj = {}
texture_obj[str(i)] = texture_s_obj
texture_s_obj["filename"] = trim_null(f.read(128)).decode("ASCII")
texture_s_obj["index"] = i
f.read(4) # ???
material_obj = {}
fbxex_obj["material"] = material_obj
material_obj["count"] = int.from_bytes(f.read(4), byteorder="little")
for i in range(material_obj["count"]):
material_s_obj = {}
material_obj[str(i)] = material_s_obj
material_s_obj["filename"] = trim_null(f.read(128)).decode("ASCII")
material_s_obj["index"] = int.from_bytes(f.read(4), byteorder="little")
material_s_obj["texture_index"] = int.from_bytes(f.read(4), byteorder="little")
material_s_obj["value"] = list(read_unpack('fffffffffffffffff', f))
f.read(4) # ???
node_obj = {}
fbxex_obj["node"] = node_obj
node_obj["count"] = int.from_bytes(f.read(4), byteorder="little")
for i in range(node_obj["count"]):
f.read(4) # ???
node_s_obj = {}
node_obj[str(i)] = node_s_obj
node_s_obj["type"] = int.from_bytes(f.read(4), byteorder="little")
if node_s_obj["type"] not in [0, 1]:
raise Exception("Unknown node type")
node_s_obj["child"] = int.from_bytes(f.read(4), byteorder="little", signed=True)
node_s_obj["sibling"] = int.from_bytes(f.read(4), byteorder="little", signed=True)
if node_s_obj["type"] == 1:
node_s_obj["blendmode"] = int.from_bytes(f.read(4), byteorder="little")
node_s_obj["alpha"] = int.from_bytes(f.read(4), byteorder="little")
node_s_obj["matrix"] = list(read_unpack('ffffffffffffffff', f))
node_vertex_s_obj = {}
node_s_obj["vertex"] = node_vertex_s_obj
node_vertex_s_obj["count"] = int.from_bytes(f.read(4), byteorder="little")
for ii in range(node_vertex_s_obj["count"]):
node_vertex_s_obj[str(ii)] = list(read_unpack('ffffffffffff', f))
node_material_s_obj = {}
node_s_obj["material"] = node_material_s_obj
node_material_s_obj["count"] = int.from_bytes(f.read(4), byteorder="little")
for ii in range(node_material_s_obj["count"]):
node_material_s_s_obj = {}
node_material_s_obj[str(ii)] = node_material_s_s_obj
node_material_s_s_obj["index"] = int.from_bytes(f.read(4), byteorder="little")
node_material_s_s_obj["vertexindexcount"] = int.from_bytes(f.read(4), byteorder="little")
node_material_s_s_obj["vertexindex"] = [int.from_bytes(f.read(4), byteorder="little") for iii in range(node_material_s_s_obj["vertexindexcount"])]
f.read(4) # ???
anime_obj = {}
fbxex_obj["anime"] = anime_obj
anime_obj["count"] = int.from_bytes(f.read(4), byteorder="little")
for i in range(anime_obj["count"]):
anime_obj[str(i)] = list(read_unpack('Iffffffffffffffff', f))
return json_root
if __name__ == "__main__":
d = None
with open(sys.argv[1], "rb") as f:
d = convert_fbxex(f)
with open(sys.argv[1] + ".json", "wb") as f:
f.write(json.dumps(d).encode("ASCII"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment