add possibility to configure height
This commit is contained in:
parent
d25017192d
commit
eab54b5850
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,6 +1,7 @@
|
||||||
# Godot 4+ specific ignores
|
# Godot 4+ specific ignores
|
||||||
.godot/
|
.godot/
|
||||||
android/build/
|
android/build/
|
||||||
|
builds/
|
||||||
|
|
||||||
# Godot-specific ignores
|
# Godot-specific ignores
|
||||||
.import/
|
.import/
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:e54002ccb9b04b9b4fb4642cc3b5fd6512f910e65ecb52e41c117a2345d1d22b
|
oid sha256:b117dc5a7537a60ff341010636802131c9aa3b80982130e63d5d94902c002d07
|
||||||
size 17810864
|
size 13505995
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
version https://git-lfs.github.com/spec/v1
|
||||||
oid sha256:68e2b9d5e723a2009f341e45e2968893dd2a1dd5077fe1d9ba970f01d0d75e02
|
oid sha256:9738010a57d2157a53e4f537afbcfb50dd28e9de40bae510621d0ea8c94c5844
|
||||||
size 56989
|
size 51682
|
||||||
|
|
|
@ -1,172 +1,21 @@
|
||||||
extends Node3D
|
extends Node3D
|
||||||
|
|
||||||
const wall_corner_scene = preload("./wall_corner.tscn")
|
@onready var wall_corners = $Ceiling/WallCorners
|
||||||
const wall_edge_scene = preload("./wall_edge.tscn")
|
@onready var wall_edges = $Ceiling/WallEdges
|
||||||
|
|
||||||
@onready var wall_corners = $WallCorners
|
|
||||||
@onready var wall_edges = $WallEdges
|
|
||||||
@onready var wall_mesh = $WallMesh
|
@onready var wall_mesh = $WallMesh
|
||||||
@onready var wall_collisions = $WallCollisions
|
@onready var wall_collisions = $WallCollisions
|
||||||
|
|
||||||
@onready var ground = $Ground/Clickable
|
@onready var room_floor = $Floor
|
||||||
|
@onready var room_ceiling = $Ceiling
|
||||||
|
|
||||||
var moving = null
|
@onready var state_machine = $StateMachine
|
||||||
var editable := false:
|
|
||||||
|
var editable: bool = false:
|
||||||
set(value):
|
set(value):
|
||||||
if value == editable:
|
|
||||||
return
|
|
||||||
|
|
||||||
editable = value
|
|
||||||
if value:
|
if value:
|
||||||
_start_edit_mode()
|
state_machine.change_to("Edit")
|
||||||
else:
|
else:
|
||||||
_end_edit_mode()
|
state_machine.change_to("View")
|
||||||
var ground_plane = Plane(Vector3.UP, Vector3.ZERO)
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
ground.on_click.connect(func(event):
|
|
||||||
if !editable:
|
|
||||||
return
|
|
||||||
|
|
||||||
add_corner(event.ray.get_collision_point())
|
|
||||||
)
|
|
||||||
|
|
||||||
func _start_edit_mode():
|
|
||||||
wall_corners.visible = true
|
|
||||||
wall_edges.visible = true
|
|
||||||
wall_mesh.visible = false
|
|
||||||
wall_mesh.mesh = null
|
|
||||||
|
|
||||||
for old_coll in wall_collisions.get_children():
|
|
||||||
old_coll.queue_free()
|
|
||||||
|
|
||||||
func _end_edit_mode():
|
|
||||||
wall_corners.visible = false
|
|
||||||
wall_edges.visible = false
|
|
||||||
wall_mesh.mesh = generate_mesh()
|
|
||||||
|
|
||||||
if wall_mesh.mesh == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
var collisions = generate_collision(wall_mesh.mesh)
|
|
||||||
|
|
||||||
for collision in collisions:
|
|
||||||
var static_body = StaticBody3D.new()
|
|
||||||
static_body.set_collision_layer_value(4, true)
|
|
||||||
static_body.set_collision_layer_value(5, true)
|
|
||||||
static_body.collision_mask = 0
|
|
||||||
static_body.add_child(collision)
|
|
||||||
wall_collisions.add_child(static_body)
|
|
||||||
|
|
||||||
wall_mesh.visible = true
|
|
||||||
|
|
||||||
func generate_mesh():
|
|
||||||
var corner_count = wall_corners.get_child_count()
|
|
||||||
|
|
||||||
if corner_count < 3:
|
|
||||||
return
|
|
||||||
|
|
||||||
var st = SurfaceTool.new()
|
|
||||||
var wall_up = Vector3.UP * 3
|
|
||||||
|
|
||||||
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
|
||||||
|
|
||||||
for i in range(corner_count):
|
|
||||||
var corner = get_corner(i)
|
|
||||||
|
|
||||||
st.add_vertex(corner.position)
|
|
||||||
st.add_vertex(corner.position + wall_up)
|
|
||||||
|
|
||||||
var first_corner = get_corner(0)
|
|
||||||
|
|
||||||
st.add_vertex(first_corner.position)
|
|
||||||
st.add_vertex(first_corner.position + wall_up)
|
|
||||||
|
|
||||||
st.index()
|
|
||||||
st.generate_normals()
|
|
||||||
st.generate_tangents()
|
|
||||||
var mesh = st.commit()
|
|
||||||
|
|
||||||
return mesh
|
|
||||||
|
|
||||||
func generate_collision(mesh: ArrayMesh):
|
|
||||||
var corner_count = wall_corners.get_child_count()
|
|
||||||
|
|
||||||
if corner_count < 3:
|
|
||||||
return
|
|
||||||
|
|
||||||
var collision_shapes: Array[CollisionShape3D] = []
|
|
||||||
|
|
||||||
for i in range(corner_count):
|
|
||||||
var corner = get_corner(i)
|
|
||||||
var next_corner = get_corner(i + 1)
|
|
||||||
|
|
||||||
var shape = BoxShape3D.new()
|
|
||||||
shape.size = Vector3((next_corner.position - corner.position).length(), 3, 0.04)
|
|
||||||
|
|
||||||
var transform = Transform3D()
|
|
||||||
var back_vector = (corner.position - next_corner.position).cross(Vector3.UP).normalized() * shape.size.z / 2
|
|
||||||
|
|
||||||
transform.basis = Basis((next_corner.position - corner.position).normalized(), Vector3.UP, back_vector.normalized())
|
|
||||||
transform.origin = corner.position + (next_corner.position - corner.position) / 2 + back_vector + Vector3.UP * shape.size.y / 2
|
|
||||||
|
|
||||||
var collision_shape = CollisionShape3D.new()
|
|
||||||
|
|
||||||
collision_shape.shape = shape
|
|
||||||
collision_shape.transform = transform
|
|
||||||
|
|
||||||
collision_shapes.append(collision_shape)
|
|
||||||
|
|
||||||
return collision_shapes
|
|
||||||
|
|
||||||
func add_corner(position: Vector3):
|
|
||||||
var corner = wall_corner_scene.instantiate()
|
|
||||||
corner.position = position
|
|
||||||
|
|
||||||
corner.get_node("Clickable").on_grab_down.connect(func(event):
|
|
||||||
if !editable:
|
|
||||||
return
|
|
||||||
|
|
||||||
moving = event.target
|
|
||||||
)
|
|
||||||
|
|
||||||
corner.get_node("Clickable").on_grab_move.connect(func(event):
|
|
||||||
if moving == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
var direction = -event.ray.global_transform.basis.z
|
|
||||||
var new_position = ground_plane.intersects_ray(event.ray.global_position, direction)
|
|
||||||
|
|
||||||
if new_position == null:
|
|
||||||
return
|
|
||||||
|
|
||||||
moving.position = new_position
|
|
||||||
var moving_index = moving.get_index()
|
|
||||||
|
|
||||||
get_edge(moving_index).transform = corners_to_edge_transform(new_position, get_corner(moving_index + 1).position)
|
|
||||||
get_edge(moving_index - 1).transform = corners_to_edge_transform(get_corner(moving_index - 1).position, new_position)
|
|
||||||
)
|
|
||||||
|
|
||||||
corner.get_node("Clickable").on_grab_up.connect(func(_event):
|
|
||||||
moving = null
|
|
||||||
)
|
|
||||||
|
|
||||||
wall_corners.add_child(corner)
|
|
||||||
|
|
||||||
|
|
||||||
var num_corners = wall_corners.get_child_count()
|
|
||||||
var edge
|
|
||||||
|
|
||||||
if num_corners > 1:
|
|
||||||
edge = add_edge(wall_corners.get_child(num_corners - 2).position, position)
|
|
||||||
|
|
||||||
if num_corners > 2:
|
|
||||||
if num_corners != wall_edges.get_child_count():
|
|
||||||
add_edge(position, wall_corners.get_child(0).position)
|
|
||||||
else:
|
|
||||||
wall_edges.move_child(edge, num_corners - 2)
|
|
||||||
get_edge(-1).transform = corners_to_edge_transform(position, get_corner(0).position)
|
|
||||||
|
|
||||||
func get_corner(index: int) -> MeshInstance3D:
|
func get_corner(index: int) -> MeshInstance3D:
|
||||||
return wall_corners.get_child(index % wall_corners.get_child_count())
|
return wall_corners.get_child(index % wall_corners.get_child_count())
|
||||||
|
@ -175,22 +24,6 @@ func get_edge(index: int) -> MeshInstance3D:
|
||||||
return wall_edges.get_child(index % wall_edges.get_child_count())
|
return wall_edges.get_child(index % wall_edges.get_child_count())
|
||||||
|
|
||||||
|
|
||||||
func add_edge(from_pos: Vector3, to_pos: Vector3):
|
|
||||||
var edge: MeshInstance3D = wall_edge_scene.instantiate()
|
|
||||||
edge.transform = corners_to_edge_transform(from_pos, to_pos)
|
|
||||||
wall_edges.add_child(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 edge_position = from_pos + diff / 2
|
|
||||||
var edge_basis = Basis(Vector3.UP, diff, direction.cross(Vector3.UP))
|
|
||||||
|
|
||||||
var edge_transform = Transform3D(edge_basis, edge_position)
|
|
||||||
return edge_transform
|
|
||||||
|
|
||||||
func _save():
|
func _save():
|
||||||
return {
|
return {
|
||||||
"corners": wall_corners.get_children().map(func(corner): return corner.position),
|
"corners": wall_corners.get_children().map(func(corner): return corner.position),
|
||||||
|
@ -198,8 +31,11 @@ func _save():
|
||||||
|
|
||||||
func _load(data):
|
func _load(data):
|
||||||
await ready
|
await ready
|
||||||
|
return
|
||||||
|
|
||||||
|
state_machine.change_to("Edit")
|
||||||
|
|
||||||
for corner in data["corners"]:
|
for corner in data["corners"]:
|
||||||
add_corner(corner)
|
state_machine.current_state.add_corner(corner)
|
||||||
|
|
||||||
_end_edit_mode()
|
state_machine.change_to("View")
|
||||||
|
|
|
@ -1,42 +1,60 @@
|
||||||
[gd_scene load_steps=7 format=3 uid="uid://bswgmclohuqui"]
|
[gd_scene load_steps=10 format=3 uid="uid://bswgmclohuqui"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://content/system/room/room.gd" id="1_fccq0"]
|
[ext_resource type="Script" path="res://content/system/room/room.gd" id="1_fccq0"]
|
||||||
[ext_resource type="Script" path="res://content/functions/clickable.gd" id="1_ugebq"]
|
[ext_resource type="Script" path="res://content/functions/clickable.gd" id="1_ugebq"]
|
||||||
[ext_resource type="Material" uid="uid://bbx6fv7jq50tr" path="res://content/system/room/walls.tres" id="3_al1ev"]
|
[ext_resource type="Material" uid="uid://bbx6fv7jq50tr" path="res://content/system/room/walls.tres" id="3_al1ev"]
|
||||||
|
[ext_resource type="Script" path="res://lib/utils/state_machine/state_machine.gd" id="4_nbbo6"]
|
||||||
|
[ext_resource type="Script" path="res://content/system/room/states/view.gd" id="6_g066t"]
|
||||||
|
[ext_resource type="Script" path="res://content/system/room/states/edit.gd" id="7_ap14h"]
|
||||||
|
|
||||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_08sv0"]
|
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_08sv0"]
|
||||||
|
|
||||||
[sub_resource type="ArrayMesh" id="ArrayMesh_7dibq"]
|
[sub_resource type="ArrayMesh" id="ArrayMesh_7dibq"]
|
||||||
|
|
||||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ap613"]
|
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ap613"]
|
||||||
|
plane = Plane(0, -1, 0, 0)
|
||||||
|
|
||||||
[node name="Room" type="Node3D"]
|
[node name="Room" type="Node3D"]
|
||||||
script = ExtResource("1_fccq0")
|
script = ExtResource("1_fccq0")
|
||||||
|
|
||||||
[node name="Ground" type="StaticBody3D" parent="."]
|
[node name="Floor" type="StaticBody3D" parent="."]
|
||||||
collision_layer = 24
|
collision_layer = 24
|
||||||
collision_mask = 0
|
collision_mask = 0
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor"]
|
||||||
shape = SubResource("WorldBoundaryShape3D_08sv0")
|
shape = SubResource("WorldBoundaryShape3D_08sv0")
|
||||||
|
|
||||||
[node name="Clickable" type="Node" parent="Ground"]
|
[node name="Clickable" type="Node" parent="Floor"]
|
||||||
script = ExtResource("1_ugebq")
|
script = ExtResource("1_ugebq")
|
||||||
|
|
||||||
[node name="WallCorners" type="Node3D" parent="."]
|
|
||||||
|
|
||||||
[node name="WallEdges" type="Node3D" parent="."]
|
|
||||||
|
|
||||||
[node name="WallMesh" type="MeshInstance3D" parent="."]
|
[node name="WallMesh" type="MeshInstance3D" parent="."]
|
||||||
material_override = ExtResource("3_al1ev")
|
material_override = ExtResource("3_al1ev")
|
||||||
mesh = SubResource("ArrayMesh_7dibq")
|
mesh = SubResource("ArrayMesh_7dibq")
|
||||||
|
|
||||||
[node name="WallCollisions" type="Node3D" parent="."]
|
[node name="WallCollisions" type="Node3D" parent="."]
|
||||||
|
|
||||||
[node name="Celing" type="StaticBody3D" parent="."]
|
[node name="Ceiling" type="StaticBody3D" parent="."]
|
||||||
transform = Transform3D(-1, 8.74228e-08, 0, -8.74228e-08, -1, 0, 0, 0, 1, 0, 3.07, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0)
|
||||||
collision_layer = 0
|
collision_layer = 24
|
||||||
collision_mask = 0
|
collision_mask = 0
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Celing"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ceiling"]
|
||||||
shape = SubResource("WorldBoundaryShape3D_ap613")
|
shape = SubResource("WorldBoundaryShape3D_ap613")
|
||||||
|
disabled = true
|
||||||
|
|
||||||
|
[node name="Clickable" type="Node" parent="Ceiling"]
|
||||||
|
script = ExtResource("1_ugebq")
|
||||||
|
|
||||||
|
[node name="WallCorners" type="Node3D" parent="Ceiling"]
|
||||||
|
|
||||||
|
[node name="WallEdges" type="Node3D" parent="Ceiling"]
|
||||||
|
|
||||||
|
[node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("current_state")]
|
||||||
|
script = ExtResource("4_nbbo6")
|
||||||
|
current_state = NodePath("View")
|
||||||
|
|
||||||
|
[node name="View" type="Node" parent="StateMachine"]
|
||||||
|
script = ExtResource("6_g066t")
|
||||||
|
|
||||||
|
[node name="Edit" type="Node" parent="StateMachine"]
|
||||||
|
script = ExtResource("7_ap14h")
|
||||||
|
|
213
content/system/room/states/edit.gd
Normal file
213
content/system/room/states/edit.gd
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
extends RoomState
|
||||||
|
|
||||||
|
const wall_corner_scene = preload("../wall_corner.tscn")
|
||||||
|
const wall_edge_scene = preload("../wall_edge.tscn")
|
||||||
|
const RoomState = preload("./room_state.gd")
|
||||||
|
|
||||||
|
var moving = null
|
||||||
|
var floor_corner: StaticBody3D = null
|
||||||
|
var height_corner: StaticBody3D = null
|
||||||
|
var height_edge: MeshInstance3D = null
|
||||||
|
|
||||||
|
func _on_enter():
|
||||||
|
room.wall_corners.visible = true
|
||||||
|
room.wall_edges.visible = true
|
||||||
|
|
||||||
|
if floor_corner != null:
|
||||||
|
floor_corner.visible = true
|
||||||
|
height_corner.visible = true
|
||||||
|
height_edge.visible = true
|
||||||
|
|
||||||
|
room.room_ceiling.get_node("Clickable").on_click.connect(_on_click_ceiling)
|
||||||
|
room.room_floor.get_node("Clickable").on_click.connect(_on_click_floor)
|
||||||
|
|
||||||
|
func _on_leave():
|
||||||
|
room.wall_corners.visible = false
|
||||||
|
room.wall_edges.visible = false
|
||||||
|
|
||||||
|
if floor_corner != null:
|
||||||
|
floor_corner.visible = false
|
||||||
|
height_corner.visible = false
|
||||||
|
height_edge.visible = false
|
||||||
|
|
||||||
|
room.room_ceiling.get_node("Clickable").on_click.disconnect(_on_click_ceiling)
|
||||||
|
room.room_floor.get_node("Clickable").on_click.disconnect(_on_click_floor)
|
||||||
|
|
||||||
|
func _on_click_floor(event):
|
||||||
|
if floor_corner != null && height_corner != null:
|
||||||
|
return
|
||||||
|
|
||||||
|
add_floor_corner(event.ray.get_collision_point())
|
||||||
|
add_height_corner(event.ray.get_collision_point())
|
||||||
|
room.room_ceiling.get_node("CollisionShape3D").disabled = false
|
||||||
|
|
||||||
|
func _on_click_ceiling(event):
|
||||||
|
if floor_corner == null || height_corner == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var pos = event.ray.get_collision_point()
|
||||||
|
pos.y = 0
|
||||||
|
|
||||||
|
add_corner(pos)
|
||||||
|
|
||||||
|
func add_floor_corner(position: Vector3):
|
||||||
|
floor_corner = wall_corner_scene.instantiate()
|
||||||
|
floor_corner.position = position
|
||||||
|
|
||||||
|
height_edge = wall_edge_scene.instantiate()
|
||||||
|
height_edge.transform = corners_to_edge_transform(position, position + Vector3.UP * room.room_ceiling.global_position.y)
|
||||||
|
|
||||||
|
floor_corner.get_node("Clickable").on_grab_down.connect(func(event):
|
||||||
|
if !is_active():
|
||||||
|
return
|
||||||
|
|
||||||
|
moving = event.target
|
||||||
|
)
|
||||||
|
|
||||||
|
floor_corner.get_node("Clickable").on_grab_move.connect(func(event):
|
||||||
|
if moving == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var direction = -event.ray.global_transform.basis.z
|
||||||
|
var new_position = room.room_floor.get_node("CollisionShape3D").shape.plane.intersects_ray(event.ray.global_position, direction)
|
||||||
|
|
||||||
|
if new_position == null:
|
||||||
|
# mark for deletion
|
||||||
|
return
|
||||||
|
|
||||||
|
moving.position = new_position
|
||||||
|
var moving_index = height_corner.get_index()
|
||||||
|
|
||||||
|
height_edge.transform = corners_to_edge_transform(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.z = new_position.z
|
||||||
|
|
||||||
|
if room.wall_edges.get_child_count() == 0:
|
||||||
|
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 - 1).transform = corners_to_edge_transform(room.get_corner(moving_index - 1).position, new_position)
|
||||||
|
)
|
||||||
|
|
||||||
|
floor_corner.get_node("Clickable").on_grab_up.connect(func(_event):
|
||||||
|
moving = null
|
||||||
|
)
|
||||||
|
|
||||||
|
room.add_child(floor_corner)
|
||||||
|
room.add_child(height_edge)
|
||||||
|
|
||||||
|
func add_height_corner(position: Vector3):
|
||||||
|
height_corner = wall_corner_scene.instantiate()
|
||||||
|
height_corner.position.x = position.x
|
||||||
|
height_corner.position.z = position.z
|
||||||
|
|
||||||
|
height_corner.get_node("Clickable").on_grab_down.connect(func(event):
|
||||||
|
if !is_active():
|
||||||
|
return
|
||||||
|
|
||||||
|
moving = event.target
|
||||||
|
)
|
||||||
|
|
||||||
|
height_corner.get_node("Clickable").on_grab_move.connect(func(event):
|
||||||
|
if moving == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var direction = -event.ray.global_transform.basis.z
|
||||||
|
var plane_direction = direction
|
||||||
|
plane_direction.y = 0
|
||||||
|
plane_direction = plane_direction.normalized() * -1
|
||||||
|
|
||||||
|
var plane = Plane(plane_direction, moving.position)
|
||||||
|
|
||||||
|
var new_position = plane.intersects_ray(event.ray.global_position, direction)
|
||||||
|
|
||||||
|
if new_position == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
room.room_ceiling.position.y = new_position.y
|
||||||
|
height_edge.transform = corners_to_edge_transform(floor_corner.global_position, height_corner.global_position)
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
height_corner.get_node("Clickable").on_grab_up.connect(func(_event):
|
||||||
|
moving = null
|
||||||
|
)
|
||||||
|
|
||||||
|
room.wall_corners.add_child(height_corner)
|
||||||
|
|
||||||
|
func add_corner(position: Vector3):
|
||||||
|
var corner = wall_corner_scene.instantiate()
|
||||||
|
corner.position.x = position.x
|
||||||
|
corner.position.z = position.z
|
||||||
|
|
||||||
|
corner.get_node("Clickable").on_grab_down.connect(func(event):
|
||||||
|
if !is_active():
|
||||||
|
return
|
||||||
|
|
||||||
|
moving = event.target
|
||||||
|
)
|
||||||
|
|
||||||
|
corner.get_node("Clickable").on_grab_move.connect(func(event):
|
||||||
|
if moving == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var direction = -event.ray.global_transform.basis.z
|
||||||
|
var ceiling_plane = Plane(Vector3.DOWN, room.room_ceiling.global_position)
|
||||||
|
var new_position = ceiling_plane.intersects_ray(event.ray.global_position, direction)
|
||||||
|
|
||||||
|
if new_position == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
new_position.y = 0
|
||||||
|
|
||||||
|
moving.position = new_position
|
||||||
|
var moving_index = moving.get_index()
|
||||||
|
|
||||||
|
if room.wall_edges.get_child_count() == 0:
|
||||||
|
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 - 1).transform = corners_to_edge_transform(room.get_corner(moving_index - 1).position, new_position)
|
||||||
|
)
|
||||||
|
|
||||||
|
corner.get_node("Clickable").on_grab_up.connect(func(_event):
|
||||||
|
moving = null
|
||||||
|
)
|
||||||
|
|
||||||
|
room.wall_corners.add_child(corner)
|
||||||
|
|
||||||
|
|
||||||
|
var num_corners = room.wall_corners.get_child_count()
|
||||||
|
var edge
|
||||||
|
|
||||||
|
if num_corners > 1:
|
||||||
|
edge = add_edge(room.wall_corners.get_child(num_corners - 2).position, position)
|
||||||
|
|
||||||
|
if num_corners > 2:
|
||||||
|
if num_corners != room.wall_edges.get_child_count():
|
||||||
|
add_edge(position, room.wall_corners.get_child(0).position)
|
||||||
|
else:
|
||||||
|
room.wall_edges.move_child(edge, num_corners - 2)
|
||||||
|
room.get_edge(-1).transform = corners_to_edge_transform(position, room.get_corner(0).position)
|
||||||
|
|
||||||
|
func add_edge(from_pos: Vector3, to_pos: Vector3):
|
||||||
|
var edge: MeshInstance3D = wall_edge_scene.instantiate()
|
||||||
|
edge.transform = corners_to_edge_transform(from_pos, to_pos)
|
||||||
|
room.wall_edges.add_child(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
|
7
content/system/room/states/room_state.gd
Normal file
7
content/system/room/states/room_state.gd
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
extends State
|
||||||
|
const Room = preload("res://content/system/room/room.gd")
|
||||||
|
|
||||||
|
var room: Room
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
room = get_parent().get_parent()
|
86
content/system/room/states/view.gd
Normal file
86
content/system/room/states/view.gd
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
extends RoomState
|
||||||
|
|
||||||
|
const RoomState = preload("./room_state.gd")
|
||||||
|
|
||||||
|
var room_height = 3
|
||||||
|
var corner_count = 0
|
||||||
|
|
||||||
|
func _on_enter():
|
||||||
|
corner_count = room.wall_corners.get_child_count()
|
||||||
|
|
||||||
|
if corner_count < 3:
|
||||||
|
return
|
||||||
|
|
||||||
|
room_height = room.get_corner(0).global_position.y
|
||||||
|
|
||||||
|
room.wall_mesh.mesh = generate_mesh()
|
||||||
|
|
||||||
|
if room.wall_mesh.mesh == null:
|
||||||
|
return
|
||||||
|
|
||||||
|
var collisions = generate_collision()
|
||||||
|
|
||||||
|
for collision in collisions:
|
||||||
|
var static_body = StaticBody3D.new()
|
||||||
|
static_body.set_collision_layer_value(4, true)
|
||||||
|
static_body.set_collision_layer_value(5, true)
|
||||||
|
static_body.collision_mask = 0
|
||||||
|
static_body.add_child(collision)
|
||||||
|
room.wall_collisions.add_child(static_body)
|
||||||
|
|
||||||
|
room.wall_mesh.visible = true
|
||||||
|
|
||||||
|
func _on_leave():
|
||||||
|
room.wall_mesh.mesh = null
|
||||||
|
|
||||||
|
for collision in room.wall_collisions.get_children():
|
||||||
|
collision.queue_free()
|
||||||
|
|
||||||
|
func generate_mesh():
|
||||||
|
var st = SurfaceTool.new()
|
||||||
|
var wall_up = Vector3.UP * room_height
|
||||||
|
|
||||||
|
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
||||||
|
|
||||||
|
for i in range(corner_count):
|
||||||
|
var corner = room.get_corner(i)
|
||||||
|
|
||||||
|
st.add_vertex(corner.position)
|
||||||
|
st.add_vertex(corner.position + wall_up)
|
||||||
|
|
||||||
|
var first_corner = room.get_corner(0)
|
||||||
|
|
||||||
|
st.add_vertex(first_corner.position)
|
||||||
|
st.add_vertex(first_corner.position + wall_up)
|
||||||
|
|
||||||
|
st.index()
|
||||||
|
st.generate_normals()
|
||||||
|
st.generate_tangents()
|
||||||
|
var mesh = st.commit()
|
||||||
|
|
||||||
|
return mesh
|
||||||
|
|
||||||
|
func generate_collision():
|
||||||
|
var collision_shapes: Array[CollisionShape3D] = []
|
||||||
|
|
||||||
|
for i in range(corner_count):
|
||||||
|
var corner = room.get_corner(i)
|
||||||
|
var next_corner = room.get_corner(i + 1)
|
||||||
|
|
||||||
|
var shape = BoxShape3D.new()
|
||||||
|
shape.size = Vector3((next_corner.position - corner.position).length(), room_height, 0.04)
|
||||||
|
|
||||||
|
var transform = Transform3D()
|
||||||
|
var back_vector = (corner.position - next_corner.position).cross(Vector3.UP).normalized() * shape.size.z / 2
|
||||||
|
|
||||||
|
transform.basis = Basis((next_corner.position - corner.position).normalized(), Vector3.UP, back_vector.normalized())
|
||||||
|
transform.origin = corner.position + (next_corner.position - corner.position) / 2 + back_vector + Vector3.UP * shape.size.y / 2
|
||||||
|
|
||||||
|
var collision_shape = CollisionShape3D.new()
|
||||||
|
|
||||||
|
collision_shape.shape = shape
|
||||||
|
collision_shape.transform = transform
|
||||||
|
|
||||||
|
collision_shapes.append(collision_shape)
|
||||||
|
|
||||||
|
return collision_shapes
|
|
@ -248,7 +248,7 @@ architectures/armeabi-v7a=false
|
||||||
architectures/arm64-v8a=true
|
architectures/arm64-v8a=true
|
||||||
architectures/x86=false
|
architectures/x86=false
|
||||||
architectures/x86_64=false
|
architectures/x86_64=false
|
||||||
version/code=6
|
version/code=7
|
||||||
version/name="v0.2.0"
|
version/name="v0.2.0"
|
||||||
package/unique_name="de.nitwel.$genname"
|
package/unique_name="de.nitwel.$genname"
|
||||||
package/name="Immersive Home"
|
package/name="Immersive Home"
|
||||||
|
|
13
lib/utils/state_machine/state.gd
Normal file
13
lib/utils/state_machine/state.gd
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
extends Node
|
||||||
|
class_name State
|
||||||
|
|
||||||
|
var state_machine: StateMachine
|
||||||
|
|
||||||
|
func is_active():
|
||||||
|
return state_machine.current_state == self
|
||||||
|
|
||||||
|
func _on_enter():
|
||||||
|
pass
|
||||||
|
|
||||||
|
func _on_leave():
|
||||||
|
pass
|
32
lib/utils/state_machine/state_machine.gd
Normal file
32
lib/utils/state_machine/state_machine.gd
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
class_name StateMachine
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
signal changed(state_name: String, old_state: String)
|
||||||
|
|
||||||
|
@export var current_state: Node
|
||||||
|
var states: Dictionary = {}
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
for state in get_children():
|
||||||
|
states[state.get_name()] = state
|
||||||
|
state.state_machine = self
|
||||||
|
|
||||||
|
if state != current_state:
|
||||||
|
remove_child(state)
|
||||||
|
|
||||||
|
await get_parent().ready
|
||||||
|
|
||||||
|
current_state._on_enter()
|
||||||
|
|
||||||
|
func change_to(new_state: String) -> void:
|
||||||
|
if states.has(new_state) == false:
|
||||||
|
return
|
||||||
|
|
||||||
|
var old_state = current_state.get_name()
|
||||||
|
|
||||||
|
current_state._on_leave()
|
||||||
|
remove_child(current_state)
|
||||||
|
current_state = states[new_state]
|
||||||
|
add_child(current_state)
|
||||||
|
current_state._on_enter()
|
||||||
|
changed.emit(new_state, old_state)
|
Loading…
Reference in New Issue
Block a user