Files
CosmicClash/tools/blender/extract_meshes.gd
T
Josh Creek 1eb5a3188d feat: replace ship and ball placeholder meshes with Blender-modeled assets
Ship gets a greebled hull, tapered nose, swept canopy, twin engine nacelles,
and tail fin (built via the vendored Blender MCP, generator committed at
tools/blender/gen_ship.py) in place of the 5 flat primitives. The ball is
fully remodeled as a smooth round sphere with a crossed emissive accent
pattern (gen_ball.py), replacing the old flat-shaded gold_ball rather than
just tweaking its material.

Node names (Nose/TailFin) are preserved for Ship._apply_team_color(), and
the RigidBody3D/CollisionShape3D physics on both ship.tscn and ball.tscn are
untouched so RL-trained bots and flight feel stay valid. Each part's mesh is
extracted to a standalone .res (tools/blender/extract_meshes.gd) rather than
referenced via glb::ArrayMesh_xxx sub-paths, which don't reliably resolve
across scene files and were silently rendering both models invisible.
2026-08-03 22:39:46 +01:00

36 lines
1.6 KiB
GDScript

## Extracts baked ArrayMesh resources out of the per-part ship/ball glb files
## into standalone .res files, which is what ship.tscn/ball.tscn actually
## reference (see gen_ship.py/gen_ball.py for why: a fresh glTF import's
## PackedScene wraps its single mesh object in a synthetic Node3D root, so
## the mesh itself needs pulling out to be usable as a direct MeshInstance3D
## child of Ship/Ball).
##
## Run after re-exporting the glbs from Blender (gen_ship.py / gen_ball.py):
## godot --headless --path Game --script ../tools/blender/extract_meshes.gd
## (from the repo root; adjust the relative --script path to wherever you run
## the command from). Overwrites the existing ship_*.res / ball.res files.
extends SceneTree
const SOURCES = {
"res://assets/models/ship_hull.glb": "res://assets/models/ship_hull.res",
"res://assets/models/ship_nose.glb": "res://assets/models/ship_nose.res",
"res://assets/models/ship_canopy.glb": "res://assets/models/ship_canopy.res",
"res://assets/models/ship_tailfin.glb": "res://assets/models/ship_tailfin.res",
"res://assets/models/ship_engine_l.glb": "res://assets/models/ship_engine_l.res",
"res://assets/models/ship_engine_r.glb": "res://assets/models/ship_engine_r.res",
"res://assets/models/ball.glb": "res://assets/models/ball.res",
}
func _initialize() -> void:
for glb_path in SOURCES:
var res_path: String = SOURCES[glb_path]
var packed: PackedScene = load(glb_path)
var instance: Node = packed.instantiate()
var mesh_node: MeshInstance3D = instance.get_child(0)
var err := ResourceSaver.save(mesh_node.mesh, res_path)
print("%s -> %s (err=%d)" % [glb_path, res_path, err])
instance.free()
quit()