pokemon-base/addons/gd-blender-3d-shortcuts/Utils.gd
2025-01-26 20:23:56 +01:00

188 lines
6.6 KiB
GDScript

static func apply_transform(nodes, transform, cache_global_transforms):
var i = 0
for node in nodes:
var cache_global_transform = cache_global_transforms[i]
node.global_transform.origin = cache_global_transform.origin
node.global_transform.origin += cache_global_transform.basis.get_rotation_quaternion() * transform.origin
node.global_transform.basis.x = cache_global_transform.basis * transform.basis.x
node.global_transform.basis.y = cache_global_transform.basis * transform.basis.y
node.global_transform.basis.z = cache_global_transform.basis * transform.basis.z
i += 1
static func apply_global_transform(nodes, transform, cache_transforms):
var i = 0
for node in nodes:
node.global_transform = transform * cache_transforms[i]
i += 1
static func revert_transform(nodes, cache_global_transforms):
var i = 0
for node in nodes:
node.global_transform = cache_global_transforms[i]
i += 1
static func reset_translation(nodes):
for node in nodes:
node.transform.origin = Vector3.ZERO
static func reset_rotation(nodes):
for node in nodes:
var scale = node.transform.basis.get_scale()
node.transform.basis = Basis().scaled(scale)
static func reset_scale(nodes):
for node in nodes:
var quat = node.transform.basis.get_rotation_quaternion()
node.transform.basis = Basis(quat)
static func hide_nodes(nodes, is_hide=true):
for node in nodes:
node.visible = !is_hide
static func recursive_get_children(node):
var children = node.get_children()
if children.size() == 0:
return []
else:
for child in children:
children += recursive_get_children(child)
return children
static func get_spatial_editor(base_control):
var children = recursive_get_children(base_control)
for child in children:
if child.get_class() == "Node3DEditor":
return child
static func get_spatial_editor_viewport_container(spatial_editor):
var children = recursive_get_children(spatial_editor)
for child in children:
if child.get_class() == "Node3DEditorViewportContainer":
return child
static func get_spatial_editor_viewports(spatial_editor_viewport):
var children = recursive_get_children(spatial_editor_viewport)
var spatial_editor_viewports = []
for child in children:
if child.get_class() == "Node3DEditorViewport":
spatial_editor_viewports.append(child)
return spatial_editor_viewports
static func get_spatial_editor_viewport_viewport(spatial_editor_viewport):
var children = recursive_get_children(spatial_editor_viewport)
for child in children:
if child.get_class() == "SubViewport":
return child
static func get_spatial_editor_viewport_control(spatial_editor_viewport):
var children = recursive_get_children(spatial_editor_viewport)
for child in children:
if child.get_class() == "Control":
return child
static func get_focused_spatial_editor_viewport(spatial_editor_viewports):
for viewport in spatial_editor_viewports:
var viewport_control = get_spatial_editor_viewport_control(viewport)
if viewport_control.get_rect().has_point(viewport_control.get_local_mouse_position()):
return viewport
static func get_snap_dialog(spatial_editor):
var children = recursive_get_children(spatial_editor)
for child in children:
if child.get_class() == "ConfirmationDialog":
if child.title == "Snap Settings":
return child
static func get_snap_dialog_line_edits(snap_dialog):
var line_edits = []
for child in recursive_get_children(snap_dialog):
if child.get_class() == "LineEdit":
line_edits.append(child)
return line_edits
static func get_spatial_editor_local_space_button(spatial_editor):
var children = recursive_get_children(spatial_editor)
for child in children:
if child.get_class() == "Button":
if child.shortcut:
if child.shortcut.get_as_text() == OS.get_keycode_string(KEY_T):# TODO: Check if user has custom shortcut
return child
static func get_spatial_editor_snap_button(spatial_editor):
var children = recursive_get_children(spatial_editor)
for child in children:
if child.get_class() == "Button":
if child.shortcut:
if child.shortcut.get_as_text() == OS.get_keycode_string(KEY_Y):# TODO: Check if user has custom shortcut
return child
static func project_on_plane(camera, screen_point, plane):
var from = camera.project_ray_origin(screen_point)
var dir = camera.project_ray_normal(screen_point)
var intersection = plane.intersects_ray(from, dir)
return intersection if intersection else Vector3.ZERO
static func transform_to_plane(t):
var a = t.basis.x
var b = t.basis.z
var c = a + b
var o = t.origin
return Plane(a + o, b + o, c + o)
# Return new position when out of bounds
static func infinite_rect(rect, from, to):
# Clamp from position to rect first, so it won't hit current side
from = Vector2(clamp(from.x, rect.position.x + 2, rect.size.x - 2), clamp(from.y, rect.position.y + 2, rect.size.y - 2))
# Intersect with sides of rect
var intersection
# Top
intersection = Geometry2D.segment_intersects_segment(rect.position, Vector2(rect.size.x, rect.position.y), from, to)
if intersection:
return intersection
# Left
intersection = Geometry2D.segment_intersects_segment(rect.position, Vector2(rect.position.x, rect.size.y), from, to)
if intersection:
return intersection
# Right
intersection = Geometry2D.segment_intersects_segment(rect.size, Vector2(rect.size.x, rect.position.y), from, to)
if intersection:
return intersection
# Bottom
intersection = Geometry2D.segment_intersects_segment(rect.size, Vector2(rect.position.x, rect.size.y), from, to)
if intersection:
return intersection
return null
static func draw_axis(im, origin, axis, length, color):
var from = origin + (-axis * length / 2)
var to = origin + (axis * length / 2)
im.surface_begin(Mesh.PRIMITIVE_LINES)
im.surface_set_color(color)
im.surface_add_vertex(from)
im.surface_add_vertex(to)
im.surface_end()
static func draw_dashed_line(canvas_item, from, to, color, width, dash_length = 5, cap_end = false, antialiased = false):
# See https://github.com/juddrgledhill/godot-dashed-line/blob/master/line_harness.gd
var length = (to - from).length()
var normal = (to - from).normalized()
var dash_step = normal * dash_length
if length < dash_length: #not long enough to dash
canvas_item.draw_line(from, to, color, width, antialiased)
return
else:
var draw_flag = true
var segment_start = from
var steps = length/dash_length
for start_length in range(0, steps + 1):
var segment_end = segment_start + dash_step
if draw_flag:
canvas_item.draw_line(segment_start, segment_end, color, width, antialiased)
segment_start = segment_end
draw_flag = !draw_flag
if cap_end:
canvas_item.draw_line(segment_start, to, color, width, antialiased)