add alignment system to rooms

This commit is contained in:
Nitwel 2024-01-24 17:43:44 +01:00
parent 0875d37ec2
commit 0f50f5a0c8
14 changed files with 207 additions and 40 deletions

View File

@ -2,7 +2,10 @@
extends Function extends Function
class_name Movable class_name Movable
signal on_move(position: Vector3, rotation: Vector3)
@export var restricted: bool = false @export var restricted: bool = false
@export var restrict_movement: Callable
@export var lock_rotation: bool = false @export var lock_rotation: bool = false
var hit_node := Node3D.new() var hit_node := Node3D.new()
@ -14,10 +17,20 @@ func _on_grab_down(event: EventPointer):
hit_node.global_transform = get_parent().global_transform hit_node.global_transform = get_parent().global_transform
func _on_grab_move(_event: EventPointer): func _on_grab_move(_event: EventPointer):
get_parent().global_position = hit_node.global_position if hit_node.get_parent() == null:
return
if restrict_movement:
get_parent().global_position = restrict_movement.call(hit_node.global_position)
else:
get_parent().global_position = hit_node.global_position
if !lock_rotation: if !lock_rotation:
get_parent().global_rotation = hit_node.global_rotation get_parent().global_rotation = hit_node.global_rotation
on_move.emit(get_parent().global_position, get_parent().global_rotation)
else:
on_move.emit(get_parent().global_position, Vector3(0, 0, 0))
func _on_grab_up(event: EventPointer): func _on_grab_up(event: EventPointer):
event.initiator.node.remove_child(hit_node) event.initiator.node.remove_child(hit_node)

View File

@ -0,0 +1,46 @@
extends Node3D
@onready var corner1 = $Corner1
@onready var corner2 = $Corner1/Corner2
@onready var edge = $Edge
@onready var marker = $Edge/Marker3D
@export var disabled: bool:
set(value):
disabled = value
if !is_node_ready(): await ready
corner1.get_node("CollisionShape3D").disabled = value
corner2.get_node("CollisionShape3D").disabled = value
edge.get_node("CollisionShape3D").disabled = value
corner1.visible = !value
corner2.visible = !value
edge.visible = !value
func _ready():
update_initial_positions()
corner1.get_node("Movable").on_move.connect(func(position, rotation):
edge.align_to_corners(corner1.global_position, corner2.global_position)
)
corner2.get_node("Movable").on_move.connect(func(position, rotation):
edge.align_to_corners(corner1.global_position, corner2.global_position)
)
corner2.get_node("Movable").restrict_movement = func(new_position):
new_position.y = corner1.global_position.y
var delta_new_pos_corner1 = (new_position - corner1.position).normalized()
return corner1.position + delta_new_pos_corner1
func update_initial_positions():
edge.align_to_corners(corner1.global_position, corner2.global_position)
marker.global_transform = House.body.transform
func get_new_transform(old_transform: Transform3D):
marker.scale = Vector3(1, 1, 1)
return marker.global_transform

View File

@ -0,0 +1,36 @@
[gd_scene load_steps=6 format=3 uid="uid://jls16btb8nko"]
[ext_resource type="Script" path="res://content/system/house/align_reference.gd" id="1_8fatp"]
[ext_resource type="PackedScene" uid="uid://brf6mm2gxj7y2" path="res://content/system/house/room/wall_corner.tscn" id="2_ppkie"]
[ext_resource type="PackedScene" uid="uid://dlj5chj7ndgua" path="res://content/system/house/room/wall_edge.tscn" id="3_6o3xn"]
[ext_resource type="Script" path="res://content/functions/movable.gd" id="3_7ktdq"]
[sub_resource type="CylinderMesh" id="CylinderMesh_0e4xu"]
top_radius = 0.1
bottom_radius = 0.1
height = 0.2
[node name="AlignReference" type="Node3D"]
script = ExtResource("1_8fatp")
[node name="Corner1" parent="." instance=ExtResource("2_ppkie")]
[node name="Movable" type="Node" parent="Corner1"]
script = ExtResource("3_7ktdq")
restricted = true
lock_rotation = true
[node name="Corner2" parent="Corner1" instance=ExtResource("2_ppkie")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0)
[node name="Movable" type="Node" parent="Corner1/Corner2"]
script = ExtResource("3_7ktdq")
lock_rotation = true
[node name="Edge" parent="." instance=ExtResource("3_6o3xn")]
transform = Transform3D(-4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0, 1, 0.5, 0, 0)
[node name="Marker3D" type="Marker3D" parent="Edge"]
[node name="MeshInstance3D" type="MeshInstance3D" parent="Edge/Marker3D"]
mesh = SubResource("CylinderMesh_0e4xu")

View File

@ -5,7 +5,9 @@ const RoomType = preload("./room/room.gd")
@onready var levels = $Levels @onready var levels = $Levels
@onready var collision_shape = $Levels/CollisionShape3D @onready var collision_shape = $Levels/CollisionShape3D
@onready var align_reference = $AlignReference
var fixing_reference: bool = false
var editing_room: RoomType = null var editing_room: RoomType = null
var mini_view: bool = false: var mini_view: bool = false:
set(value): set(value):
@ -146,3 +148,21 @@ func update_mini_view():
for room in get_rooms(0): for room in get_rooms(0):
room.state_machine.change_to("Mini" if mini_view else "View") room.state_machine.change_to("Mini" if mini_view else "View")
func edit_reference():
fixing_reference = false
align_reference.disabled = false
func fix_reference():
fixing_reference = true
align_reference.disabled = false
align_reference.update_initial_positions()
func save_reference():
if fixing_reference:
var align_transform = align_reference.global_transform
transform = align_reference.get_new_transform(transform)
align_reference.global_transform = align_transform
align_reference.disabled = true
align_reference.update_initial_positions()

View File

@ -1,10 +1,15 @@
[gd_scene load_steps=4 format=3 uid="uid://cbemihbxkd4ll"] [gd_scene load_steps=6 format=3 uid="uid://cbemihbxkd4ll"]
[ext_resource type="Script" path="res://content/system/house/house.gd" id="1_p8amj"] [ext_resource type="Script" path="res://content/system/house/house.gd" id="1_p8amj"]
[ext_resource type="Script" path="res://content/functions/movable.gd" id="2_w1auk"] [ext_resource type="Script" path="res://content/functions/movable.gd" id="2_w1auk"]
[ext_resource type="PackedScene" uid="uid://jls16btb8nko" path="res://content/system/house/align_reference.tscn" id="3_e1tcn"]
[sub_resource type="BoxShape3D" id="BoxShape3D_x81up"] [sub_resource type="BoxShape3D" id="BoxShape3D_x81up"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_uovmo"]
radius = 0.02
height = 0.4
[node name="House" type="Node3D"] [node name="House" type="Node3D"]
script = ExtResource("1_p8amj") script = ExtResource("1_p8amj")
@ -20,3 +25,10 @@ disabled = true
script = ExtResource("2_w1auk") script = ExtResource("2_w1auk")
restricted = true restricted = true
lock_rotation = true lock_rotation = true
[node name="AlignReference" parent="." instance=ExtResource("3_e1tcn")]
disabled = true
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
transform = Transform3D(-4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0, 1, 0, 0, 0)
mesh = SubResource("CapsuleMesh_uovmo")

View File

@ -64,7 +64,7 @@ func add_floor_corner(position: Vector3):
floor_corner.position = position floor_corner.position = position
height_edge = wall_edge_scene.instantiate() height_edge = wall_edge_scene.instantiate()
height_edge.transform = corners_to_edge_transform(position, position + Vector3.UP * room.room_ceiling.global_position.y) height_edge.align_to_corners(position, position + Vector3.UP * room.room_ceiling.global_position.y)
floor_corner.get_node("Clickable").on_grab_down.connect(func(event): floor_corner.get_node("Clickable").on_grab_down.connect(func(event):
if !is_active() || moving != null: if !is_active() || moving != null:
@ -86,7 +86,7 @@ func add_floor_corner(position: Vector3):
moving.position = new_position moving.position = new_position
height_edge.transform = corners_to_edge_transform(new_position, new_position + Vector3.UP * room.room_ceiling.global_position.y) height_edge.align_to_corners(new_position, new_position + Vector3.UP * room.room_ceiling.global_position.y)
room.get_corner(moving_index).position.x = new_position.x room.get_corner(moving_index).position.x = new_position.x
room.get_corner(moving_index).position.z = new_position.z room.get_corner(moving_index).position.z = new_position.z
@ -94,8 +94,8 @@ func add_floor_corner(position: Vector3):
if room.wall_edges.get_child_count() == 0: if room.wall_edges.get_child_count() == 0:
return return
room.get_edge(moving_index).transform = corners_to_edge_transform(new_position, room.get_corner(moving_index + 1).position) room.get_edge(moving_index).align_to_corners(new_position, room.get_corner(moving_index + 1).position)
room.get_edge(moving_index - 1).transform = corners_to_edge_transform(room.get_corner(moving_index - 1).position, new_position) room.get_edge(moving_index - 1).align_to_corners(room.get_corner(moving_index - 1).position, new_position)
) )
floor_corner.get_node("Clickable").on_grab_up.connect(func(_event): floor_corner.get_node("Clickable").on_grab_up.connect(func(_event):
@ -134,7 +134,7 @@ func add_height_corner(position: Vector3):
return return
room.room_ceiling.position.y = new_position.y room.room_ceiling.position.y = new_position.y
height_edge.transform = corners_to_edge_transform(floor_corner.global_position, height_corner.global_position) height_edge.align_to_corners(floor_corner.global_position, height_corner.global_position)
) )
@ -175,9 +175,8 @@ func add_corner(position: Vector3, index: int = -1):
if room.wall_edges.get_child_count() == 0: if room.wall_edges.get_child_count() == 0:
return return
var edge_transform = corners_to_edge_transform(room.get_corner(moving_index - 1).position, room.get_corner(moving_index + 1).position) room.get_edge(moving_index).align_to_corners(room.get_corner(moving_index - 1).position, room.get_corner(moving_index + 1).position)
room.get_edge(moving_index).transform = edge_transform room.get_edge(moving_index - 1).transform = room.get_edge(moving_index).transform
room.get_edge(moving_index - 1).transform = edge_transform
return return
@ -191,8 +190,8 @@ func add_corner(position: Vector3, index: int = -1):
if room.wall_edges.get_child_count() == 0: if room.wall_edges.get_child_count() == 0:
return return
room.get_edge(moving_index).transform = corners_to_edge_transform(new_position, room.get_corner(moving_index + 1).position) room.get_edge(moving_index).align_to_corners(new_position, room.get_corner(moving_index + 1).position)
room.get_edge(moving_index - 1).transform = corners_to_edge_transform(room.get_corner(moving_index - 1).position, new_position) room.get_edge(moving_index - 1).align_to_corners(room.get_corner(moving_index - 1).position, new_position)
) )
corner.get_node("Clickable").on_grab_up.connect(func(_event): corner.get_node("Clickable").on_grab_up.connect(func(_event):
@ -208,21 +207,20 @@ func add_corner(position: Vector3, index: int = -1):
room.wall_corners.move_child(corner, index) room.wall_corners.move_child(corner, index)
var num_corners = room.wall_corners.get_child_count() var num_corners = room.wall_corners.get_child_count()
var edge
if num_corners > 1: if num_corners > 1:
edge = add_edge(position, room.get_corner(index + 1).position, index) add_edge(position, room.get_corner(index + 1).position, index)
if num_corners > 2: if num_corners > 2:
if num_corners != room.wall_edges.get_child_count(): if num_corners != room.wall_edges.get_child_count():
add_edge(room.get_corner(-2).position, room.get_corner(-1).position, -2) add_edge(room.get_corner(-2).position, room.get_corner(-1).position, -2)
else: else:
room.get_edge(index - 1).transform = corners_to_edge_transform(room.get_corner(index - 1).position, position) room.get_edge(index - 1).align_to_corners(room.get_corner(index - 1).position, position)
func add_edge(from_pos: Vector3, to_pos: Vector3, index: int = -1): func add_edge(from_pos: Vector3, to_pos: Vector3, index: int = -1):
var edge: StaticBody3D = wall_edge_scene.instantiate() var edge: StaticBody3D = wall_edge_scene.instantiate()
edge.transform = corners_to_edge_transform(from_pos, to_pos) edge.align_to_corners(from_pos, to_pos)
edge.get_node("Clickable").on_press_down.connect(func(event): edge.get_node("Clickable").on_press_down.connect(func(event):
var point = event.ray.get_collision_point() var point = event.ray.get_collision_point()
@ -234,18 +232,3 @@ func add_edge(from_pos: Vector3, to_pos: Vector3, index: int = -1):
room.wall_edges.add_child(edge) room.wall_edges.add_child(edge)
room.wall_edges.move_child(edge, index) room.wall_edges.move_child(edge, index)
return edge return edge
func corners_to_edge_transform(from_pos: Vector3, to_pos: Vector3) -> Transform3D:
var diff = to_pos - from_pos
var direction = diff.normalized()
var tangent = Vector3(direction.z, 0, -direction.x).normalized()
if tangent == Vector3.ZERO:
tangent = Vector3(1, 0, 0)
var edge_position = from_pos + diff / 2
var edge_basis = Basis(tangent, diff, tangent.cross(direction))
var edge_transform = Transform3D(edge_basis, edge_position)
return edge_transform

View File

@ -0,0 +1,16 @@
extends StaticBody3D
func align_to_corners(from_pos: Vector3, to_pos: Vector3):
var diff = to_pos - from_pos
var direction = diff.normalized()
var tangent = Vector3(direction.z, 0, -direction.x).normalized()
if tangent == Vector3.ZERO:
tangent = Vector3(1, 0, 0)
var edge_position = from_pos + diff / 2
var edge_basis = Basis(tangent, diff, tangent.cross(direction))
transform = Transform3D(edge_basis, edge_position)

View File

@ -1,5 +1,6 @@
[gd_scene load_steps=5 format=3 uid="uid://dlj5chj7ndgua"] [gd_scene load_steps=6 format=3 uid="uid://dlj5chj7ndgua"]
[ext_resource type="Script" path="res://content/system/house/room/wall_edge.gd" id="1_0c5rj"]
[ext_resource type="Material" uid="uid://j12e5wwthtaa" path="res://content/system/house/room/edge.tres" id="1_hs3tw"] [ext_resource type="Material" uid="uid://j12e5wwthtaa" path="res://content/system/house/room/edge.tres" id="1_hs3tw"]
[ext_resource type="Script" path="res://content/functions/clickable.gd" id="2_cfvx2"] [ext_resource type="Script" path="res://content/functions/clickable.gd" id="2_cfvx2"]
@ -13,6 +14,7 @@ radius = 0.04
height = 1.0 height = 1.0
[node name="StaticBody3D" type="StaticBody3D"] [node name="StaticBody3D" type="StaticBody3D"]
script = ExtResource("1_0c5rj")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."] [node name="MeshInstance3D" type="MeshInstance3D" parent="."]
mesh = SubResource("CapsuleMesh_a2dct") mesh = SubResource("CapsuleMesh_a2dct")

View File

@ -10,6 +10,8 @@ func _ready():
for child in children: for child in children:
child.visible = true child.visible = true
if tabs.selected != null && tabs.selected.get_index() == child.get_index():
continue
remove_child(child) remove_child(child)
tabs.on_select.connect(func(index): tabs.on_select.connect(func(index):

View File

@ -187,7 +187,7 @@ shape = SubResource("ConvexPolygonShape3D_mgnm0")
[node name="Tabs" type="Node3D" parent="AnimationContainer" node_paths=PackedStringArray("initial_selected")] [node name="Tabs" type="Node3D" parent="AnimationContainer" node_paths=PackedStringArray("initial_selected")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.06, 0, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.06, 0, 0)
script = ExtResource("4_eavfx") script = ExtResource("4_eavfx")
initial_selected = NodePath("") initial_selected = NodePath("View")
[node name="View" parent="AnimationContainer/Tabs" instance=ExtResource("5_w4i01")] [node name="View" parent="AnimationContainer/Tabs" instance=ExtResource("5_w4i01")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.03) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0, 0.03)

View File

@ -21,8 +21,9 @@ mesh = SubResource("BoxMesh_e37nn")
[node name="Interface" type="Node3D" parent="."] [node name="Interface" type="Node3D" parent="."]
[node name="Tabs3D" type="Node3D" parent="Interface"] [node name="Tabs3D" type="Node3D" parent="Interface" node_paths=PackedStringArray("initial_selected")]
script = ExtResource("5_ddrep") script = ExtResource("5_ddrep")
initial_selected = NodePath("Overview")
[node name="Overview" parent="Interface/Tabs3D" instance=ExtResource("4_cghmp")] [node name="Overview" parent="Interface/Tabs3D" instance=ExtResource("4_cghmp")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.03, 0, -0.02) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.03, 0, -0.02)

View File

@ -0,0 +1,31 @@
extends Node3D
@onready var edit_button = $EditButton
@onready var fix_button = $FixButton
var active = false:
set(value):
if value:
edit_button.label = "save"
fix_button.disabled = true
fix_button.visible = false
else:
edit_button.label = "edit"
fix_button.disabled = false
fix_button.visible = true
active = value
func _ready():
edit_button.on_button_down.connect(func():
if active:
House.body.save_reference()
else:
House.body.edit_reference()
active = !active
)
fix_button.on_button_down.connect(func():
House.body.fix_reference()
active = true
)

View File

@ -1,15 +1,17 @@
[gd_scene load_steps=2 format=3 uid="uid://dd71loi64gnmp"] [gd_scene load_steps=3 format=3 uid="uid://dd71loi64gnmp"]
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_fteh8"] [ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_fteh8"]
[ext_resource type="Script" path="res://content/ui/menu/room/views/overview.gd" id="1_jesad"]
[node name="Overview" type="Node3D"] [node name="Overview" type="Node3D"]
script = ExtResource("1_jesad")
[node name="Button2" parent="." instance=ExtResource("1_fteh8")] [node name="EditButton" parent="." instance=ExtResource("1_fteh8")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.04, 0, 0.07) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.04, 0, 0.07)
label = "add" label = "edit"
icon = true icon = true
[node name="Button3" parent="." instance=ExtResource("1_fteh8")] [node name="FixButton" parent="." instance=ExtResource("1_fteh8")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.1, 0, 0.07) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.1, 0, 0.07)
label = "healing" label = "healing"
icon = true icon = true

View File

@ -49,6 +49,9 @@ func load():
var json_text = save_file.get_line() var json_text = save_file.get_line()
var save_data = JSON.parse_string(json_text) var save_data = JSON.parse_string(json_text)
if save_data == null:
return
if save_data.has("version") == false: if save_data.has("version") == false:
save() save()
return return