Compare commits
25 Commits
2eb79e9840
...
fd8d624437
Author | SHA1 | Date | |
---|---|---|---|
|
fd8d624437 | ||
|
111a7c2558 | ||
|
ad9245a922 | ||
|
4a4d359773 | ||
|
85ebcd3edd | ||
|
cd38985510 | ||
|
f3e2d2e9ff | ||
|
0fee21ccdb | ||
|
cfbd73bb21 | ||
|
f9a4d8ad6b | ||
|
9aacf22850 | ||
|
6d49a74359 | ||
|
48c0a84242 | ||
|
cd96865711 | ||
|
231f64f4f5 | ||
|
2d049c6109 | ||
|
5f414434d8 | ||
|
39bf59d78f | ||
|
2dcc9e546d | ||
|
5f4b128231 | ||
|
93e36f8f28 | ||
|
a433fc0845 | ||
|
a824bb3f0b | ||
|
ccebdb5209 | ||
|
875424b413 |
14
.github/workflows/hassfest.yml
vendored
Normal file
14
.github/workflows/hassfest.yml
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
name: Validate with hassfest
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 0 * * *'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate:
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- uses: "actions/checkout@v4"
|
||||||
|
- uses: "home-assistant/actions/hassfest@master"
|
17
.github/workflows/validate-hacs.yml
vendored
Normal file
17
.github/workflows/validate-hacs.yml
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
name: HACS Action
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
schedule:
|
||||||
|
- cron: "0 0 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
hacs:
|
||||||
|
name: HACS Action
|
||||||
|
runs-on: "ubuntu-latest"
|
||||||
|
steps:
|
||||||
|
- name: HACS Action
|
||||||
|
uses: "hacs/action@main"
|
||||||
|
with:
|
||||||
|
category: "integration"
|
|
@ -5,7 +5,7 @@ const Entity = preload ("../entity.gd")
|
||||||
@export var view_width = 0.15
|
@export var view_width = 0.15
|
||||||
|
|
||||||
@onready var view = $View
|
@onready var view = $View
|
||||||
@onready var http_request = $HTTPRequest
|
@onready var http_request: HTTPRequest = $HTTPRequest
|
||||||
@onready var mesh = $MeshInstance3D
|
@onready var mesh = $MeshInstance3D
|
||||||
@onready var refresh_timer = $RefreshTimer
|
@onready var refresh_timer = $RefreshTimer
|
||||||
@onready var settings = $Settings
|
@onready var settings = $Settings
|
||||||
|
@ -33,6 +33,7 @@ func _ready():
|
||||||
)
|
)
|
||||||
|
|
||||||
R.effect(func(_arg):
|
R.effect(func(_arg):
|
||||||
|
print("Cam active: ", cam_active.value)
|
||||||
if cam_active.value:
|
if cam_active.value:
|
||||||
refresh_timer.start()
|
refresh_timer.start()
|
||||||
else:
|
else:
|
||||||
|
@ -69,6 +70,10 @@ func set_state(stateInfo):
|
||||||
refresh_timer.timeout.connect(load_image.bind(url))
|
refresh_timer.timeout.connect(load_image.bind(url))
|
||||||
|
|
||||||
func load_image(url: String):
|
func load_image(url: String):
|
||||||
|
if http_request.get_http_client_status() != HTTPClient.STATUS_DISCONNECTED:
|
||||||
|
print("HTTP client is busy, skipping")
|
||||||
|
return
|
||||||
|
|
||||||
http_request.request("http://192.168.33.33:8123" + url)
|
http_request.request("http://192.168.33.33:8123" + url)
|
||||||
|
|
||||||
var result = await http_request.request_completed
|
var result = await http_request.request_completed
|
||||||
|
@ -115,6 +120,8 @@ func load_image(url: String):
|
||||||
view.pixel_size = pixel_size
|
view.pixel_size = pixel_size
|
||||||
mesh.visible = false
|
mesh.visible = false
|
||||||
|
|
||||||
|
print("Loaded image: ", url)
|
||||||
|
|
||||||
func get_options():
|
func get_options():
|
||||||
return {
|
return {
|
||||||
"cam_active": cam_active.value,
|
"cam_active": cam_active.value,
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
[ext_resource type="PackedScene" uid="uid://pk5k1q8bx0rj" path="res://content/ui/components/slider/slider.tscn" id="4_t8xp5"]
|
[ext_resource type="PackedScene" uid="uid://pk5k1q8bx0rj" path="res://content/ui/components/slider/slider.tscn" id="4_t8xp5"]
|
||||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="5_opf0y"]
|
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="5_opf0y"]
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_smnuk"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ikxbe"]
|
||||||
resource_local_to_scene = true
|
resource_local_to_scene = true
|
||||||
render_priority = 10
|
render_priority = 10
|
||||||
shader = ExtResource("2_wwobq")
|
shader = ExtResource("2_wwobq")
|
||||||
|
@ -22,7 +22,7 @@ shader_parameter/corner_radius = 0.2
|
||||||
shader_parameter/roughness = 0.3
|
shader_parameter/roughness = 0.3
|
||||||
shader_parameter/grain_amount = 0.02
|
shader_parameter/grain_amount = 0.02
|
||||||
|
|
||||||
[sub_resource type="QuadMesh" id="QuadMesh_jill0"]
|
[sub_resource type="QuadMesh" id="QuadMesh_qfg01"]
|
||||||
size = Vector2(0.3, 0.2)
|
size = Vector2(0.3, 0.2)
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_ctomk"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_ctomk"]
|
||||||
|
@ -34,8 +34,8 @@ collision_mask = 0
|
||||||
script = ExtResource("1_1ixy6")
|
script = ExtResource("1_1ixy6")
|
||||||
|
|
||||||
[node name="Panel" parent="." instance=ExtResource("1_myvk1")]
|
[node name="Panel" parent="." instance=ExtResource("1_myvk1")]
|
||||||
material_override = SubResource("ShaderMaterial_smnuk")
|
material_override = SubResource("ShaderMaterial_ikxbe")
|
||||||
mesh = SubResource("QuadMesh_jill0")
|
mesh = SubResource("QuadMesh_qfg01")
|
||||||
skeleton = NodePath("../..")
|
skeleton = NodePath("../..")
|
||||||
size = Vector2(0.3, 0.2)
|
size = Vector2(0.3, 0.2)
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ horizontal_alignment = 0
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.06, -0.01, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.06, -0.01, 0)
|
||||||
label = "videocam_off"
|
label = "videocam_off"
|
||||||
icon = true
|
icon = true
|
||||||
|
toggleable = true
|
||||||
|
|
||||||
[node name="FPSLabel" type="Label3D" parent="."]
|
[node name="FPSLabel" type="Label3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.14, -0.05, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.14, -0.05, 0)
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="3_2gpr3"]
|
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="3_2gpr3"]
|
||||||
[ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="4_upyp3"]
|
[ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="4_upyp3"]
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_t0vpw"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_00j7x"]
|
||||||
resource_local_to_scene = true
|
resource_local_to_scene = true
|
||||||
render_priority = 10
|
render_priority = 10
|
||||||
shader = ExtResource("2_m4moa")
|
shader = ExtResource("2_m4moa")
|
||||||
|
@ -21,7 +21,7 @@ shader_parameter/corner_radius = 0.2
|
||||||
shader_parameter/roughness = 0.3
|
shader_parameter/roughness = 0.3
|
||||||
shader_parameter/grain_amount = 0.02
|
shader_parameter/grain_amount = 0.02
|
||||||
|
|
||||||
[sub_resource type="QuadMesh" id="QuadMesh_s453u"]
|
[sub_resource type="QuadMesh" id="QuadMesh_3236q"]
|
||||||
size = Vector2(0.3, 0.25)
|
size = Vector2(0.3, 0.25)
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_bu024"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_bu024"]
|
||||||
|
@ -34,8 +34,8 @@ script = ExtResource("1_gw2gi")
|
||||||
|
|
||||||
[node name="Panel" parent="." instance=ExtResource("1_78ups")]
|
[node name="Panel" parent="." instance=ExtResource("1_78ups")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -7.45058e-09, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -7.45058e-09, 0)
|
||||||
material_override = SubResource("ShaderMaterial_t0vpw")
|
material_override = SubResource("ShaderMaterial_00j7x")
|
||||||
mesh = SubResource("QuadMesh_s453u")
|
mesh = SubResource("QuadMesh_3236q")
|
||||||
skeleton = NodePath("../..")
|
skeleton = NodePath("../..")
|
||||||
size = Vector2(0.3, 0.25)
|
size = Vector2(0.3, 0.25)
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
[ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="5_ecnnd"]
|
[ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="5_ecnnd"]
|
||||||
[ext_resource type="PackedScene" uid="uid://wgnowarejk5y" path="res://content/ui/components/select/select.tscn" id="6_egqee"]
|
[ext_resource type="PackedScene" uid="uid://wgnowarejk5y" path="res://content/ui/components/select/select.tscn" id="6_egqee"]
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_3ewpv"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_pqb3y"]
|
||||||
resource_local_to_scene = true
|
resource_local_to_scene = true
|
||||||
render_priority = 10
|
render_priority = 10
|
||||||
shader = ExtResource("3_vjmg5")
|
shader = ExtResource("3_vjmg5")
|
||||||
|
@ -22,7 +22,7 @@ shader_parameter/corner_radius = 0.2
|
||||||
shader_parameter/roughness = 0.3
|
shader_parameter/roughness = 0.3
|
||||||
shader_parameter/grain_amount = 0.02
|
shader_parameter/grain_amount = 0.02
|
||||||
|
|
||||||
[sub_resource type="QuadMesh" id="QuadMesh_t2fh8"]
|
[sub_resource type="QuadMesh" id="QuadMesh_b6qk4"]
|
||||||
size = Vector2(0.3, 0.2)
|
size = Vector2(0.3, 0.2)
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_53oq0"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_53oq0"]
|
||||||
|
@ -34,8 +34,8 @@ collision_mask = 0
|
||||||
script = ExtResource("1_xxfkt")
|
script = ExtResource("1_xxfkt")
|
||||||
|
|
||||||
[node name="Panel" parent="." instance=ExtResource("2_4g761")]
|
[node name="Panel" parent="." instance=ExtResource("2_4g761")]
|
||||||
material_override = SubResource("ShaderMaterial_3ewpv")
|
material_override = SubResource("ShaderMaterial_pqb3y")
|
||||||
mesh = SubResource("QuadMesh_t2fh8")
|
mesh = SubResource("QuadMesh_b6qk4")
|
||||||
skeleton = NodePath("../..")
|
skeleton = NodePath("../..")
|
||||||
size = Vector2(0.3, 0.2)
|
size = Vector2(0.3, 0.2)
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,40 @@ const Entity = preload ("../entity.gd")
|
||||||
@onready var artist = $PlayingInfo/Artist
|
@onready var artist = $PlayingInfo/Artist
|
||||||
@onready var http_request = $PlayingInfo/HTTPRequest
|
@onready var http_request = $PlayingInfo/HTTPRequest
|
||||||
@onready var slider = $Slider
|
@onready var slider = $Slider
|
||||||
|
@onready var settings = $Settings
|
||||||
|
|
||||||
var playing = false
|
var playing = false
|
||||||
var volume = 50
|
var volume = 50
|
||||||
|
|
||||||
|
var show_volume = R.state(true)
|
||||||
|
var show_image = R.state(true)
|
||||||
|
|
||||||
# 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()
|
||||||
|
|
||||||
|
remove_child(settings)
|
||||||
|
|
||||||
|
R.effect(func(_arg):
|
||||||
|
if show_settings.value:
|
||||||
|
add_child(settings)
|
||||||
|
elif settings.is_inside_tree():
|
||||||
|
remove_child(settings)
|
||||||
|
camera_follower.reset()
|
||||||
|
App.house.save_all_entities()
|
||||||
|
)
|
||||||
|
|
||||||
|
R.effect(func(_arg):
|
||||||
|
if show_volume.value:
|
||||||
|
add_child(slider)
|
||||||
|
else:
|
||||||
|
remove_child(slider)
|
||||||
|
)
|
||||||
|
|
||||||
|
R.effect(func(_arg):
|
||||||
|
logo.visible=show_image.value
|
||||||
|
)
|
||||||
|
|
||||||
icon.value = "pause_circle"
|
icon.value = "pause_circle"
|
||||||
|
|
||||||
var stateInfo = await HomeApi.get_state(entity_id)
|
var stateInfo = await HomeApi.get_state(entity_id)
|
||||||
|
@ -94,3 +120,13 @@ func load_image(url: String):
|
||||||
var texture = ImageTexture.create_from_image(image)
|
var texture = ImageTexture.create_from_image(image)
|
||||||
logo.texture = texture
|
logo.texture = texture
|
||||||
logo.pixel_size = pixel_size
|
logo.pixel_size = pixel_size
|
||||||
|
|
||||||
|
func get_options():
|
||||||
|
return {
|
||||||
|
"show_volume": show_volume.value,
|
||||||
|
"show_image": show_image.value
|
||||||
|
}
|
||||||
|
|
||||||
|
func set_options(options):
|
||||||
|
if options.has("show_volume"): show_volume.value = options["show_volume"]
|
||||||
|
if options.has("show_image"): show_image.value = options["show_image"]
|
|
@ -1,10 +1,12 @@
|
||||||
[gd_scene load_steps=7 format=3 uid="uid://dyktdg7ggiwl4"]
|
[gd_scene load_steps=9 format=3 uid="uid://dyktdg7ggiwl4"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_8opk3"]
|
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="1_8opk3"]
|
||||||
[ext_resource type="Script" path="res://content/entities/media_player/media_player.gd" id="1_ame17"]
|
[ext_resource type="Script" path="res://content/entities/media_player/media_player.gd" id="1_ame17"]
|
||||||
|
[ext_resource type="Script" path="res://content/functions/camera_follower.gd" id="3_24ewx"]
|
||||||
[ext_resource type="Script" path="res://content/functions/movable.gd" id="3_bguto"]
|
[ext_resource type="Script" path="res://content/functions/movable.gd" id="3_bguto"]
|
||||||
[ext_resource type="PackedScene" uid="uid://pk5k1q8bx0rj" path="res://content/ui/components/slider/slider.tscn" id="4_w73hw"]
|
[ext_resource type="PackedScene" uid="uid://pk5k1q8bx0rj" path="res://content/ui/components/slider/slider.tscn" id="4_w73hw"]
|
||||||
[ext_resource type="FontVariation" uid="uid://sshfnckriqxn" path="res://assets/icons/icons.tres" id="5_koe28"]
|
[ext_resource type="FontVariation" uid="uid://sshfnckriqxn" path="res://assets/icons/icons.tres" id="5_koe28"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cm070pgl3s7gm" path="res://content/entities/media_player/settings.tscn" id="6_iuvm7"]
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_vi3eg"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_vi3eg"]
|
||||||
size = Vector3(0.23, 0.142768, 0.01)
|
size = Vector3(0.23, 0.142768, 0.01)
|
||||||
|
@ -13,6 +15,14 @@ size = Vector3(0.23, 0.142768, 0.01)
|
||||||
collision_mask = 0
|
collision_mask = 0
|
||||||
script = ExtResource("1_ame17")
|
script = ExtResource("1_ame17")
|
||||||
|
|
||||||
|
[node name="Movable" type="Node" parent="."]
|
||||||
|
script = ExtResource("3_bguto")
|
||||||
|
resizable = true
|
||||||
|
|
||||||
|
[node name="CameraFollower" type="Node" parent="." node_paths=PackedStringArray("focus_point")]
|
||||||
|
script = ExtResource("3_24ewx")
|
||||||
|
focus_point = NodePath("../Settings")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0364514, -0.01)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0364514, -0.01)
|
||||||
shape = SubResource("BoxShape3D_vi3eg")
|
shape = SubResource("BoxShape3D_vi3eg")
|
||||||
|
@ -56,10 +66,6 @@ pixel_size = 0.001
|
||||||
|
|
||||||
[node name="HTTPRequest" type="HTTPRequest" parent="PlayingInfo"]
|
[node name="HTTPRequest" type="HTTPRequest" parent="PlayingInfo"]
|
||||||
|
|
||||||
[node name="Movable" type="Node" parent="."]
|
|
||||||
script = ExtResource("3_bguto")
|
|
||||||
resizable = true
|
|
||||||
|
|
||||||
[node name="Slider" parent="." instance=ExtResource("4_w73hw")]
|
[node name="Slider" parent="." instance=ExtResource("4_w73hw")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0562844, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.0562844, 0)
|
||||||
max = 100.0
|
max = 100.0
|
||||||
|
@ -74,3 +80,6 @@ text = "volume_up"
|
||||||
font = ExtResource("5_koe28")
|
font = ExtResource("5_koe28")
|
||||||
font_size = 18
|
font_size = 18
|
||||||
outline_size = 4
|
outline_size = 4
|
||||||
|
|
||||||
|
[node name="Settings" parent="." instance=ExtResource("6_iuvm7")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.27, 0, 0)
|
||||||
|
|
30
app/content/entities/media_player/settings.gd
Normal file
30
app/content/entities/media_player/settings.gd
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
extends StaticBody3D
|
||||||
|
|
||||||
|
const MediaPlayer = preload ("./media_player.gd")
|
||||||
|
|
||||||
|
@onready var close_button: Button3D = $Close
|
||||||
|
@onready var id_input: Input3D = $IDInput
|
||||||
|
@onready var volume_button: Button3D = $VolumeButton
|
||||||
|
@onready var image_button: Button3D = $ImageButton
|
||||||
|
|
||||||
|
var media_player: MediaPlayer
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
media_player = get_parent()
|
||||||
|
|
||||||
|
close_button.on_button_up.connect(func():
|
||||||
|
media_player.show_settings.value=false
|
||||||
|
)
|
||||||
|
|
||||||
|
id_input.text = media_player.entity_id
|
||||||
|
|
||||||
|
R.effect(func(_arg):
|
||||||
|
volume_button.label="check" if media_player.show_volume.value else "close"
|
||||||
|
)
|
||||||
|
|
||||||
|
R.effect(func(_arg):
|
||||||
|
image_button.label="check" if media_player.show_image.value else "close"
|
||||||
|
)
|
||||||
|
|
||||||
|
R.bind(volume_button, "active", media_player.show_volume, volume_button.on_toggled)
|
||||||
|
R.bind(image_button, "active", media_player.show_image, image_button.on_toggled)
|
102
app/content/entities/media_player/settings.tscn
Normal file
102
app/content/entities/media_player/settings.tscn
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
[gd_scene load_steps=9 format=3 uid="uid://cm070pgl3s7gm"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://content/entities/media_player/settings.gd" id="1_03bil"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dnam3fe36gg62" path="res://content/ui/components/panel/panel.tscn" id="2_kt6qc"]
|
||||||
|
[ext_resource type="Shader" path="res://content/ui/components/panel/glass.gdshader" id="3_abcrk"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://bsjqdvkt0u87c" path="res://content/ui/components/button/button.tscn" id="4_u2igx"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://blrhy2uccrdn4" path="res://content/ui/components/input/input.tscn" id="5_1jm5m"]
|
||||||
|
|
||||||
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ncmoa"]
|
||||||
|
resource_local_to_scene = true
|
||||||
|
render_priority = 10
|
||||||
|
shader = ExtResource("3_abcrk")
|
||||||
|
shader_parameter/color = Color(1, 1, 1, 0.3)
|
||||||
|
shader_parameter/border_color = Color(1, 1, 1, 1)
|
||||||
|
shader_parameter/edge_color = Color(0, 0, 0, 1)
|
||||||
|
shader_parameter/size = Vector2(7.5, 5)
|
||||||
|
shader_parameter/border_size = 0.01
|
||||||
|
shader_parameter/border_fade_in = 0.05
|
||||||
|
shader_parameter/border_fade_out = 0.0
|
||||||
|
shader_parameter/corner_radius = 0.2
|
||||||
|
shader_parameter/roughness = 0.3
|
||||||
|
shader_parameter/grain_amount = 0.02
|
||||||
|
|
||||||
|
[sub_resource type="QuadMesh" id="QuadMesh_qm2qb"]
|
||||||
|
size = Vector2(0.3, 0.2)
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape3D" id="BoxShape3D_53oq0"]
|
||||||
|
size = Vector3(0.3, 0.2, 0.02)
|
||||||
|
|
||||||
|
[node name="Settings" type="StaticBody3D"]
|
||||||
|
script = ExtResource("1_03bil")
|
||||||
|
|
||||||
|
[node name="Panel" parent="." instance=ExtResource("2_kt6qc")]
|
||||||
|
material_override = SubResource("ShaderMaterial_ncmoa")
|
||||||
|
mesh = SubResource("QuadMesh_qm2qb")
|
||||||
|
skeleton = NodePath("../..")
|
||||||
|
size = Vector2(0.3, 0.2)
|
||||||
|
|
||||||
|
[node name="Name" type="Label3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.14, 0.07, 0)
|
||||||
|
pixel_size = 0.001
|
||||||
|
render_priority = 15
|
||||||
|
outline_render_priority = 14
|
||||||
|
text = "Media Player Settings"
|
||||||
|
font_size = 20
|
||||||
|
outline_size = 0
|
||||||
|
horizontal_alignment = 0
|
||||||
|
|
||||||
|
[node name="Close" parent="." instance=ExtResource("4_u2igx")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.12, 0.07, 0)
|
||||||
|
label = "close"
|
||||||
|
icon = true
|
||||||
|
|
||||||
|
[node name="IDLabel" type="Label3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.14, 0.03, 0)
|
||||||
|
pixel_size = 0.001
|
||||||
|
render_priority = 15
|
||||||
|
outline_render_priority = 14
|
||||||
|
text = "ID:"
|
||||||
|
font_size = 18
|
||||||
|
outline_size = 0
|
||||||
|
horizontal_alignment = 0
|
||||||
|
|
||||||
|
[node name="IDInput" parent="." instance=ExtResource("5_1jm5m")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.03, 0.03, 0)
|
||||||
|
disabled = true
|
||||||
|
|
||||||
|
[node name="VideoLabel" type="Label3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.14, -0.02, 0)
|
||||||
|
pixel_size = 0.001
|
||||||
|
render_priority = 15
|
||||||
|
outline_render_priority = 14
|
||||||
|
text = "Show Volume:"
|
||||||
|
font_size = 18
|
||||||
|
outline_size = 0
|
||||||
|
horizontal_alignment = 0
|
||||||
|
|
||||||
|
[node name="VolumeButton" parent="." instance=ExtResource("4_u2igx")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.02, -0.02, 0)
|
||||||
|
label = "close"
|
||||||
|
icon = true
|
||||||
|
toggleable = true
|
||||||
|
|
||||||
|
[node name="VideoLabel2" type="Label3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.14, -0.07, 0)
|
||||||
|
pixel_size = 0.001
|
||||||
|
render_priority = 15
|
||||||
|
outline_render_priority = 14
|
||||||
|
text = "Show Image:"
|
||||||
|
font_size = 18
|
||||||
|
outline_size = 0
|
||||||
|
horizontal_alignment = 0
|
||||||
|
|
||||||
|
[node name="ImageButton" parent="." instance=ExtResource("4_u2igx")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.02, -0.07, 0)
|
||||||
|
label = "close"
|
||||||
|
icon = true
|
||||||
|
toggleable = true
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.01)
|
||||||
|
shape = SubResource("BoxShape3D_53oq0")
|
|
@ -43,7 +43,7 @@ func _on_action_value(event: EventAction):
|
||||||
if event.name != "primary"||event.initiator != initiator:
|
if event.name != "primary"||event.initiator != initiator:
|
||||||
return
|
return
|
||||||
|
|
||||||
relative_transform = relative_transform.translated(Vector3(0, 0, -event.value.y * 0.05))
|
relative_transform = relative_transform.translated(Vector3(0, 0, -event.value.y * 0.05)).rotated_local(Vector3(0, 1, 0), event.value.x * 0.05)
|
||||||
|
|
||||||
func _on_grab_down(event: EventPointer):
|
func _on_grab_down(event: EventPointer):
|
||||||
if disabled:
|
if disabled:
|
||||||
|
|
|
@ -125,9 +125,9 @@ func _setup_hand():
|
||||||
auto_hand.hand_active_changed.connect(func(hand: int, active: bool):
|
auto_hand.hand_active_changed.connect(func(hand: int, active: bool):
|
||||||
if hand != 0: return
|
if hand != 0: return
|
||||||
|
|
||||||
hand_active=active
|
hand_active=active&&_is_hand_simulated() == false
|
||||||
|
|
||||||
$IndexTip/TouchArea/CollisionShape3D.disabled=!active
|
$IndexTip/TouchArea/CollisionShape3D.disabled=!hand_active
|
||||||
hand_mesh.visible=active
|
hand_mesh.visible=active
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -155,6 +155,17 @@ func _setup_hand():
|
||||||
pointer = Pointer.new(initiator, ray)
|
pointer = Pointer.new(initiator, ray)
|
||||||
add_child(pointer)
|
add_child(pointer)
|
||||||
|
|
||||||
|
func _is_hand_simulated():
|
||||||
|
var hand_trackers = XRServer.get_trackers(XRServer.TRACKER_HAND)
|
||||||
|
|
||||||
|
for tracker in hand_trackers.values():
|
||||||
|
if tracker.hand != XRPositionalTracker.TrackerHand.TRACKER_HAND_LEFT:
|
||||||
|
continue
|
||||||
|
|
||||||
|
return tracker.hand_tracking_source == XRHandTracker.HAND_TRACKING_SOURCE_CONTROLLER
|
||||||
|
|
||||||
|
return false
|
||||||
|
|
||||||
func _get_entity(node: Node):
|
func _get_entity(node: Node):
|
||||||
if node is Entity:
|
if node is Entity:
|
||||||
return node
|
return node
|
||||||
|
|
|
@ -56,9 +56,9 @@ func _setup_hand():
|
||||||
auto_hand.hand_active_changed.connect(func(hand: int, active: bool):
|
auto_hand.hand_active_changed.connect(func(hand: int, active: bool):
|
||||||
if hand != 1: return
|
if hand != 1: return
|
||||||
|
|
||||||
hand_active=active
|
hand_active=active&&_is_hand_simulated() == false
|
||||||
|
|
||||||
$IndexTip/TouchArea/CollisionShape3D.disabled=!active
|
$IndexTip/TouchArea/CollisionShape3D.disabled=!hand_active
|
||||||
hand_mesh.visible=active
|
hand_mesh.visible=active
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -83,4 +83,15 @@ func _physics_process(_delta):
|
||||||
grabbed = true
|
grabbed = true
|
||||||
elif !grab_close&&grabbed:
|
elif !grab_close&&grabbed:
|
||||||
pointer.released(Initiator.EventType.GRIP)
|
pointer.released(Initiator.EventType.GRIP)
|
||||||
grabbed = false
|
grabbed = false
|
||||||
|
|
||||||
|
func _is_hand_simulated():
|
||||||
|
var hand_trackers = XRServer.get_trackers(XRServer.TRACKER_HAND)
|
||||||
|
|
||||||
|
for tracker in hand_trackers.values():
|
||||||
|
if tracker.hand != XRPositionalTracker.TrackerHand.TRACKER_HAND_RIGHT:
|
||||||
|
continue
|
||||||
|
|
||||||
|
return tracker.hand_tracking_source == XRHandTracker.HAND_TRACKING_SOURCE_CONTROLLER
|
||||||
|
|
||||||
|
return false
|
|
@ -29,6 +29,9 @@ mesh = SubResource("BoxMesh_ir3co")
|
||||||
|
|
||||||
[node name="AutoHandtracker" parent="." instance=ExtResource("3_pjmb2")]
|
[node name="AutoHandtracker" parent="." instance=ExtResource("3_pjmb2")]
|
||||||
visible = false
|
visible = false
|
||||||
|
applymiddlefingerfix = null
|
||||||
|
applyscaling = null
|
||||||
|
coincidewristorknuckle = null
|
||||||
visiblehandtrackskeleton = false
|
visiblehandtrackskeleton = false
|
||||||
enableautotracker = false
|
enableautotracker = false
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
extends StaticBody3D
|
extends StaticBody3D
|
||||||
|
|
||||||
const Entity = preload ("res://content/entities/entity.gd")
|
const Entity = preload ("res://content/entities/entity.gd")
|
||||||
|
const Light = preload ("res://content/entities/light/light.gd")
|
||||||
|
|
||||||
const TOUCH_LONG = 400.0
|
const TOUCH_LONG = 400.0
|
||||||
|
|
||||||
|
@ -9,6 +10,7 @@ const TOUCH_LONG = 400.0
|
||||||
@onready var collision = $CollisionShape3D
|
@onready var collision = $CollisionShape3D
|
||||||
@onready var area = $Area3D/CollisionShape3D2
|
@onready var area = $Area3D/CollisionShape3D2
|
||||||
@onready var snap_sound = $SnapSound
|
@onready var snap_sound = $SnapSound
|
||||||
|
# @onready var light: OmniLight3D = $OmniLight3D
|
||||||
@onready var label = $Label3D
|
@onready var label = $Label3D
|
||||||
var active = R.state(false)
|
var active = R.state(false)
|
||||||
var disabled = null
|
var disabled = null
|
||||||
|
@ -17,6 +19,16 @@ var moved_ran = false
|
||||||
var touch_ran = false
|
var touch_ran = false
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
|
# Wait until https://github.com/godotengine/godot/pull/83360 is merged for faster vertex lighting
|
||||||
|
# if entity is Light:
|
||||||
|
# R.effect(func(_arg):
|
||||||
|
# light.light_energy=1 if entity.active.value else 0
|
||||||
|
# light.light_color=entity.color.value
|
||||||
|
# )
|
||||||
|
# else:
|
||||||
|
# remove_child(light)
|
||||||
|
# light.queue_free()
|
||||||
|
|
||||||
R.effect(func(_arg):
|
R.effect(func(_arg):
|
||||||
label.text=entity.icon.value
|
label.text=entity.icon.value
|
||||||
label.modulate=entity.icon_color.value
|
label.modulate=entity.icon_color.value
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
extends Node3D
|
extends Node3D
|
||||||
|
|
||||||
const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd")
|
const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd")
|
||||||
|
const ConstructDoorMesh = preload ("res://lib/utils/mesh/construct_door_mesh.gd")
|
||||||
|
const RoomMaterial = preload ("res://content/system/house/room/states/room.tres")
|
||||||
|
|
||||||
@onready var wall_corners = $Ceiling/WallCorners
|
@onready var wall_corners = $Ceiling/WallCorners
|
||||||
@onready var wall_edges = $Ceiling/WallEdges
|
@onready var wall_edges = $Ceiling/WallEdges
|
||||||
|
@ -10,6 +12,7 @@ const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd"
|
||||||
|
|
||||||
@onready var room_floor = $Floor
|
@onready var room_floor = $Floor
|
||||||
@onready var room_ceiling = $Ceiling
|
@onready var room_ceiling = $Ceiling
|
||||||
|
@onready var doors = $Doors
|
||||||
|
|
||||||
@onready var state_machine: StateMachine = $StateMachine
|
@onready var state_machine: StateMachine = $StateMachine
|
||||||
|
|
||||||
|
@ -84,3 +87,29 @@ static func generate_ceiling_mesh(room: Dictionary):
|
||||||
var corners = room.corners
|
var corners = room.corners
|
||||||
|
|
||||||
return ConstructRoomMesh.generate_ceiling_mesh(corners)
|
return ConstructRoomMesh.generate_ceiling_mesh(corners)
|
||||||
|
|
||||||
|
func generate_doors_mesh():
|
||||||
|
for door in Store.house.state.doors:
|
||||||
|
if door.room1 != name:
|
||||||
|
continue
|
||||||
|
|
||||||
|
var door_mesh = MeshInstance3D.new()
|
||||||
|
|
||||||
|
doors.add_child(door_mesh)
|
||||||
|
|
||||||
|
if Geometry2D.is_polygon_clockwise([
|
||||||
|
Vector2(door.room1_position1.x, door.room1_position1.z),
|
||||||
|
Vector2(door.room2_position1.x, door.room2_position1.z),
|
||||||
|
Vector2(door.room2_position2.x, door.room2_position2.z),
|
||||||
|
Vector2(door.room1_position2.x, door.room1_position2.z)
|
||||||
|
]):
|
||||||
|
door_mesh.mesh = ConstructDoorMesh.generate_door_mesh(door.room1_position2, door.room2_position2, door.room2_position1, door.room1_position1)
|
||||||
|
else:
|
||||||
|
door_mesh.mesh = ConstructDoorMesh.generate_door_mesh(door.room1_position1, door.room2_position1, door.room2_position2, door.room1_position2)
|
||||||
|
|
||||||
|
door_mesh.material_override = RoomMaterial
|
||||||
|
|
||||||
|
func clear_doors_mesh():
|
||||||
|
for door in doors.get_children():
|
||||||
|
doors.remove_child(door)
|
||||||
|
door.queue_free()
|
|
@ -1,24 +1,14 @@
|
||||||
[gd_scene load_steps=12 format=3 uid="uid://bswgmclohuqui"]
|
[gd_scene load_steps=9 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="Material" uid="uid://xehjkoeofqc" path="res://content/system/house/room/room_next.tres" id="3_4q8ik"]
|
[ext_resource type="Material" uid="uid://d0i5oae6evn08" path="res://content/system/house/room/states/room.tres" id="3_fmi1g"]
|
||||||
[ext_resource type="Shader" path="res://content/system/house/room/room.gdshader" id="3_lwge0"]
|
|
||||||
[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/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"]
|
||||||
|
|
||||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_08sv0"]
|
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_08sv0"]
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_rqpss"]
|
|
||||||
render_priority = -100
|
|
||||||
next_pass = ExtResource("3_4q8ik")
|
|
||||||
shader = ExtResource("3_lwge0")
|
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_1hn7n"]
|
|
||||||
render_priority = -100
|
|
||||||
shader = ExtResource("3_lwge0")
|
|
||||||
|
|
||||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ap613"]
|
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ap613"]
|
||||||
plane = Plane(0, -1, 0, 0)
|
plane = Plane(0, -1, 0, 0)
|
||||||
|
|
||||||
|
@ -36,10 +26,10 @@ shape = SubResource("WorldBoundaryShape3D_08sv0")
|
||||||
script = ExtResource("1_ugebq")
|
script = ExtResource("1_ugebq")
|
||||||
|
|
||||||
[node name="WallMesh" type="MeshInstance3D" parent="."]
|
[node name="WallMesh" type="MeshInstance3D" parent="."]
|
||||||
material_override = SubResource("ShaderMaterial_rqpss")
|
material_override = ExtResource("3_fmi1g")
|
||||||
|
|
||||||
[node name="CeilingMesh" type="MeshInstance3D" parent="."]
|
[node name="CeilingMesh" type="MeshInstance3D" parent="."]
|
||||||
material_override = SubResource("ShaderMaterial_1hn7n")
|
material_override = ExtResource("3_fmi1g")
|
||||||
|
|
||||||
[node name="WallCollision" type="StaticBody3D" parent="."]
|
[node name="WallCollision" type="StaticBody3D" parent="."]
|
||||||
collision_layer = 24
|
collision_layer = 24
|
||||||
|
@ -76,4 +66,6 @@ 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="Doors" type="Node3D" parent="."]
|
||||||
|
|
||||||
[node name="Entities" type="Node3D" parent="."]
|
[node name="Entities" type="Node3D" parent="."]
|
||||||
|
|
9
app/content/system/house/room/states/room.tres
Normal file
9
app/content/system/house/room/states/room.tres
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://d0i5oae6evn08"]
|
||||||
|
|
||||||
|
[ext_resource type="Material" uid="uid://xehjkoeofqc" path="res://content/system/house/room/room_next.tres" id="1_irw15"]
|
||||||
|
[ext_resource type="Shader" path="res://content/system/house/room/room.gdshader" id="2_hhffe"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
render_priority = -100
|
||||||
|
next_pass = ExtResource("1_irw15")
|
||||||
|
shader = ExtResource("2_hhffe")
|
|
@ -30,10 +30,14 @@ func _on_enter():
|
||||||
wall_collisions.backface_collision = true
|
wall_collisions.backface_collision = true
|
||||||
room.wall_collision.shape = wall_collisions
|
room.wall_collision.shape = wall_collisions
|
||||||
|
|
||||||
|
room.generate_doors_mesh()
|
||||||
|
|
||||||
func _on_leave():
|
func _on_leave():
|
||||||
room.room_ceiling.get_node("CollisionShape3D").disabled = true
|
room.room_ceiling.get_node("CollisionShape3D").disabled = true
|
||||||
room.room_floor.get_node("CollisionShape3D").disabled = true
|
room.room_floor.get_node("CollisionShape3D").disabled = true
|
||||||
|
|
||||||
room.wall_collision.shape = null
|
room.wall_collision.shape = null
|
||||||
room.wall_mesh.mesh = null
|
room.wall_mesh.mesh = null
|
||||||
room.ceiling_mesh.mesh = null
|
room.ceiling_mesh.mesh = null
|
||||||
|
|
||||||
|
room.clear_doors_mesh()
|
|
@ -5,3 +5,8 @@
|
||||||
[resource]
|
[resource]
|
||||||
render_priority = 0
|
render_priority = 0
|
||||||
shader = ExtResource("1_sbr3e")
|
shader = ExtResource("1_sbr3e")
|
||||||
|
shader_parameter/data = null
|
||||||
|
shader_parameter/data_size = null
|
||||||
|
shader_parameter/alpha = 0.3
|
||||||
|
shader_parameter/roughness = 0.85
|
||||||
|
shader_parameter/edge_color = Color(0, 0, 0, 1)
|
||||||
|
|
|
@ -63,22 +63,22 @@ void fragment() {
|
||||||
ROUGHNESS = roughness;
|
ROUGHNESS = roughness;
|
||||||
DEPTH = FRAGCOORD.z + 0.0001;
|
DEPTH = FRAGCOORD.z + 0.0001;
|
||||||
ALBEDO = vec3(color.xyz);
|
ALBEDO = vec3(color.xyz);
|
||||||
|
|
||||||
vec2 pos = vec2(UV.x * aspect_ratio.x, UV.y * aspect_ratio.y);
|
vec2 pos = vec2(UV.x * aspect_ratio.x, UV.y * aspect_ratio.y);
|
||||||
float border = 0.05;
|
float border = 0.05;
|
||||||
|
|
||||||
if (pos.x <= border) {
|
if (pos.x <= border) {
|
||||||
ALBEDO = mix(vec3(0.0), ALBEDO, pos.x / border);
|
ALBEDO = mix(vec3(0.0), ALBEDO, pos.x / border);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos.x >= aspect_ratio.x - border) {
|
if (pos.x >= aspect_ratio.x - border) {
|
||||||
ALBEDO = mix(vec3(0.0), ALBEDO, 1.0 - (pos.x - (aspect_ratio.x - border)) / border);
|
ALBEDO = mix(vec3(0.0), ALBEDO, 1.0 - (pos.x - (aspect_ratio.x - border)) / border);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos.y <= border) {
|
if (pos.y <= border) {
|
||||||
ALBEDO = mix(vec3(0.0), ALBEDO, pos.y / border);
|
ALBEDO = mix(vec3(0.0), ALBEDO, pos.y / border);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pos.y >= aspect_ratio.y - border) {
|
if (pos.y >= aspect_ratio.y - border) {
|
||||||
ALBEDO = mix(vec3(0.0), ALBEDO, 1.0 - (pos.y - (aspect_ratio.y - border)) / border);
|
ALBEDO = mix(vec3(0.0), ALBEDO, 1.0 - (pos.y - (aspect_ratio.y - border)) / border);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
extends Node3D
|
extends Node3D
|
||||||
|
|
||||||
const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd")
|
const ConstructRoomMesh = preload ("res://lib/utils/mesh/construct_room_mesh.gd")
|
||||||
|
const ConstructDoorMesh = preload ("res://lib/utils/mesh/construct_door_mesh.gd")
|
||||||
const wall_material = preload ("./mini_wall.tres")
|
const wall_material = preload ("./mini_wall.tres")
|
||||||
const humidity_gradient = preload ("./humid_gradient.tres")
|
const humidity_gradient = preload ("./humid_gradient.tres")
|
||||||
const temperature_gradient = preload ("./temp_gradient.tres")
|
const temperature_gradient = preload ("./temp_gradient.tres")
|
||||||
|
@ -78,6 +79,28 @@ func _ready():
|
||||||
|
|
||||||
walls_mesh.material_override=wall_material
|
walls_mesh.material_override=wall_material
|
||||||
floor_mesh.material_override=wall_material
|
floor_mesh.material_override=wall_material
|
||||||
|
|
||||||
|
walls_mesh.set_layer_mask_value(2, true)
|
||||||
|
floor_mesh.set_layer_mask_value(2, true)
|
||||||
|
|
||||||
|
for door in Store.house.state.doors:
|
||||||
|
var door_mesh=MeshInstance3D.new()
|
||||||
|
|
||||||
|
model.add_child(door_mesh)
|
||||||
|
|
||||||
|
if Geometry2D.is_polygon_clockwise([
|
||||||
|
Vector2(door.room1_position1.x, door.room1_position1.z),
|
||||||
|
Vector2(door.room2_position1.x, door.room2_position1.z),
|
||||||
|
Vector2(door.room2_position2.x, door.room2_position2.z),
|
||||||
|
Vector2(door.room1_position2.x, door.room1_position2.z)
|
||||||
|
]):
|
||||||
|
door_mesh.mesh=ConstructDoorMesh.generate_door_mesh(door.room1_position2, door.room2_position2, door.room2_position1, door.room1_position1)
|
||||||
|
else:
|
||||||
|
door_mesh.mesh=ConstructDoorMesh.generate_door_mesh(door.room1_position1, door.room2_position1, door.room2_position2, door.room1_position2)
|
||||||
|
|
||||||
|
door_mesh.material_override=wall_material
|
||||||
|
|
||||||
|
door_mesh.set_layer_mask_value(2, true)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update Size
|
# Update Size
|
||||||
|
|
163
app/lib/utils/mesh/construct_door_mesh.gd
Normal file
163
app/lib/utils/mesh/construct_door_mesh.gd
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
## Generate a door mesh between two rooms based on their upper left and right corners
|
||||||
|
static func generate_door_mesh(room1_pos1: Vector3, room2_pos1: Vector3, room2_pos2: Vector3, room1_pos2: Vector3):
|
||||||
|
var st = SurfaceTool.new()
|
||||||
|
|
||||||
|
st.begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||||
|
st.set_custom_format(0, SurfaceTool.CUSTOM_RG_FLOAT)
|
||||||
|
|
||||||
|
var points = [room1_pos1, room2_pos1, room2_pos2, room1_pos2, Vector3(room1_pos1.x, 0, room1_pos1.z), Vector3(room2_pos1.x, 0, room2_pos1.z), Vector3(room2_pos2.x, 0, room2_pos2.z), Vector3(room1_pos2.x, 0, room1_pos2.z)]
|
||||||
|
|
||||||
|
# Add top face
|
||||||
|
add_quad(st, points, 0, 1, 2, 3)
|
||||||
|
|
||||||
|
# Add bottom face
|
||||||
|
add_quad(st, points, 5, 4, 7, 6)
|
||||||
|
|
||||||
|
# Add side faces
|
||||||
|
add_quad(st, points, 0, 4, 5, 1)
|
||||||
|
add_quad(st, points, 2, 6, 7, 3)
|
||||||
|
|
||||||
|
st.deindex()
|
||||||
|
st.generate_normals()
|
||||||
|
st.generate_tangents()
|
||||||
|
|
||||||
|
return st.commit()
|
||||||
|
|
||||||
|
static func generate_door_mesh_grid(room1_pos1: Vector3, room2_pos1: Vector3, room2_pos2: Vector3, room1_pos2: Vector3, grid:=0.1):
|
||||||
|
var st = SurfaceTool.new()
|
||||||
|
|
||||||
|
var room1_pos1_bottom = Vector3(room1_pos1.x, 0, room1_pos1.z)
|
||||||
|
var room2_pos1_bottom = Vector3(room2_pos1.x, 0, room2_pos1.z)
|
||||||
|
var room2_pos2_bottom = Vector3(room2_pos2.x, 0, room2_pos2.z)
|
||||||
|
var room1_pos2_bottom = Vector3(room1_pos2.x, 0, room1_pos2.z)
|
||||||
|
|
||||||
|
st.begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||||
|
st.set_custom_format(0, SurfaceTool.CUSTOM_RG_FLOAT)
|
||||||
|
|
||||||
|
# Add top
|
||||||
|
add_quad_grid(st, room1_pos1, room1_pos2, room2_pos2, room2_pos1, false, grid)
|
||||||
|
|
||||||
|
# Add bottom
|
||||||
|
add_quad_grid(st, room1_pos1_bottom, room1_pos2_bottom, room2_pos2_bottom, room2_pos1_bottom, true, grid)
|
||||||
|
|
||||||
|
# Add side faces
|
||||||
|
add_quad_grid(st, room1_pos1, room1_pos1_bottom, room2_pos1_bottom, room2_pos1, true, grid)
|
||||||
|
add_quad_grid(st, room1_pos2, room1_pos2_bottom, room2_pos2_bottom, room2_pos2, false, grid)
|
||||||
|
|
||||||
|
st.deindex()
|
||||||
|
st.generate_normals()
|
||||||
|
st.generate_tangents()
|
||||||
|
|
||||||
|
return st.commit()
|
||||||
|
|
||||||
|
static func add_quad(st: SurfaceTool, points, index1: int, index2: int, index3: int, index4: int):
|
||||||
|
st.set_uv(Vector2(0.0, 0.0))
|
||||||
|
st.set_custom(0, Color(2.0, 2.0, 0, 0))
|
||||||
|
st.add_vertex(points[index1])
|
||||||
|
|
||||||
|
st.set_uv(Vector2(1.0, 1.0))
|
||||||
|
st.set_custom(0, Color(2.0, 2.0, 0, 0))
|
||||||
|
st.add_vertex(points[index3])
|
||||||
|
|
||||||
|
st.set_uv(Vector2(1.0, 0.0))
|
||||||
|
st.set_custom(0, Color(2.0, 2.0, 0, 0))
|
||||||
|
st.add_vertex(points[index2])
|
||||||
|
|
||||||
|
st.set_uv(Vector2(0.0, 0.0))
|
||||||
|
st.set_custom(0, Color(2.0, 2.0, 0, 0))
|
||||||
|
st.add_vertex(points[index1])
|
||||||
|
|
||||||
|
st.set_uv(Vector2(0.0, 1.0))
|
||||||
|
st.set_custom(0, Color(2.0, 2.0, 0, 0))
|
||||||
|
st.add_vertex(points[index4])
|
||||||
|
|
||||||
|
st.set_uv(Vector2(1.0, 1.0))
|
||||||
|
st.set_custom(0, Color(2.0, 2.0, 0, 0))
|
||||||
|
st.add_vertex(points[index3])
|
||||||
|
|
||||||
|
static func add_quad_grid(st: SurfaceTool, p1: Vector3, p2: Vector3, p3: Vector3, p4: Vector3, flipped: bool=false, grid:=1.0):
|
||||||
|
var d1 = (p2 - p1).normalized()
|
||||||
|
var d2 = (p4 - p1).normalized()
|
||||||
|
|
||||||
|
var n1 = d1.cross(d2).normalized()
|
||||||
|
|
||||||
|
var transform_local = Transform3D(d1, n1, d2, p1)
|
||||||
|
|
||||||
|
var lp1 = transform_local.affine_inverse() * p1
|
||||||
|
var lp2 = transform_local.affine_inverse() * p2
|
||||||
|
var lp3 = transform_local.affine_inverse() * p3
|
||||||
|
var lp4 = transform_local.affine_inverse() * p4
|
||||||
|
|
||||||
|
lp1 = Vector2(lp1.x, lp1.z)
|
||||||
|
lp2 = Vector2(lp2.x, lp2.z)
|
||||||
|
lp3 = Vector2(lp3.x, lp3.z)
|
||||||
|
lp4 = Vector2(lp4.x, lp4.z)
|
||||||
|
|
||||||
|
var points = PackedVector2Array()
|
||||||
|
|
||||||
|
# Generate edges
|
||||||
|
var edge_points = [lp1, lp2, lp3, lp4]
|
||||||
|
|
||||||
|
for i in range(4):
|
||||||
|
var delta: Vector2 = edge_points[(i + 1) % 4] - edge_points[i]
|
||||||
|
|
||||||
|
var steps = ceil(delta.length() / grid)
|
||||||
|
|
||||||
|
for j in range(steps):
|
||||||
|
var p = edge_points[i] + delta.normalized() * j * grid
|
||||||
|
points.push_back(p)
|
||||||
|
|
||||||
|
var edges = PackedInt32Array()
|
||||||
|
|
||||||
|
for k in range(points.size()):
|
||||||
|
edges.append(k)
|
||||||
|
edges.append((k + 1) % points.size())
|
||||||
|
|
||||||
|
# Generate points
|
||||||
|
var rect = Rect2()
|
||||||
|
rect = rect.expand(lp1)
|
||||||
|
rect = rect.expand(lp2)
|
||||||
|
rect = rect.expand(lp3)
|
||||||
|
rect = rect.expand(lp4)
|
||||||
|
|
||||||
|
var ls = rect.position
|
||||||
|
var ld1 = rect.size.x
|
||||||
|
var ld2 = rect.size.y
|
||||||
|
|
||||||
|
var steps = Vector2(ld1 / grid, ld2 / grid).ceil() + Vector2(2, 2)
|
||||||
|
|
||||||
|
for i in range(steps.x):
|
||||||
|
for j in range(steps.y):
|
||||||
|
var p = Vector2(i, j) * grid + ls - Vector2(0.5, 0.5) * grid
|
||||||
|
points.push_back(p)
|
||||||
|
|
||||||
|
# Triangulate
|
||||||
|
var cdt: ConstrainedTriangulation = ConstrainedTriangulation.new()
|
||||||
|
cdt.init(true, true, 0.01)
|
||||||
|
|
||||||
|
cdt.insert_vertices(points)
|
||||||
|
cdt.insert_edges(edges)
|
||||||
|
|
||||||
|
cdt.erase_outer_triangles()
|
||||||
|
|
||||||
|
points = cdt.get_all_vertices()
|
||||||
|
var triangles: PackedInt32Array = cdt.get_all_triangles()
|
||||||
|
|
||||||
|
var points3D = PackedVector3Array()
|
||||||
|
|
||||||
|
for i in range(points.size()):
|
||||||
|
var pos3D = transform_local * Vector3(points[i].x, 0, points[i].y)
|
||||||
|
|
||||||
|
points3D.push_back(pos3D)
|
||||||
|
|
||||||
|
if flipped:
|
||||||
|
for i in range(triangles.size() / 3):
|
||||||
|
var temp = triangles[i * 3]
|
||||||
|
triangles[i * 3] = triangles[i * 3 + 1]
|
||||||
|
triangles[i * 3 + 1] = temp
|
||||||
|
|
||||||
|
for i in range(triangles.size()):
|
||||||
|
st.set_uv(Vector2(0.5, 0.5))
|
||||||
|
st.set_custom(0, Color(1.0, 1.0, 0, 0))
|
||||||
|
st.add_vertex(points3D[triangles[i]])
|
||||||
|
|
|
@ -138,7 +138,7 @@ static func generate_ceiling_mesh(corners):
|
||||||
|
|
||||||
return _create_mesh_2d(points, triangles)
|
return _create_mesh_2d(points, triangles)
|
||||||
|
|
||||||
static func generate_wall_mesh_with_doors_grid(corners, height, doors, grid:=0.1):
|
static func generate_wall_mesh_with_doors_grid(corners, height, doors, grid:=0.2):
|
||||||
if corners.size() < 3:
|
if corners.size() < 3:
|
||||||
return null
|
return null
|
||||||
|
|
||||||
|
@ -241,7 +241,7 @@ static func generate_wall_mesh_with_doors_grid(corners, height, doors, grid:=0.1
|
||||||
|
|
||||||
return mesh
|
return mesh
|
||||||
|
|
||||||
static func generate_wall_mesh_grid(corners, height, grid: Vector2=Vector2(0.1, 0.1)):
|
static func generate_wall_mesh_grid(corners, height, grid: Vector2=Vector2(0.2, 0.2)):
|
||||||
if corners.size() < 3:
|
if corners.size() < 3:
|
||||||
return null
|
return null
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ static func generate_wall_mesh_grid(corners, height, grid: Vector2=Vector2(0.1,
|
||||||
|
|
||||||
return mesh
|
return mesh
|
||||||
|
|
||||||
static func generate_ceiling_mesh_grid(corners, grid: Vector2=Vector2(0.1, 0.1)):
|
static func generate_ceiling_mesh_grid(corners, grid: Vector2=Vector2(0.2, 0.2)):
|
||||||
var points: PackedVector2Array = PackedVector2Array()
|
var points: PackedVector2Array = PackedVector2Array()
|
||||||
var edges: PackedInt32Array = PackedInt32Array()
|
var edges: PackedInt32Array = PackedInt32Array()
|
||||||
var triangles: PackedInt32Array
|
var triangles: PackedInt32Array
|
||||||
|
|
|
@ -46,7 +46,8 @@ enabled=PackedStringArray("res://addons/godot-xr-tools/plugin.cfg")
|
||||||
folder_colors={
|
folder_colors={
|
||||||
"res://assets/": "blue",
|
"res://assets/": "blue",
|
||||||
"res://content/": "teal",
|
"res://content/": "teal",
|
||||||
"res://lib/": "yellow"
|
"res://lib/": "yellow",
|
||||||
|
"res://test/": "purple"
|
||||||
}
|
}
|
||||||
|
|
||||||
[filesystem]
|
[filesystem]
|
||||||
|
|
15
app/test/lib/utils/mesh/construct_door_mesh.gd
Normal file
15
app/test/lib/utils/mesh/construct_door_mesh.gd
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
@tool
|
||||||
|
extends Node3D
|
||||||
|
|
||||||
|
const ConstructDoorMesh = preload ("res://lib/utils/mesh/construct_door_mesh.gd")
|
||||||
|
|
||||||
|
@onready var door_mesh = $DoorMesh
|
||||||
|
@onready var door_mesh_grid = $DoorMeshGrid
|
||||||
|
@onready var room1_pos1 = $Room1Pos1
|
||||||
|
@onready var room1_pos2 = $Room1Pos2
|
||||||
|
@onready var room2_pos1 = $Room2Pos1
|
||||||
|
@onready var room2_pos2 = $Room2Pos2
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
door_mesh.mesh = ConstructDoorMesh.generate_door_mesh(room1_pos1.position, room2_pos1.position, room2_pos2.position, room1_pos2.position)
|
||||||
|
door_mesh_grid.mesh = ConstructDoorMesh.generate_door_mesh_grid(room1_pos1.position, room2_pos1.position, room2_pos2.position, room1_pos2.position)
|
72
app/test/lib/utils/mesh/construct_door_mesh.tscn
Normal file
72
app/test/lib/utils/mesh/construct_door_mesh.tscn
Normal file
File diff suppressed because one or more lines are too long
20
custom_components/immersive_home/manifest.json
Normal file
20
custom_components/immersive_home/manifest.json
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
"domain": "immersive_home",
|
||||||
|
"name": "ImmersiveHome",
|
||||||
|
"codeowners": [
|
||||||
|
"@nitwel"
|
||||||
|
],
|
||||||
|
"config_flow": true,
|
||||||
|
"dependencies": [
|
||||||
|
"http",
|
||||||
|
"websocket_api"
|
||||||
|
],
|
||||||
|
"documentation": "https://docs.immersive-home.org",
|
||||||
|
"homekit": {},
|
||||||
|
"iot_class": "local_push",
|
||||||
|
"issue_tracker": "https://github.com/Nitwel/Immersive-Home/issues",
|
||||||
|
"requirements": [],
|
||||||
|
"ssdp": [],
|
||||||
|
"version": "0.0.1",
|
||||||
|
"zeroconf": []
|
||||||
|
}
|
8
hacs.json
Normal file
8
hacs.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"name": "Immersive Home",
|
||||||
|
"content_in_root": false,
|
||||||
|
"zip_release": true,
|
||||||
|
"filename": "Integration.zip",
|
||||||
|
"render_readme": true,
|
||||||
|
"hide_default_branch": true
|
||||||
|
}
|
14
vendors/home_assistant_integration/manifest.json
vendored
14
vendors/home_assistant_integration/manifest.json
vendored
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
"domain": "immersive_home",
|
|
||||||
"name": "ImmersiveHome",
|
|
||||||
"codeowners": ["@nitwel"],
|
|
||||||
"config_flow": true,
|
|
||||||
"dependencies": ["http", "websocket_api"],
|
|
||||||
"documentation": "https://www.home-assistant.io/integrations/immersive_home",
|
|
||||||
"homekit": {},
|
|
||||||
"iot_class": "local_push",
|
|
||||||
"requirements": [],
|
|
||||||
"ssdp": [],
|
|
||||||
"zeroconf": [],
|
|
||||||
"version": "0.0.1"
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user