class_name TransformTool extends EditorTool ## Moves, rotates, or scales an existing object. ## ## Not one of the four tools literally named in docs/architecture/editor.md ## ยง7.1's `ToolRegistry` list ("brush / object-place / select / erase, ## etc.") but required by this task's brief ("place / move / rotate / scale ## / delete") -- the doc's own "etc." leaves room, so this is a fifth ## registered tool rather than overloading `ObjectPlaceTool` (placing a new ## object and re-transforming an existing one are different undo units) ## or `SelectTool` (selection is deliberately not chunk-mutating). ## ## `args`: `object_id` (String), `op` ("move" | "rotate" | "scale"), `value` ## (Vector3 for move/scale, Vector4 quaternion for rotate). func _init() -> void: tool_id = "transform" func apply(core: EditorCore, args: Dictionary) -> Variant: var object_id: String = args.get("object_id", "") var op: String = args.get("op", "") var obj := core.model.find_object(object_id) if obj == null: return false match op: "move": return _apply_vector3(core, object_id, args.get("value", obj.position), obj.position, "Move", core.model.set_object_position_raw) "rotate": return _apply_vector4(core, object_id, args.get("value", obj.rotation), obj.rotation, "Rotate", core.model.set_object_rotation_raw) "scale": return _apply_vector3(core, object_id, args.get("value", obj.scale), obj.scale, "Scale", core.model.set_object_scale_raw) _: push_error("TransformTool: unknown op '%s'" % op) return false func _apply_vector3(core: EditorCore, object_id: String, new_value: Vector3, old_value: Vector3, label: String, setter: Callable) -> bool: if new_value.is_equal_approx(old_value): return false core.undo_redo.begin("%s '%s'" % [label, object_id]) core.undo_redo.add_do(setter.bind(object_id, new_value)) core.undo_redo.add_undo(setter.bind(object_id, old_value)) core.undo_redo.commit() return true func _apply_vector4(core: EditorCore, object_id: String, new_value: Vector4, old_value: Vector4, label: String, setter: Callable) -> bool: if new_value.is_equal_approx(old_value): return false core.undo_redo.begin("%s '%s'" % [label, object_id]) core.undo_redo.add_do(setter.bind(object_id, new_value)) core.undo_redo.add_undo(setter.bind(object_id, old_value)) core.undo_redo.commit() return true