make miniature view separate
This commit is contained in:
parent
9cb0c63fa0
commit
c0dccc8401
|
@ -5,6 +5,8 @@ const Entity = preload ("../entity.gd")
|
||||||
@onready var label: Label3D = $Label
|
@onready var label: Label3D = $Label
|
||||||
@onready var collision_shape = $CollisionShape3D
|
@onready var collision_shape = $CollisionShape3D
|
||||||
|
|
||||||
|
var sensor_data = {}
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready():
|
func _ready():
|
||||||
super()
|
super()
|
||||||
|
@ -17,6 +19,9 @@ func _ready():
|
||||||
)
|
)
|
||||||
|
|
||||||
func set_text(stateInfo):
|
func set_text(stateInfo):
|
||||||
|
if stateInfo == null:
|
||||||
|
return
|
||||||
|
|
||||||
var text = stateInfo["state"]
|
var text = stateInfo["state"]
|
||||||
|
|
||||||
if stateInfo["attributes"]["friendly_name"] != null:
|
if stateInfo["attributes"]["friendly_name"] != null:
|
||||||
|
@ -25,6 +30,9 @@ func set_text(stateInfo):
|
||||||
if stateInfo["attributes"].has("unit_of_measurement")&&stateInfo["attributes"]["unit_of_measurement"] != null:
|
if stateInfo["attributes"].has("unit_of_measurement")&&stateInfo["attributes"]["unit_of_measurement"] != null:
|
||||||
text += " " + stateInfo["attributes"]["unit_of_measurement"]
|
text += " " + stateInfo["attributes"]["unit_of_measurement"]
|
||||||
|
|
||||||
|
if stateInfo["attributes"].has("device_class"):
|
||||||
|
sensor_data[stateInfo["attributes"]["device_class"]] = stateInfo["state"]
|
||||||
|
|
||||||
label.text = text
|
label.text = text
|
||||||
|
|
||||||
var font = label.get_font()
|
var font = label.get_font()
|
||||||
|
@ -35,3 +43,9 @@ func set_text(stateInfo):
|
||||||
|
|
||||||
collision_shape.shape.size.x = size.x * label.pixel_size * 0.5
|
collision_shape.shape.size.x = size.x * label.pixel_size * 0.5
|
||||||
collision_shape.shape.size.y = size.y * label.pixel_size * 0.25
|
collision_shape.shape.size.y = size.y * label.pixel_size * 0.25
|
||||||
|
|
||||||
|
func get_sensor_data(type: String):
|
||||||
|
if sensor_data.has(type) == false:
|
||||||
|
return null
|
||||||
|
|
||||||
|
return sensor_data[type]
|
||||||
|
|
|
@ -6,13 +6,10 @@ 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
|
@onready var align_reference = $AlignReference
|
||||||
|
@onready var mini_view = $Miniature
|
||||||
|
|
||||||
var fixing_reference: bool = false
|
var fixing_reference: bool = false
|
||||||
var editing_room: RoomType = null
|
var editing_room: RoomType = null
|
||||||
var mini_view: bool = false:
|
|
||||||
set(value):
|
|
||||||
mini_view = value
|
|
||||||
update_mini_view()
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
Store.house.on_loaded.connect(func():
|
Store.house.on_loaded.connect(func():
|
||||||
|
@ -198,44 +195,6 @@ func create_entity_in(entity_id: String, room_name: String):
|
||||||
|
|
||||||
return entity
|
return entity
|
||||||
|
|
||||||
func update_mini_view():
|
|
||||||
collision_shape.disabled = !mini_view
|
|
||||||
|
|
||||||
var tween = create_tween()
|
|
||||||
tween.set_parallel(true)
|
|
||||||
tween.set_trans(Tween.TRANS_CUBIC)
|
|
||||||
|
|
||||||
if mini_view:
|
|
||||||
var aabb = get_level_aabb(0)
|
|
||||||
aabb.position.y = -0.03
|
|
||||||
aabb.size.y = 0.06
|
|
||||||
var center = aabb.position + aabb.size / 2.0
|
|
||||||
|
|
||||||
collision_shape.global_position = center
|
|
||||||
collision_shape.shape.size = aabb.size
|
|
||||||
|
|
||||||
var camera = get_node("/root/Main/XROrigin3D/XRCamera3D")
|
|
||||||
var camera_position = camera.global_position
|
|
||||||
var camera_direction = -camera.global_transform.basis.z
|
|
||||||
|
|
||||||
camera_position.y *= 0.5
|
|
||||||
camera_direction.y = 0.0
|
|
||||||
|
|
||||||
var target_position = camera_position + camera_direction.normalized() * 0.2
|
|
||||||
var new_position = target_position - center * 0.1
|
|
||||||
tween.tween_property(levels, "global_position", new_position, 0.5)
|
|
||||||
tween.tween_property(levels, "scale", Vector3(0.1, 0.1, 0.1), 0.5)
|
|
||||||
|
|
||||||
for room in get_rooms(0):
|
|
||||||
room.state_machine.change_to("Mini")
|
|
||||||
else:
|
|
||||||
tween.tween_property(levels, "global_position", Vector3(0, 0, 0), 0.5)
|
|
||||||
tween.tween_property(levels, "scale", Vector3(1.0, 1.0, 1.0), 0.5)
|
|
||||||
await tween.finished
|
|
||||||
|
|
||||||
for room in get_rooms(0):
|
|
||||||
room.state_machine.change_to("View")
|
|
||||||
|
|
||||||
func edit_reference():
|
func edit_reference():
|
||||||
fixing_reference = false
|
fixing_reference = false
|
||||||
align_reference.visible = true
|
align_reference.visible = true
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
[gd_scene load_steps=5 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"]
|
[ext_resource type="PackedScene" uid="uid://jls16btb8nko" path="res://content/system/house/align_reference.tscn" id="3_e1tcn"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://ds60i5n211hi3" path="res://content/system/house/mini/miniature.tscn" id="4_qjbly"]
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_x81up"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_x81up"]
|
||||||
|
|
||||||
|
@ -25,3 +26,5 @@ lock_rotation = true
|
||||||
[node name="AlignReference" parent="." instance=ExtResource("3_e1tcn")]
|
[node name="AlignReference" parent="." instance=ExtResource("3_e1tcn")]
|
||||||
visible = false
|
visible = false
|
||||||
disabled = true
|
disabled = true
|
||||||
|
|
||||||
|
[node name="Miniature" parent="." instance=ExtResource("4_qjbly")]
|
||||||
|
|
3
app/content/system/house/mini/mini_view_options.gd
Normal file
3
app/content/system/house/mini/mini_view_options.gd
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
extends Node3D
|
||||||
|
|
||||||
|
const mini_wall_shader: ShaderMaterial = preload ("./mini_wall.tres")
|
19
app/content/system/house/mini/mini_wall.tres
Normal file
19
app/content/system/house/mini/mini_wall.tres
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
[gd_resource type="ShaderMaterial" load_steps=4 format=3 uid="uid://bcfcough6ucvc"]
|
||||||
|
|
||||||
|
[ext_resource type="Shader" path="res://content/system/house/mini/mini_wall_shader.gdshader" id="1_sbr3e"]
|
||||||
|
|
||||||
|
[sub_resource type="Gradient" id="Gradient_2jwis"]
|
||||||
|
interpolation_color_space = 2
|
||||||
|
offsets = PackedFloat32Array(0.00280112, 1)
|
||||||
|
colors = PackedColorArray(0, 0.558935, 0.886772, 1, 0.999396, 0, 0.058647, 1)
|
||||||
|
|
||||||
|
[sub_resource type="GradientTexture1D" id="GradientTexture1D_rrsal"]
|
||||||
|
gradient = SubResource("Gradient_2jwis")
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
render_priority = 0
|
||||||
|
shader = ExtResource("1_sbr3e")
|
||||||
|
shader_parameter/data = PackedFloat32Array()
|
||||||
|
shader_parameter/data_size = 0
|
||||||
|
shader_parameter/min_max_data = null
|
||||||
|
shader_parameter/color_gradient = SubResource("GradientTexture1D_rrsal")
|
39
app/content/system/house/mini/mini_wall_shader.gdshader
Normal file
39
app/content/system/house/mini/mini_wall_shader.gdshader
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
shader_type spatial;
|
||||||
|
render_mode blend_mix, depth_draw_opaque, cull_disabled, diffuse_lambert, specular_schlick_ggx, unshaded;
|
||||||
|
|
||||||
|
uniform vec4 data[100];
|
||||||
|
uniform int data_size: hint_range(0, 100, 1);
|
||||||
|
uniform vec2 min_max_data;
|
||||||
|
uniform sampler2D color_gradient;
|
||||||
|
|
||||||
|
varying vec3 color;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void vertex() {
|
||||||
|
// Calculate Global Coordinates
|
||||||
|
vec3 world_position = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
|
||||||
|
|
||||||
|
color = vec3(1.0, 1.0, 1.0);
|
||||||
|
vec2 distances[100];
|
||||||
|
float dist_sum = 0.0;
|
||||||
|
|
||||||
|
if(data_size > 0) {
|
||||||
|
for(int i = 0; i < data_size; i++) {
|
||||||
|
float delta = 1.0 / distance(data[i].xyz, world_position);
|
||||||
|
|
||||||
|
distances[i] = vec2(delta, data[i].w);
|
||||||
|
dist_sum += delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < data_size; i++) {
|
||||||
|
float average = distances[i].x / dist_sum * distances[i].y;
|
||||||
|
color.xyz = texture(color_gradient, vec2(average, 0)).xyz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
ALBEDO = vec3(color.xyz);
|
||||||
|
ALPHA = 0.3;
|
||||||
|
}
|
84
app/content/system/house/mini/miniature.gd
Normal file
84
app/content/system/house/mini/miniature.gd
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
extends Node3D
|
||||||
|
|
||||||
|
const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd")
|
||||||
|
const wall_material = preload ("./mini_wall.tres")
|
||||||
|
|
||||||
|
@onready var walls_mesh = $WallsMesh
|
||||||
|
@onready var floor_mesh = $FloorMesh
|
||||||
|
@onready var collision_shape = $CollisionShape3D
|
||||||
|
@onready var toggle_heatmap = $HeatmapButton
|
||||||
|
|
||||||
|
var enabled = true:
|
||||||
|
set(value):
|
||||||
|
enabled = value
|
||||||
|
update()
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
update()
|
||||||
|
|
||||||
|
if Store.house.is_loaded() == false:
|
||||||
|
await Store.house.on_loaded
|
||||||
|
|
||||||
|
var room = Store.house.rooms[0]
|
||||||
|
|
||||||
|
var corners = room.corners
|
||||||
|
var height = room.height
|
||||||
|
|
||||||
|
walls_mesh.mesh = ConstructRoomMesh.generate_wall_mesh_grid(corners, height)
|
||||||
|
floor_mesh.mesh = ConstructRoomMesh.generate_ceiling_mesh_grid(corners)
|
||||||
|
|
||||||
|
walls_mesh.material_override = wall_material
|
||||||
|
floor_mesh.material_override = wall_material
|
||||||
|
|
||||||
|
active = true
|
||||||
|
update_data(0.0)
|
||||||
|
|
||||||
|
toggle_heatmap.on_button_down.connect(func():
|
||||||
|
active=true
|
||||||
|
EventSystem.on_slow_tick.connect(update_data)
|
||||||
|
)
|
||||||
|
|
||||||
|
toggle_heatmap.on_button_up.connect(func():
|
||||||
|
wall_material.set_shader_parameter("data", [])
|
||||||
|
wall_material.set_shader_parameter("data_size", 0)
|
||||||
|
active=false
|
||||||
|
EventSystem.on_slow_tick.disconnect(update_data)
|
||||||
|
)
|
||||||
|
|
||||||
|
func update():
|
||||||
|
walls_mesh.visible = enabled
|
||||||
|
floor_mesh.visible = enabled
|
||||||
|
collision_shape.disabled = not enabled
|
||||||
|
|
||||||
|
const SensorEntity = preload ("res://content/entities/sensor/sensor.gd")
|
||||||
|
|
||||||
|
var active: bool = false
|
||||||
|
|
||||||
|
func update_data(delta: float) -> void:
|
||||||
|
var data_list = []
|
||||||
|
var min_max_data
|
||||||
|
|
||||||
|
for room in House.body.get_rooms(0):
|
||||||
|
for entity in room.get_node("Entities").get_children():
|
||||||
|
if entity is SensorEntity:
|
||||||
|
var sensor = entity as SensorEntity
|
||||||
|
var data = sensor.get_sensor_data("temperature")
|
||||||
|
if data == null:
|
||||||
|
continue
|
||||||
|
|
||||||
|
var sensor_pos = sensor.global_position
|
||||||
|
|
||||||
|
if min_max_data == null:
|
||||||
|
min_max_data = Vector2(float(data), float(data))
|
||||||
|
else:
|
||||||
|
min_max_data.x = min(min_max_data.x, float(data))
|
||||||
|
min_max_data.y = max(min_max_data.y, float(data))
|
||||||
|
|
||||||
|
data_list.append(Vector4(sensor_pos.x, sensor_pos.y, sensor_pos.z, float(data)))
|
||||||
|
|
||||||
|
for data in data_list:
|
||||||
|
data.w = (data.w - min_max_data.x) / (min_max_data.y - min_max_data.x)
|
||||||
|
|
||||||
|
wall_material.set_shader_parameter("data", data_list)
|
||||||
|
wall_material.set_shader_parameter("min_max_data", min_max_data)
|
||||||
|
wall_material.set_shader_parameter("data_size", data_list.size())
|
24
app/content/system/house/mini/miniature.tscn
Normal file
24
app/content/system/house/mini/miniature.tscn
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
[gd_scene load_steps=5 format=3 uid="uid://ds60i5n211hi3"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://content/system/house/mini/miniature.gd" id="1_b53yn"]
|
||||||
|
[ext_resource type="Script" path="res://content/functions/movable.gd" id="2_x7oed"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="3_tgdcf"]
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape3D" id="BoxShape3D_bckw3"]
|
||||||
|
|
||||||
|
[node name="Miniature" type="StaticBody3D"]
|
||||||
|
script = ExtResource("1_b53yn")
|
||||||
|
|
||||||
|
[node name="WallsMesh" type="MeshInstance3D" parent="."]
|
||||||
|
|
||||||
|
[node name="FloorMesh" type="MeshInstance3D" parent="."]
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
|
shape = SubResource("BoxShape3D_bckw3")
|
||||||
|
|
||||||
|
[node name="Movable" type="Node" parent="."]
|
||||||
|
script = ExtResource("2_x7oed")
|
||||||
|
|
||||||
|
[node name="HeatmapButton" parent="." instance=ExtResource("3_tgdcf")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.5, 0.48)
|
||||||
|
toggleable = true
|
|
@ -1,5 +1,7 @@
|
||||||
extends Node3D
|
extends Node3D
|
||||||
|
|
||||||
|
const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd")
|
||||||
|
|
||||||
@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
|
||||||
|
@ -55,75 +57,12 @@ func get_aabb():
|
||||||
return AABB(to_global(min_pos), to_global(max_pos) - to_global(min_pos))
|
return AABB(to_global(min_pos), to_global(max_pos) - to_global(min_pos))
|
||||||
|
|
||||||
static func generate_wall_mesh(room_store: Dictionary):
|
static func generate_wall_mesh(room_store: Dictionary):
|
||||||
if room_store.corners.size() < 2:
|
var corners = room_store.corners
|
||||||
return null
|
var height = room_store.height
|
||||||
|
|
||||||
var st = SurfaceTool.new()
|
return ConstructRoomMesh.generate_wall_mesh_grid(corners, height)
|
||||||
var wall_up = Vector3.UP * room_store.height
|
|
||||||
|
|
||||||
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
|
||||||
|
|
||||||
for corner in room_store.corners:
|
|
||||||
var corner3D = Vector3(corner.x, 0, corner.y)
|
|
||||||
|
|
||||||
st.add_vertex(corner3D)
|
|
||||||
st.add_vertex(corner3D + wall_up)
|
|
||||||
|
|
||||||
var first_corner = Vector3(room_store.corners[0].x, 0, room_store.corners[0].y)
|
|
||||||
|
|
||||||
st.add_vertex(first_corner)
|
|
||||||
st.add_vertex(first_corner + wall_up)
|
|
||||||
|
|
||||||
st.index()
|
|
||||||
st.generate_normals()
|
|
||||||
st.generate_tangents()
|
|
||||||
var mesh = st.commit()
|
|
||||||
|
|
||||||
return mesh
|
|
||||||
|
|
||||||
static func generate_ceiling_mesh(room_store: Dictionary):
|
static func generate_ceiling_mesh(room_store: Dictionary):
|
||||||
|
|
||||||
var points: PackedVector2Array = PackedVector2Array()
|
|
||||||
var edges: PackedInt32Array = PackedInt32Array()
|
|
||||||
var triangles: PackedInt32Array
|
|
||||||
|
|
||||||
var corners = room_store.corners
|
var corners = room_store.corners
|
||||||
|
|
||||||
if corners.size() < 3:
|
return ConstructRoomMesh.generate_ceiling_mesh_grid(corners)
|
||||||
return null
|
|
||||||
|
|
||||||
for i in range(corners.size()):
|
|
||||||
var corner = corners[i]
|
|
||||||
points.append(Vector2(corner.x, corner.y))
|
|
||||||
edges.append(i)
|
|
||||||
edges.append((i + 1) % corners.size())
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
[gd_scene load_steps=9 format=3 uid="uid://bswgmclohuqui"]
|
[gd_scene load_steps=8 format=3 uid="uid://bswgmclohuqui"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://content/system/house/room/room.gd" id="1_fccq0"]
|
[ext_resource type="Script" path="res://content/system/house/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="Script" path="res://lib/utils/state_machine/state_machine.gd" id="4_nbbo6"]
|
[ext_resource type="Script" path="res://lib/utils/state_machine/state_machine.gd" id="4_nbbo6"]
|
||||||
[ext_resource type="Script" path="res://content/system/house/room/states/mini.gd" id="6_g4qca"]
|
|
||||||
[ext_resource type="Script" path="res://content/system/house/room/states/view.gd" id="6_g066t"]
|
[ext_resource type="Script" path="res://content/system/house/room/states/view.gd" id="6_g066t"]
|
||||||
[ext_resource type="Script" path="res://content/system/house/room/states/edit.gd" id="7_ap14h"]
|
[ext_resource type="Script" path="res://content/system/house/room/states/edit.gd" id="7_ap14h"]
|
||||||
|
|
||||||
|
@ -57,7 +56,4 @@ script = ExtResource("6_g066t")
|
||||||
[node name="Edit" type="Node" parent="StateMachine"]
|
[node name="Edit" type="Node" parent="StateMachine"]
|
||||||
script = ExtResource("7_ap14h")
|
script = ExtResource("7_ap14h")
|
||||||
|
|
||||||
[node name="Mini" type="Node" parent="StateMachine"]
|
|
||||||
script = ExtResource("6_g4qca")
|
|
||||||
|
|
||||||
[node name="Entities" type="Node3D" parent="."]
|
[node name="Entities" type="Node3D" parent="."]
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
extends RoomState
|
|
||||||
|
|
||||||
const RoomState = preload("./room_state.gd")
|
|
||||||
const walls_mini_material = preload("../walls_mini.tres")
|
|
||||||
const walls_material = preload("../walls.tres")
|
|
||||||
|
|
||||||
func _on_enter():
|
|
||||||
room.wall_mesh.visible = true
|
|
||||||
room.ceiling_mesh.visible = false
|
|
||||||
room.wall_mesh.material_override = walls_mini_material
|
|
||||||
room.room_ceiling.get_node("CollisionShape3D").disabled = true
|
|
||||||
room.room_floor.get_node("CollisionShape3D").disabled = true
|
|
||||||
|
|
||||||
for collision in room.wall_collisions.get_children():
|
|
||||||
collision.get_child(0).disabled = true
|
|
||||||
|
|
||||||
for corner in room.wall_corners.get_children():
|
|
||||||
corner.get_node("CollisionShape3D").disabled = true
|
|
||||||
|
|
||||||
for edge in room.wall_edges.get_children():
|
|
||||||
edge.get_node("CollisionShape3D").disabled = true
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _on_leave():
|
|
||||||
room.wall_mesh.visible = false
|
|
||||||
room.ceiling_mesh.visible = false
|
|
||||||
room.wall_mesh.material_override = walls_material
|
|
||||||
room.room_ceiling.get_node("CollisionShape3D").disabled = false
|
|
||||||
room.room_floor.get_node("CollisionShape3D").disabled = false
|
|
||||||
|
|
||||||
for collision in room.wall_collisions.get_children():
|
|
||||||
collision.get_child(0).disabled = false
|
|
||||||
|
|
||||||
for corner in room.wall_corners.get_children():
|
|
||||||
corner.get_node("CollisionShape3D").disabled = false
|
|
||||||
|
|
||||||
for edge in room.wall_edges.get_children():
|
|
||||||
edge.get_node("CollisionShape3D").disabled = false
|
|
||||||
|
|
||||||
|
|
|
@ -28,16 +28,16 @@ func _on_enter():
|
||||||
ceiling_shape.shape = room.ceiling_mesh.mesh.create_trimesh_shape()
|
ceiling_shape.shape = room.ceiling_mesh.mesh.create_trimesh_shape()
|
||||||
floor_shape.shape = room.ceiling_mesh.mesh.create_trimesh_shape()
|
floor_shape.shape = room.ceiling_mesh.mesh.create_trimesh_shape()
|
||||||
ceiling_shape.shape.backface_collision = true
|
ceiling_shape.shape.backface_collision = true
|
||||||
|
|
||||||
var collisions = generate_collision()
|
|
||||||
|
|
||||||
for collision in collisions:
|
var collision = CollisionShape3D.new()
|
||||||
var static_body = StaticBody3D.new()
|
collision.shape = room.wall_mesh.mesh.create_trimesh_shape()
|
||||||
static_body.set_collision_layer_value(4, true)
|
|
||||||
static_body.set_collision_layer_value(5, true)
|
var static_body = StaticBody3D.new()
|
||||||
static_body.collision_mask = 0
|
static_body.set_collision_layer_value(4, true)
|
||||||
static_body.add_child(collision)
|
static_body.set_collision_layer_value(5, true)
|
||||||
room.wall_collisions.add_child(static_body)
|
static_body.collision_mask = 0
|
||||||
|
static_body.add_child(collision)
|
||||||
|
room.wall_collisions.add_child(static_body)
|
||||||
|
|
||||||
func _on_leave():
|
func _on_leave():
|
||||||
room.room_ceiling.get_node("CollisionShape3D").disabled = true
|
room.room_ceiling.get_node("CollisionShape3D").disabled = true
|
||||||
|
@ -46,33 +46,3 @@ func _on_leave():
|
||||||
for collision in room.wall_collisions.get_children():
|
for collision in room.wall_collisions.get_children():
|
||||||
collision.queue_free()
|
collision.queue_free()
|
||||||
await collision.tree_exited
|
await collision.tree_exited
|
||||||
|
|
||||||
func generate_collision():
|
|
||||||
var room_store = Store.house.get_room(room.name)
|
|
||||||
|
|
||||||
var collision_shapes: Array[CollisionShape3D] = []
|
|
||||||
|
|
||||||
var corners = room_store.corners
|
|
||||||
|
|
||||||
for i in range(corners.size()):
|
|
||||||
var corner = Vector3(corners[i].x, 0, corners[i].y)
|
|
||||||
var next_corner_index = (i + 1) % corners.size()
|
|
||||||
var next_corner = Vector3(corners[next_corner_index].x, 0, corners[next_corner_index].y)
|
|
||||||
|
|
||||||
var shape = BoxShape3D.new()
|
|
||||||
shape.size = Vector3((next_corner - corner).length(), room_store.height, 0.04)
|
|
||||||
|
|
||||||
var transform = Transform3D()
|
|
||||||
var back_vector = (corner - next_corner).cross(Vector3.UP).normalized() * shape.size.z / 2
|
|
||||||
|
|
||||||
transform.basis = Basis((next_corner - corner).normalized(), Vector3.UP, back_vector.normalized())
|
|
||||||
transform.origin = corner + (next_corner - corner) / 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
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[gd_resource type="StandardMaterial3D" format=3 uid="uid://dxyuncqxagt28"]
|
|
||||||
|
|
||||||
[resource]
|
|
||||||
transparency = 1
|
|
||||||
cull_mode = 2
|
|
||||||
albedo_color = Color(1, 1, 1, 0.47451)
|
|
|
@ -32,6 +32,15 @@ func _enter_tree():
|
||||||
func load_devices():
|
func load_devices():
|
||||||
if devices.size() == 0:
|
if devices.size() == 0:
|
||||||
devices = await HomeApi.get_devices()
|
devices = await HomeApi.get_devices()
|
||||||
|
devices.sort_custom(func(a, b):
|
||||||
|
return a.values()[0]["name"].to_lower() < b.values()[0]["name"].to_lower()
|
||||||
|
)
|
||||||
|
|
||||||
|
for device in devices:
|
||||||
|
device.values()[0]["entities"].sort_custom(func(a, b):
|
||||||
|
return a.to_lower() < b.to_lower()
|
||||||
|
)
|
||||||
|
|
||||||
render()
|
render()
|
||||||
|
|
||||||
HomeApi.on_disconnect.connect(func():
|
HomeApi.on_disconnect.connect(func():
|
||||||
|
|
|
@ -7,6 +7,5 @@ func _ready():
|
||||||
background.visible = false
|
background.visible = false
|
||||||
|
|
||||||
mini_view.on_button_down.connect(func():
|
mini_view.on_button_down.connect(func():
|
||||||
House.body.mini_view = !House.body.mini_view
|
House.body.mini_view.enabled=!House.body.mini_view.enabled
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
194
app/lib/utils/mesh/construct_room_mesh.gd
Normal file
194
app/lib/utils/mesh/construct_room_mesh.gd
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
static func generate_wall_mesh(corners, height):
|
||||||
|
if corners.size() < 3:
|
||||||
|
return null
|
||||||
|
|
||||||
|
var st = SurfaceTool.new()
|
||||||
|
var wall_up = Vector3.UP * height
|
||||||
|
|
||||||
|
st.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
||||||
|
|
||||||
|
for corner in corners:
|
||||||
|
var corner3D = Vector3(corner.x, 0, corner.y)
|
||||||
|
|
||||||
|
st.add_vertex(corner3D)
|
||||||
|
st.add_vertex(corner3D + wall_up)
|
||||||
|
|
||||||
|
var first_corner = Vector3(corners[0].x, 0, corners[0].y)
|
||||||
|
|
||||||
|
st.add_vertex(first_corner)
|
||||||
|
st.add_vertex(first_corner + wall_up)
|
||||||
|
|
||||||
|
st.index()
|
||||||
|
st.generate_normals()
|
||||||
|
st.generate_tangents()
|
||||||
|
var mesh = st.commit()
|
||||||
|
|
||||||
|
return mesh
|
||||||
|
|
||||||
|
static func generate_ceiling_mesh(corners):
|
||||||
|
var points: PackedVector2Array = PackedVector2Array()
|
||||||
|
var edges: PackedInt32Array = PackedInt32Array()
|
||||||
|
var triangles: PackedInt32Array
|
||||||
|
|
||||||
|
if corners.size() < 3:
|
||||||
|
return null
|
||||||
|
|
||||||
|
for i in range(corners.size()):
|
||||||
|
var corner = corners[i]
|
||||||
|
points.append(Vector2(corner.x, corner.y))
|
||||||
|
edges.append(i)
|
||||||
|
edges.append((i + 1) % corners.size())
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
return _create_mesh(points, triangles)
|
||||||
|
|
||||||
|
static func generate_wall_mesh_grid(corners, height, grid: Vector2=Vector2(0.1, 0.1)):
|
||||||
|
if corners.size() < 3:
|
||||||
|
return null
|
||||||
|
|
||||||
|
var st = SurfaceTool.new()
|
||||||
|
|
||||||
|
st.begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||||
|
|
||||||
|
for corner_i in range(corners.size()):
|
||||||
|
var corner = Vector3(corners[corner_i].x, 0, corners[corner_i].y)
|
||||||
|
var next_index = (corner_i + 1) % corners.size()
|
||||||
|
var next_corner = Vector3(corners[next_index].x, 0, corners[next_index].y)
|
||||||
|
|
||||||
|
var steps = ceil(Vector2((next_corner - corner).length() / grid.x, height / grid.y))
|
||||||
|
|
||||||
|
var forward_dir = (next_corner - corner).normalized() * grid.x
|
||||||
|
var up_dir = Vector3.UP * grid.y
|
||||||
|
|
||||||
|
var close_distance = Vector2(1, 1)
|
||||||
|
|
||||||
|
for y in range(0, steps.y):
|
||||||
|
|
||||||
|
close_distance.x = 1
|
||||||
|
|
||||||
|
if y == steps.y - 1:
|
||||||
|
close_distance.y = fmod(height, grid.y) / grid.y
|
||||||
|
print(close_distance.y)
|
||||||
|
|
||||||
|
for x in range(0, steps.x):
|
||||||
|
var point = corner + forward_dir * x + Vector3.UP * grid.y * y
|
||||||
|
|
||||||
|
if x == steps.x - 1:
|
||||||
|
close_distance.x = fmod(corner.distance_to(next_corner), grid.x) / grid.x
|
||||||
|
|
||||||
|
st.add_vertex(point)
|
||||||
|
st.add_vertex(point + forward_dir * close_distance.x)
|
||||||
|
st.add_vertex(point + up_dir * close_distance.y)
|
||||||
|
|
||||||
|
st.add_vertex(point + forward_dir * close_distance.x)
|
||||||
|
st.add_vertex(point + forward_dir * close_distance.x + up_dir * close_distance.y)
|
||||||
|
st.add_vertex(point + up_dir * close_distance.y)
|
||||||
|
|
||||||
|
st.index()
|
||||||
|
st.generate_normals()
|
||||||
|
st.generate_tangents()
|
||||||
|
var mesh = st.commit()
|
||||||
|
|
||||||
|
return mesh
|
||||||
|
|
||||||
|
static func generate_ceiling_mesh_grid(corners, grid: Vector2=Vector2(0.1, 0.1)):
|
||||||
|
var points: PackedVector2Array = PackedVector2Array()
|
||||||
|
var edges: PackedInt32Array = PackedInt32Array()
|
||||||
|
var triangles: PackedInt32Array
|
||||||
|
|
||||||
|
if corners.size() < 3:
|
||||||
|
return null
|
||||||
|
|
||||||
|
var min_val = Vector2(corners[0])
|
||||||
|
var max_val = Vector2(corners[0])
|
||||||
|
|
||||||
|
for i in range(corners.size()):
|
||||||
|
var corner = corners[i]
|
||||||
|
|
||||||
|
min_val.x = min(min_val.x, corner.x)
|
||||||
|
min_val.y = min(min_val.y, corner.y)
|
||||||
|
max_val.x = max(max_val.x, corner.x)
|
||||||
|
max_val.y = max(max_val.y, corner.y)
|
||||||
|
|
||||||
|
points.append(Vector2(corner.x, corner.y))
|
||||||
|
edges.append(i)
|
||||||
|
edges.append((i + 1) % corners.size())
|
||||||
|
|
||||||
|
var size = max_val - min_val
|
||||||
|
|
||||||
|
## Fill points insde the polygon
|
||||||
|
for y in range(1, int(size.y / grid.y)):
|
||||||
|
var x_intersections: Array[float] = []
|
||||||
|
|
||||||
|
var y_start = Vector2(min_val.x, min_val.y + y * grid.y)
|
||||||
|
var y_end = Vector2(max_val.x, min_val.y + y * grid.y)
|
||||||
|
|
||||||
|
for i in range(corners.size()):
|
||||||
|
var a = corners[i]
|
||||||
|
var b = corners[(i + 1) % corners.size()]
|
||||||
|
|
||||||
|
var result = Geometry2D.segment_intersects_segment(a, b, y_start, y_end)
|
||||||
|
|
||||||
|
if result != null:
|
||||||
|
x_intersections.append(result.x)
|
||||||
|
|
||||||
|
var intersection_counter = 0
|
||||||
|
|
||||||
|
x_intersections.sort()
|
||||||
|
|
||||||
|
for x in range(1, int(size.x / grid.x)):
|
||||||
|
var point = min_val + Vector2(x * grid.x, y * grid.y)
|
||||||
|
|
||||||
|
for i in range(intersection_counter, x_intersections.size()):
|
||||||
|
if x_intersections[i] < point.x:
|
||||||
|
intersection_counter += 1
|
||||||
|
|
||||||
|
var color = Color(1, 1, 0)
|
||||||
|
|
||||||
|
if intersection_counter % 2 == 1:
|
||||||
|
color = Color(1, 0, 1)
|
||||||
|
points.append(point)
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
||||||
|
return _create_mesh(points, triangles)
|
||||||
|
|
||||||
|
static func _create_mesh(points: PackedVector2Array, triangles: PackedInt32Array):
|
||||||
|
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
|
Loading…
Reference in New Issue
Block a user