Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save coderofsalvation/20d3b68d892ab2e7ad430c6f28575943 to your computer and use it in GitHub Desktop.
Save coderofsalvation/20d3b68d892ab2e7ad430c6f28575943 to your computer and use it in GitHub Desktop.
programmatically read extras / custom properties from remote GLTF in Godot 4 gdscript
# For more sophisticated use of loading remote GLTF (with extras) use the xrfragment.org spec & xrfragment.gd script
# XRFRAGMENT.ORG is a mini-spec which standardizes 3D metadata without fileformat or platform lock-in
#
# Usage:
#
# load("https://xrfragment.org/index.glb")
# var doc = GLTFDocument.new()
# var state = GLTFState.new()
# #state.set_handle_binary_image(GLTFState.HANDLE_BINARY_EMBED_AS_BASISU) # Fixed in new Godot version (4.3 as I see) https://github.com/godotengine/godot/blob/17e7f85c06366b427e5068c5b3e2940e27ff5f1d/scene/resources/portable_compressed_texture.cpp#L116
# var error = doc.append_from_buffer(body, "", state)
# if error == OK:
# var scene = doc.generate_scene(state)
# metadata = _parseMetadata(state,scene)
# traverse(scene, evalNode)
# add_child(scene)
# print( find_child("mygltfnode").get_meta("extras")["foo"] ) # access extra
func _parseMetadata(state: GLTFState, scene: Node) -> Error:
#var meta = new Dictionary()
# Add metadata to materials
var materials_json : Array = state.json.get("materials", [])
var materials : Array[Material] = state.get_materials()
for i in materials_json.size():
if materials_json[i].has("extras"):
materials[i].set_meta("extras", materials_json[i]["extras"])
# Add metadata to ImporterMeshes
var meshes_json : Array = state.json.get("meshes", [])
var meshes : Array[GLTFMesh] = state.get_meshes()
for i in meshes_json.size():
if meshes_json[i].has("extras"):
meshes[i].mesh.set_meta("extras", meshes_json[i]["extras"])
# Add metadata to nodes
var nodes_json : Array = state.json.get("nodes", [])
for i in nodes_json.size():
if nodes_json[i].has("extras"):
var name = nodes_json[i]["name"].replace(".","_")
var node = scene.find_child(name) #state.get_scene_node(i)
if node:
node.set_meta( "extras", nodes_json[i]["extras"] )
else:
print(name+" could not be found")
return OK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment