generated from mstar/godot-template
189 lines
6.6 KiB
GDScript3
189 lines
6.6 KiB
GDScript3
|
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)
|