implement mesh generation and add basic room overview

This commit is contained in:
Nitwel 2023-12-20 22:19:43 +01:00
parent e417468b71
commit 228e32495c
9 changed files with 188 additions and 23 deletions

View File

@ -7,16 +7,14 @@ var sky_passthrough = preload("res://assets/materials/sky_passthrough.material")
@onready var camera: XRCamera3D = $XROrigin3D/XRCamera3D @onready var camera: XRCamera3D = $XROrigin3D/XRCamera3D
@onready var controller_left = $XROrigin3D/XRControllerLeft @onready var controller_left = $XROrigin3D/XRControllerLeft
@onready var controller_right = $XROrigin3D/XRControllerRight @onready var controller_right = $XROrigin3D/XRControllerRight
@onready var house = $House
func _ready(): func _ready():
# In case we're running on the headset, use the passthrough sky # In case we're running on the headset, use the passthrough sky
if OS.get_name() == "Android": if OS.get_name() == "Android":
# OS.request_permissions() # OS.request_permissions()
environment.environment.sky.set_material(sky_passthrough) environment.environment.sky.set_material(sky_passthrough)
house.visible = false
else: else:
house.visible = true RenderingServer.set_debug_generate_wireframes(true)
func _process(delta): func _process(delta):
if OS.get_name() != "Android": if OS.get_name() != "Android":
@ -34,6 +32,11 @@ func _process(delta):
camera.position += movement camera.position += movement
controller_left.position += movement controller_left.position += movement
controller_right.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): 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: if vec:
vec = vec.normalized() vec = vec.normalized()
return vec return vec

View File

@ -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="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"] [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="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="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://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"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m58yb"]
ao_enabled = true 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="Rooms" type="Node3D" parent="."]
[node name="House" parent="." instance=ExtResource("9_np6mw")]
[editable path="XROrigin3D/XRControllerLeft"] [editable path="XROrigin3D/XRControllerLeft"]

View File

@ -21,16 +21,24 @@ func create_room(room_name: String, level: int) -> RoomType:
return room 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: if editing_room != null:
editing_room.editable = false editing_room.editable = false
editing_room = null editing_room = null
if room != null:
room.editable = true
editing_room = room
var room = find_room(room_name) func is_editiong(room_name):
room.editable = true return editing_room != null && editing_room.name == room_name
editing_room = room
func find_room(room_name: String): func find_room(room_name):
for level in levels.get_children(): for level in levels.get_children():
for room in level.get_children(): for room in level.get_children():
if room.name == room_name: if room.name == room_name:
@ -45,7 +53,7 @@ func find_room_at(entity_position: Vector3):
return null return null
func get_level(level: int): func get_level(level: int):
return levels.get_index(level) return levels.get_child(level)
func get_rooms(level: int): func get_rooms(level: int):
return get_level(level).get_children() return get_level(level).get_children()

View File

@ -3,6 +3,7 @@ extends Node3D
@onready var wall_corners = $Ceiling/WallCorners @onready var wall_corners = $Ceiling/WallCorners
@onready var wall_edges = $Ceiling/WallEdges @onready var wall_edges = $Ceiling/WallEdges
@onready var wall_mesh: MeshInstance3D = $WallMesh @onready var wall_mesh: MeshInstance3D = $WallMesh
@onready var ceiling_mesh: MeshInstance3D = $CeilingMesh
@onready var wall_collisions = $WallCollisions @onready var wall_collisions = $WallCollisions
@onready var room_floor = $Floor @onready var room_floor = $Floor
@ -12,6 +13,8 @@ extends Node3D
var editable: bool = false: var editable: bool = false:
set(value): set(value):
if !is_node_ready(): await ready
if value: if value:
state_machine.change_to("Edit") state_machine.change_to("Edit")
else: else:
@ -29,12 +32,15 @@ func has_point(point: Vector3) -> bool:
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),
"name": name
} }
func _load(data): func _load(data):
await ready await ready
return return
name = data["name"]
state_machine.change_to("Edit") state_machine.change_to("Edit")
for corner in data["corners"]: for corner in data["corners"]:

View File

@ -31,6 +31,9 @@ script = ExtResource("1_ugebq")
material_override = ExtResource("3_al1ev") material_override = ExtResource("3_al1ev")
mesh = SubResource("ArrayMesh_7dibq") mesh = SubResource("ArrayMesh_7dibq")
[node name="CeilingMesh" type="MeshInstance3D" parent="."]
material_override = ExtResource("3_al1ev")
[node name="WallCollisions" type="Node3D" parent="."] [node name="WallCollisions" type="Node3D" parent="."]
[node name="Ceiling" type="StaticBody3D" parent="."] [node name="Ceiling" type="StaticBody3D" parent="."]

View File

@ -17,6 +17,8 @@ func _on_enter():
if room.wall_mesh.mesh == null: if room.wall_mesh.mesh == null:
return return
room.ceiling_mesh.mesh = generate_ceiling_mesh()
var collisions = generate_collision() var collisions = generate_collision()
@ -53,8 +55,6 @@ func generate_mesh():
st.add_vertex(first_corner.position) st.add_vertex(first_corner.position)
st.add_vertex(first_corner.position + wall_up) st.add_vertex(first_corner.position + wall_up)
# TODO: Implement Rust Binding for cdt algorithm to fill floor and ceiling
st.index() st.index()
st.generate_normals() st.generate_normals()
st.generate_tangents() st.generate_tangents()
@ -62,6 +62,47 @@ func generate_mesh():
return 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(): func generate_collision():
var collision_shapes: Array[CollisionShape3D] = [] var collision_shapes: Array[CollisionShape3D] = []

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1 version https://git-lfs.github.com/spec/v1
oid sha256:fe7c098cfc9adadb447df0230eba8a81f1825dd3c0cf4e654ebf98ca2314c8cc oid sha256:935bcbcfaa2d5dca17ce3efea167357dca8b5ac05f49d5b322add9a84607b4f0
size 151 size 158

View File

@ -6,6 +6,26 @@ const RoomType = preload("res://content/system/house/room/room.gd")
const window_scene = preload("./window.tscn") const window_scene = preload("./window.tscn")
@onready var background = $Background @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(): func _ready():
background.visible = false background.visible = false
@ -13,10 +33,79 @@ func _ready():
HomeApi.on_connect.connect(func(): HomeApi.on_connect.connect(func():
var rooms = House.body.get_rooms(0) var rooms = House.body.get_rooms(0)
for room in rooms: # for room in rooms:
var mesh = room.wall_mesh # 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)

View File

@ -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="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="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://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"] [sub_resource type="BoxMesh" id="BoxMesh_e37nn"]
size = Vector3(0.3, 0.01, 0.3) size = Vector3(0.3, 0.01, 0.3)
@ -18,9 +19,20 @@ mesh = SubResource("BoxMesh_e37nn")
[node name="Interface" type="Node3D" parent="."] [node name="Interface" type="Node3D" parent="."]
[node name="Rooms" type="Node3D" parent="Interface"] [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) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.27, 0, 0.27)
label = "add" label = "add"
icon = true 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"