From 228e32495c4c51aa389d06e7701a504b1a3019cb Mon Sep 17 00:00:00 2001 From: Nitwel Date: Wed, 20 Dec 2023 22:19:43 +0100 Subject: [PATCH] implement mesh generation and add basic room overview --- content/main.gd | 11 ++- content/main.tscn | 5 +- content/system/house/house.gd | 20 +++-- content/system/house/room/room.gd | 6 ++ content/system/house/room/room.tscn | 3 + content/system/house/room/states/view.gd | 45 ++++++++++- content/system/house/room/walls.tres | 4 +- content/ui/menu/room/room_menu.gd | 99 ++++++++++++++++++++++-- content/ui/menu/room/room_menu.tscn | 18 ++++- 9 files changed, 188 insertions(+), 23 deletions(-) diff --git a/content/main.gd b/content/main.gd index 855ca82..836fc9a 100644 --- a/content/main.gd +++ b/content/main.gd @@ -7,16 +7,14 @@ var sky_passthrough = preload("res://assets/materials/sky_passthrough.material") @onready var camera: XRCamera3D = $XROrigin3D/XRCamera3D @onready var controller_left = $XROrigin3D/XRControllerLeft @onready var controller_right = $XROrigin3D/XRControllerRight -@onready var house = $House func _ready(): # In case we're running on the headset, use the passthrough sky if OS.get_name() == "Android": # OS.request_permissions() environment.environment.sky.set_material(sky_passthrough) - house.visible = false else: - house.visible = true + RenderingServer.set_debug_generate_wireframes(true) func _process(delta): if OS.get_name() != "Android": @@ -34,6 +32,11 @@ func _process(delta): camera.position += movement controller_left.position += movement controller_right.position += movement + +func _input(event): + if event is InputEventKey and Input.is_key_pressed(KEY_F10): + var vp = get_viewport() + vp.debug_draw = (vp.debug_draw + 1) % 5 func vector_key_mapping(key_positive_x: int, key_negative_x: int, key_positive_y: int, key_negative_y: int): @@ -54,4 +57,4 @@ func vector_key_mapping(key_positive_x: int, key_negative_x: int, key_positive_y if vec: vec = vec.normalized() - return vec \ No newline at end of file + return vec diff --git a/content/main.tscn b/content/main.tscn index 01c5320..08cfec9 100644 --- a/content/main.tscn +++ b/content/main.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=13 format=3 uid="uid://eecv28y6jxk4"] +[gd_scene load_steps=14 format=3 uid="uid://eecv28y6jxk4"] [ext_resource type="PackedScene" uid="uid://clc5dre31iskm" path="res://addons/godot-xr-tools/xr/start_xr.tscn" id="1_i4c04"] [ext_resource type="Script" path="res://content/main.gd" id="1_uvrd4"] @@ -8,6 +8,7 @@ [ext_resource type="PackedScene" uid="uid://ctltchlf2j2r4" path="res://addons/xr-simulator/XRSimulator.tscn" id="5_3qc8g"] [ext_resource type="Material" uid="uid://bf5ina366dwm6" path="res://assets/materials/sky.material" id="5_wgwf8"] [ext_resource type="PackedScene" uid="uid://lrehk38exd5n" path="res://content/system/keyboard/keyboard.tscn" id="9_e5n3p"] +[ext_resource type="PackedScene" uid="uid://cbemihbxkd4ll" path="res://content/system/house/house.tscn" id="9_np6mw"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m58yb"] ao_enabled = true @@ -75,4 +76,6 @@ transform = Transform3D(0.499999, -6.98142e-12, 0, 4.74065e-12, 0.5, -2.27374e-1 [node name="Rooms" type="Node3D" parent="."] +[node name="House" parent="." instance=ExtResource("9_np6mw")] + [editable path="XROrigin3D/XRControllerLeft"] diff --git a/content/system/house/house.gd b/content/system/house/house.gd index 99aba60..991b3a8 100644 --- a/content/system/house/house.gd +++ b/content/system/house/house.gd @@ -21,16 +21,24 @@ func create_room(room_name: String, level: int) -> RoomType: return room -func edit_room(room_name: String): +func edit_room(room_name): + var room = find_room(room_name) + + if room == editing_room: + return + if editing_room != null: editing_room.editable = false editing_room = null + + if room != null: + room.editable = true + editing_room = room - var room = find_room(room_name) - room.editable = true - editing_room = room +func is_editiong(room_name): + return editing_room != null && editing_room.name == room_name -func find_room(room_name: String): +func find_room(room_name): for level in levels.get_children(): for room in level.get_children(): if room.name == room_name: @@ -45,7 +53,7 @@ func find_room_at(entity_position: Vector3): return null func get_level(level: int): - return levels.get_index(level) + return levels.get_child(level) func get_rooms(level: int): return get_level(level).get_children() diff --git a/content/system/house/room/room.gd b/content/system/house/room/room.gd index 5ed71f5..1cae35c 100644 --- a/content/system/house/room/room.gd +++ b/content/system/house/room/room.gd @@ -3,6 +3,7 @@ extends Node3D @onready var wall_corners = $Ceiling/WallCorners @onready var wall_edges = $Ceiling/WallEdges @onready var wall_mesh: MeshInstance3D = $WallMesh +@onready var ceiling_mesh: MeshInstance3D = $CeilingMesh @onready var wall_collisions = $WallCollisions @onready var room_floor = $Floor @@ -12,6 +13,8 @@ extends Node3D var editable: bool = false: set(value): + if !is_node_ready(): await ready + if value: state_machine.change_to("Edit") else: @@ -29,12 +32,15 @@ func has_point(point: Vector3) -> bool: func _save(): return { "corners": wall_corners.get_children().map(func(corner): return corner.position), + "name": name } func _load(data): await ready return + name = data["name"] + state_machine.change_to("Edit") for corner in data["corners"]: diff --git a/content/system/house/room/room.tscn b/content/system/house/room/room.tscn index 798df01..688e140 100644 --- a/content/system/house/room/room.tscn +++ b/content/system/house/room/room.tscn @@ -31,6 +31,9 @@ script = ExtResource("1_ugebq") material_override = ExtResource("3_al1ev") mesh = SubResource("ArrayMesh_7dibq") +[node name="CeilingMesh" type="MeshInstance3D" parent="."] +material_override = ExtResource("3_al1ev") + [node name="WallCollisions" type="Node3D" parent="."] [node name="Ceiling" type="StaticBody3D" parent="."] diff --git a/content/system/house/room/states/view.gd b/content/system/house/room/states/view.gd index 6db4e1a..6237580 100644 --- a/content/system/house/room/states/view.gd +++ b/content/system/house/room/states/view.gd @@ -17,6 +17,8 @@ func _on_enter(): if room.wall_mesh.mesh == null: return + + room.ceiling_mesh.mesh = generate_ceiling_mesh() var collisions = generate_collision() @@ -53,8 +55,6 @@ func generate_mesh(): st.add_vertex(first_corner.position) st.add_vertex(first_corner.position + wall_up) - # TODO: Implement Rust Binding for cdt algorithm to fill floor and ceiling - st.index() st.generate_normals() st.generate_tangents() @@ -62,6 +62,47 @@ func generate_mesh(): return mesh +func generate_ceiling_mesh(): + var points: PackedVector2Array = PackedVector2Array() + var edges: PackedInt32Array = PackedInt32Array() + var triangles: PackedInt32Array + + for i in range(corner_count): + var corner = room.get_corner(i) + points.append(Vector2(corner.position.x, corner.position.z)) + edges.append(i) + edges.append((i + 1) % corner_count) + + var cdt: ConstrainedTriangulation = ConstrainedTriangulation.new() + + cdt.init(true, true, 0.1) + + cdt.insert_vertices(points) + cdt.insert_edges(edges) + + cdt.erase_outer_triangles() + + points = cdt.get_all_vertices() + triangles = cdt.get_all_triangles() + + var st = SurfaceTool.new() + + st.begin(Mesh.PRIMITIVE_TRIANGLES) + + for i in range(points.size()): + st.add_vertex(Vector3(points[i].x, 0, points[i].y)) + + for i in range(triangles.size()): + st.add_index(triangles[i]) + + st.index() + st.generate_normals() + st.generate_tangents() + + var mesh = st.commit() + + return mesh + func generate_collision(): var collision_shapes: Array[CollisionShape3D] = [] diff --git a/content/system/house/room/walls.tres b/content/system/house/room/walls.tres index b0ebc48..c9a6a4d 100644 --- a/content/system/house/room/walls.tres +++ b/content/system/house/room/walls.tres @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fe7c098cfc9adadb447df0230eba8a81f1825dd3c0cf4e654ebf98ca2314c8cc -size 151 +oid sha256:935bcbcfaa2d5dca17ce3efea167357dca8b5ac05f49d5b322add9a84607b4f0 +size 158 diff --git a/content/ui/menu/room/room_menu.gd b/content/ui/menu/room/room_menu.gd index 667a027..775a149 100644 --- a/content/ui/menu/room/room_menu.gd +++ b/content/ui/menu/room/room_menu.gd @@ -6,6 +6,26 @@ const RoomType = preload("res://content/system/house/room/room.gd") const window_scene = preload("./window.tscn") @onready var background = $Background +@onready var add_room_button = $Interface/AddRoom +@onready var save_room_button = $Interface/SaveRoom +@onready var input = $Interface/Input +@onready var rooms_map = $Interface/Rooms + +var selected_room = null: + set(value): + selected_room = value + if value != null: + save_room_button.visible = true + else: + save_room_button.visible = false + +var edit_room = false: + set(value): + edit_room = value + if value: + save_room_button.label = "save" + else: + save_room_button.label = "edit" func _ready(): background.visible = false @@ -13,10 +33,79 @@ func _ready(): HomeApi.on_connect.connect(func(): var rooms = House.body.get_rooms(0) - for room in rooms: - var mesh = room.wall_mesh - - - + # for room in rooms: + # var mesh = room.wall_mesh ) + + add_room_button.on_button_down.connect(func(): + var room_name = input.text + House.body.create_room(room_name, 0) + selected_room = room_name + edit_room = true + add_room_button.visible = false + ) + + save_room_button.on_button_down.connect(func(): + if edit_room: + edit_room = false + add_room_button.visible = true + House.body.edit_room(null) + _generate_room_map() + else: + edit_room = true + House.body.edit_room(selected_room) + ) + +func _on_click(event: EventPointer): + if event.target.get_parent() == rooms_map: + var room_name = event.target.name + selected_room = room_name + edit_room = false + add_room_button.visible = false + House.body.edit_room(selected_room) + +func _generate_room_map(): + var rooms = House.body.get_rooms(0) + + var target_size = Vector2(0.3, 0.2) + + for old_room in rooms_map.get_children(): + old_room.queue_free() + + var current_min = Vector2(0, 0) + var current_max = Vector2(0, 0) + + for room in rooms: + var body = StaticBody3D.new() + + var mesh = room.ceiling_mesh.mesh + var mesh_instance = MeshInstance3D.new() + mesh_instance.mesh = mesh + mesh_instance.material_override = load("res://content/system/house/room/walls.tres") + body.add_child(mesh_instance) + + var collision_shape = CollisionShape3D.new() + collision_shape.shape = mesh.create_trimesh_shape() + body.add_child(collision_shape) + + rooms_map.add_child(body) + + if mesh.get_aabb().position.x < current_min.x: + current_min.x = mesh.get_aabb().position.x + + if mesh.get_aabb().position.z < current_min.y: + current_min.y = mesh.get_aabb().position.z + + if mesh.get_aabb().end.x > current_max.x: + current_max.x = mesh.get_aabb().end.x + + if mesh.get_aabb().end.z > current_max.y: + current_max.y = mesh.get_aabb().end.z + + var current_size = current_max - current_min + + var target_scale = target_size / current_size + var scale_value = max(target_scale.x, target_scale.y) + + rooms_map.scale = Vector3(scale_value, scale_value, scale_value) diff --git a/content/ui/menu/room/room_menu.tscn b/content/ui/menu/room/room_menu.tscn index 01c8224..32dc947 100644 --- a/content/ui/menu/room/room_menu.tscn +++ b/content/ui/menu/room/room_menu.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=5 format=3 uid="uid://c01gkeldvjwtr"] +[gd_scene load_steps=6 format=3 uid="uid://c01gkeldvjwtr"] [ext_resource type="Script" path="res://content/ui/menu/room/room_menu.gd" id="1_ch4jb"] [ext_resource type="Material" uid="uid://bujy3egn1oqac" path="res://assets/materials/pri-500.material" id="2_7m4yn"] [ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="4_cghmp"] +[ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="4_pbj71"] [sub_resource type="BoxMesh" id="BoxMesh_e37nn"] size = Vector3(0.3, 0.01, 0.3) @@ -18,9 +19,20 @@ mesh = SubResource("BoxMesh_e37nn") [node name="Interface" type="Node3D" parent="."] [node name="Rooms" type="Node3D" parent="Interface"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, 0, 0.12) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.15, 0.01, 0.12) -[node name="Button" parent="Interface" instance=ExtResource("4_cghmp")] +[node name="AddRoom" parent="Interface" instance=ExtResource("4_cghmp")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.27, 0, 0.27) label = "add" icon = true + +[node name="SaveRoom" parent="Interface" instance=ExtResource("4_cghmp")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.21, 0, 0.27) +visible = false +label = "save" +icon = true + +[node name="Input" parent="Interface" instance=ExtResource("4_pbj71")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.09, 0.005, 0.27) +width = 0.15 +text = "New Room"