extends EditorNode3DGizmoPlugin func _init(): print("[gizmo] _init") create_material("main", Color(1,0,1), false, true, false) create_material("secondary", Color(1,0,0)) func _get_gizmo_name() -> String: return "PortalGizmo" func _has_gizmo(for_node_3d: Node3D) -> bool: var result: bool = for_node_3d is Portal if result: print("[gizmo] _has_gizmo: " + for_node_3d.name) return result func _redraw(gizmo): var portal = gizmo.get_node_3d() as Portal print("[gizmo] _redraw: " + portal.name) gizmo.clear() # Always clear the gizmo if portal not in EditorInterface.get_selection().get_selected_nodes(): return # If not selected, don't draw anything var lines = PackedVector3Array() if portal.exit_portal != null: print("[gizmo] Drawing the bezier") # Draw a bezier curve connecting the two portals var exit = portal.exit_portal var D = portal.global_position.distance_to(exit.global_position) var p0 = Vector3.ZERO var p3 = portal.to_local(exit.global_position) var p1 = p0 + -portal.transform.basis.z * D * 0.25 # Control point var p2 = p3 + -exit.transform.basis.z * D * 0.25 # Control point var RESOLUTION: int = 24 lines.push_back(p0) for i in range(1, RESOLUTION + 1): var t: float = float(i) / RESOLUTION var spline_pos: Vector3 = pow(1 - t, 3) * p0 \ + 3 * pow(1 - t, 2) * t * p1 \ + 3 * (1 - t) * pow(t, 2) * p2 \ + pow(t, 3) * p3 lines.push_back(spline_pos) lines.push_back(p3) print("[gizmo] Bezier lines: " + str(lines.size())) gizmo.add_lines(PackedVector3Array([p0, p3, p1, p2]), get_material("secondary", gizmo)) #var handles = PackedVector3Array() #handles.push_back(Vector3(0, 1, 0)) #handles.push_back(Vector3(0, 2, 0)) gizmo.add_lines(lines, get_material("main", gizmo)) # Thicker dashed line var l2 = lines.duplicate() for i in range(l2.size()): l2[i].x += 0.01 gizmo.add_lines(l2, get_material("main", gizmo)) #gizmo.add_handles(handles, get_material("handles", gizmo), [])