stuff
This commit is contained in:
159
addons/lightmap_probe_grid/gizmo.gd
Normal file
159
addons/lightmap_probe_grid/gizmo.gd
Normal file
@@ -0,0 +1,159 @@
|
||||
# my_custom_gizmo_plugin.gd
|
||||
extends EditorNode3DGizmoPlugin
|
||||
|
||||
const handles_axis: PackedVector3Array = [
|
||||
Vector3(1, 0, 0),
|
||||
Vector3(0, 1, 0),
|
||||
Vector3(0, 0, 1),
|
||||
Vector3(-1, 0, 0),
|
||||
Vector3(0, -1, 0),
|
||||
Vector3(0, 0, -1)
|
||||
]
|
||||
|
||||
const box_lines: PackedVector3Array = [
|
||||
# plane -x
|
||||
Vector3(-1, -1, -1), Vector3(-1, -1, 1),
|
||||
Vector3(-1, -1, 1), Vector3(-1, 1, 1),
|
||||
Vector3(-1, 1, 1), Vector3(-1, 1, -1),
|
||||
Vector3(-1, 1, -1), Vector3(-1, -1, -1),
|
||||
# plane +x
|
||||
Vector3(1, -1, -1), Vector3(1, -1, 1),
|
||||
Vector3(1, -1, 1), Vector3(1, 1, 1),
|
||||
Vector3(1, 1, 1), Vector3(1, 1, -1),
|
||||
Vector3(1, 1, -1), Vector3(1, -1, -1),
|
||||
# connecting plane x with -x
|
||||
Vector3(1, -1, -1), Vector3(-1, -1, -1),
|
||||
Vector3(1, -1, 1), Vector3(-1, -1, 1),
|
||||
Vector3(1, 1, -1), Vector3(-1, 1, -1),
|
||||
Vector3(1, 1, 1), Vector3(-1, 1, 1),
|
||||
]
|
||||
|
||||
var icon: Texture2D = preload("lightmap_probe_grid_icon.svg")
|
||||
|
||||
var timer: Timer = Timer.new()
|
||||
var is_awayting: bool = false
|
||||
|
||||
|
||||
func _get_gizmo_name() -> String:
|
||||
return "LightmapProbeGrid"
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
create_material("main_material", Color(0,0,0))
|
||||
create_material("tool_material", Color(1, 0.9, 0))
|
||||
create_handle_material("handles_material")
|
||||
create_icon_material("icon_material", icon)
|
||||
|
||||
|
||||
func _has_gizmo(node: Node3D) -> bool:
|
||||
if node is LightmapProbeGrid:
|
||||
if not node.size_changed.is_connected(node.update_gizmos):
|
||||
node.size_changed.connect(node.update_gizmos)
|
||||
if not node.probes_changed.is_connected(node.update_gizmos):
|
||||
node.probes_changed.connect(node.update_gizmos)
|
||||
return true
|
||||
else:
|
||||
return false
|
||||
|
||||
|
||||
func _redraw(gizmo: EditorNode3DGizmo) -> void:
|
||||
gizmo.clear()
|
||||
var box: LightmapProbeGrid = gizmo.get_node_3d() as LightmapProbeGrid
|
||||
var size: Vector3 = box.size
|
||||
|
||||
var icon_gizmo: Material = get_material("icon_material")
|
||||
gizmo.add_unscaled_billboard(icon_gizmo, 0.05)
|
||||
|
||||
# Setting box lines
|
||||
var lines: PackedVector3Array = []
|
||||
for pos: Vector3 in box_lines:
|
||||
var scaled: Vector3 = 0.5 * pos * size
|
||||
lines.append(scaled)
|
||||
gizmo.add_lines(lines, get_material("main_material", gizmo))
|
||||
|
||||
# Setting handles
|
||||
var handles: PackedVector3Array = []
|
||||
for pos: Vector3 in handles_axis:
|
||||
var scaled: Vector3 = 0.5 * pos * size
|
||||
handles.append(scaled)
|
||||
gizmo.add_handles(handles, get_material("handles_material", gizmo), [])
|
||||
|
||||
# Setting extra tool lines from main script
|
||||
var tool_lines: PackedVector3Array = box.gizmo_lines
|
||||
if not tool_lines.is_empty():
|
||||
gizmo.add_lines(tool_lines, get_material("tool_material", gizmo))
|
||||
clear_tool_await(box)
|
||||
|
||||
|
||||
# Wait 3 seconds before clear the main script gizmos. If called twice the timer is reset
|
||||
func clear_tool_await(box: LightmapProbeGrid):
|
||||
if timer == null:
|
||||
timer = Timer.new()
|
||||
# Add timer to the scene
|
||||
if timer.get_parent() == null:
|
||||
var root_node = EditorInterface.get_edited_scene_root()
|
||||
root_node.add_child(timer)
|
||||
timer.name = "lightmap_probe_grid_timer"
|
||||
|
||||
timer.wait_time = 3.0
|
||||
timer.start()
|
||||
|
||||
if is_awayting:
|
||||
return
|
||||
|
||||
is_awayting = true
|
||||
await timer.timeout
|
||||
is_awayting = false
|
||||
|
||||
timer.stop
|
||||
box.gizmo_lines.clear()
|
||||
box.update_gizmos()
|
||||
|
||||
|
||||
# Based on github.com/godotengine/godot/blob/master/editor/plugins/gizmos/gizmo_3d_helper.cpp
|
||||
# please, make it available to GDScript plugin developers...
|
||||
func _set_handle(gizmo: EditorNode3DGizmo, index: int, _sec: bool, camera: Camera3D, point: Vector2) -> void:
|
||||
var box: LightmapProbeGrid = gizmo.get_node_3d() as LightmapProbeGrid
|
||||
var axis: Vector3 = handles_axis[index]
|
||||
var axis_index: int = axis.abs().max_axis_index()
|
||||
|
||||
var inverse: Transform3D = box.global_transform.affine_inverse()
|
||||
var ray_from: Vector3 = camera.project_ray_origin(point)
|
||||
var ray_to: Vector3 = camera.project_ray_normal(point)
|
||||
var camera_position: Vector3 = inverse * ray_from
|
||||
var camera_to_mouse: Vector3 = inverse * (ray_from + ray_to * 5000)
|
||||
|
||||
var segment1: Vector3 = axis * 5000
|
||||
var segment2: Vector3 = axis * -5000
|
||||
|
||||
var intersection: PackedVector3Array = Geometry3D.get_closest_points_between_segments(segment2,
|
||||
segment1, camera_position, camera_to_mouse)
|
||||
|
||||
# Distance between the center and the handle (without scale)
|
||||
var distance: float = intersection[0][axis_index]
|
||||
# multiply axis signal to cancel distance signal
|
||||
distance *= axis[axis_index]
|
||||
|
||||
var old_distance: float = 0.5 * box.size[axis_index]
|
||||
|
||||
# Defining new size and positions
|
||||
var new_size: float = distance + old_distance
|
||||
|
||||
# Translate halfway through the size difference
|
||||
var translate: Vector3 = 0.5 * (distance - old_distance) * axis
|
||||
|
||||
# Updating size and position
|
||||
box.size[axis_index] = new_size
|
||||
box.translate(translate)
|
||||
|
||||
# Update Gizmo
|
||||
box.update_gizmos()
|
||||
|
||||
|
||||
func _get_handle_name(_gizmo: EditorNode3DGizmo, _handle_id: int, _sec: bool) -> String:
|
||||
return "Probe Grid Size"
|
||||
|
||||
|
||||
func _get_handle_value(gizmo: EditorNode3DGizmo, _id: int, _sec: bool) -> Vector3:
|
||||
var box: LightmapProbeGrid = gizmo.get_node_3d() as LightmapProbeGrid
|
||||
return box.size
|
||||
Reference in New Issue
Block a user