OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / blender_bridge_live.gd

97 lines · gd ref:
@tool
## Live BlenderBridge editor test — starts server, exports scene, enables auto_sync.
##
## Usage:
##   1. Open this scene in the Godot editor
##   2. The bridge server starts automatically on /tmp/blender_bridge.sock
##   3. In Blender, enable the blender_bridge addon and click "Connect"
##   4. Move objects in either editor — transforms sync bidirectionally
##
## The @tool annotation makes this script run in the editor (not just at runtime).
extends Node3D

@export var auto_start: bool = true
@export var socket_path: String = "/tmp/blender_bridge.sock"
@export var debug_bones: bool = false:
	set(value):
		if value and Engine.is_editor_hint() and _bridge != null:
			var tree := get_tree()
			if tree:
				var scene_root: Node = tree.edited_scene_root
				if scene_root:
					_bridge.debug_skeleton(scene_root)
					print("[BlenderBridge] Bone debug dumped to output")

var _bridge: BlenderBridge
var _vt: VirtualTexture
var _started: bool = false


func _enter_tree() -> void:
	if not Engine.is_editor_hint():
		return
	call_deferred("_deferred_start")


func _deferred_start() -> void:
	if not auto_start or _started:
		return
	if not is_inside_tree():
		return

	_bridge = $BlenderBridge as BlenderBridge
	_vt = $VirtualTexture as VirtualTexture

	if _bridge == null:
		# Expected since v0.125.0: the bridge is owned by the EDITOR PLUGIN,
		# not by this scene. A node here would race the plugin for the same
		# socket and shared memory, and whichever is freed first unlinks the
		# segment out from under the other.
		print("[BlenderBridge] no node in this scene — the editor plugin owns the bridge")
		return

	# Wire VirtualTexture
	if _vt != null:
		_bridge.virtual_texture_path = _bridge.get_path_to(_vt)

	# Start UDS server — C++ _ready() may have already started it, that's OK
	_bridge.start_server(socket_path)

	# Export current scene to SHM for Blender to read
	var tree := get_tree()
	if tree:
		var scene_root: Node = tree.edited_scene_root
		if scene_root:
			_bridge.export_scene(scene_root)

	# Enable real-time bidirectional sync
	_bridge.auto_sync = true
	_started = true

	print("[BlenderBridge] Server started on %s — waiting for Blender connection" % socket_path)


func _exit_tree() -> void:
	if not Engine.is_editor_hint():
		return
	if _bridge != null and _started:
		_bridge.auto_sync = false
		_bridge.stop_server()
		_started = false
		print("[BlenderBridge] Server stopped")


func _process(_delta: float) -> void:
	if not Engine.is_editor_hint() or not _started:
		return
	if _bridge == null:
		return

	if Input.is_key_pressed(KEY_F6):
		var tree := get_tree()
		if tree:
			var scene_root: Node = tree.edited_scene_root
			if scene_root:
				_bridge.export_scene(scene_root)
				print("[BlenderBridge] Scene re-exported (F6)")