diff --git a/app/content/system/house/mini/mini_wall.tres b/app/content/system/house/mini/mini_wall.tres index 05daa0c..ea81d20 100644 --- a/app/content/system/house/mini/mini_wall.tres +++ b/app/content/system/house/mini/mini_wall.tres @@ -4,8 +4,10 @@ [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) +offsets = PackedFloat32Array(0.00840336, 0.1, 0.4375, 0.5625, 1) +colors = PackedColorArray(0.533333, 0, 1, 1, 0, 0.45, 1, 1, 0, 0.95, 1, 1, 0.983333, 1, 0, 1, 0.999396, 0, 0.058647, 1) +metadata/_snap_enabled = true +metadata/_snap_count = 16 [sub_resource type="GradientTexture1D" id="GradientTexture1D_rrsal"] gradient = SubResource("Gradient_2jwis") @@ -15,5 +17,5 @@ render_priority = 0 shader = ExtResource("1_sbr3e") shader_parameter/data = PackedFloat32Array() shader_parameter/data_size = 0 -shader_parameter/min_max_data = null +shader_parameter/alpha = 0.3 shader_parameter/color_gradient = SubResource("GradientTexture1D_rrsal") diff --git a/app/content/system/house/mini/mini_wall_shader.gdshader b/app/content/system/house/mini/mini_wall_shader.gdshader index 66bb686..0af72f6 100644 --- a/app/content/system/house/mini/mini_wall_shader.gdshader +++ b/app/content/system/house/mini/mini_wall_shader.gdshader @@ -3,32 +3,55 @@ render_mode blend_mix, depth_draw_opaque, cull_disabled, diffuse_lambert, specul uniform vec4 data[100]; uniform int data_size: hint_range(0, 100, 1); -uniform vec2 min_max_data; +uniform float alpha: hint_range(0.0, 1.0, 0.1) = 0.3; uniform sampler2D color_gradient; varying vec3 color; +float simple_weight(int index, vec3 world_pos, float p) { + return 1.0 / pow(distance(data[index].xyz, world_pos), p); +} +float sphere_weight(int index, vec3 world_pos, float r) { + float dist = distance(data[index].xyz, world_pos); + return pow(max(0, r - dist) / (r * dist), 2); +} 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 distances[100]; float dist_sum = 0.0; + float data_sum = 0.0; + + float closest_dist = -1.0; + int closest_index = 0; if(data_size > 0) { + closest_dist = distance(data[0].xyz, world_position); + + // Inverse distance weighting using Shepard's method for(int i = 0; i < data_size; i++) { - float delta = 1.0 / distance(data[i].xyz, world_position); + distances[i] = sphere_weight(i, world_position, 5.0); + dist_sum += distances[i]; + data_sum += distances[i] * data[i].w; - distances[i] = vec2(delta, data[i].w); - dist_sum += delta; + float dist = distance(data[i].xyz, world_position); + + if(dist < closest_dist) { + closest_dist = dist; + closest_index = i; + } } - 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; + float value = (1.0 / dist_sum) * data_sum; + + if( value > 0.0 || value < 1.0) { + color.xyz = texture(color_gradient, vec2(value, 0)).xyz; + } else { + color.xyz = texture(color_gradient, vec2(data[closest_index].w, 0)).xyz; } } } diff --git a/app/content/system/house/mini/miniature.gd b/app/content/system/house/mini/miniature.gd index 0a63fd4..66004c9 100644 --- a/app/content/system/house/mini/miniature.gd +++ b/app/content/system/house/mini/miniature.gd @@ -3,11 +3,14 @@ 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 walls_mesh = $Body/Model/WallsMesh +@onready var floor_mesh = $Body/Model/FloorMesh +@onready var collision_shape = $Body/CollisionShape3D @onready var toggle_heatmap = $HeatmapButton +# var temperature_scale := Vector2( - 20.0, 60.0) +var temperature_scale := Vector2(22.0, 25.0) + var enabled = true: set(value): enabled = value @@ -19,6 +22,9 @@ func _ready(): if Store.house.is_loaded() == false: await Store.house.on_loaded + if Store.house.rooms.size() == 0: + return + var room = Store.house.rooms[0] var corners = room.corners @@ -31,7 +37,7 @@ func _ready(): floor_mesh.material_override = wall_material active = true - update_data(0.0) + EventSystem.on_slow_tick.connect(update_data) toggle_heatmap.on_button_down.connect(func(): active=true @@ -56,7 +62,6 @@ 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(): @@ -68,17 +73,14 @@ func update_data(delta: float) -> void: 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) + data_list = data_list.map(func(data: Vector4) -> Vector4: + data.w=(data.w - temperature_scale.x) / (temperature_scale.y - temperature_scale.x) + return data + ) + + print(data_list) 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()) diff --git a/app/content/system/house/mini/miniature.tscn b/app/content/system/house/mini/miniature.tscn index a48b30b..1ae4bd5 100644 --- a/app/content/system/house/mini/miniature.tscn +++ b/app/content/system/house/mini/miniature.tscn @@ -6,19 +6,24 @@ [sub_resource type="BoxShape3D" id="BoxShape3D_bckw3"] -[node name="Miniature" type="StaticBody3D"] +[node name="Miniature" type="Node3D"] script = ExtResource("1_b53yn") -[node name="WallsMesh" type="MeshInstance3D" parent="."] +[node name="HeatmapButton" parent="." instance=ExtResource("3_tgdcf")] +toggleable = true -[node name="FloorMesh" type="MeshInstance3D" parent="."] +[node name="Body" type="StaticBody3D" parent="."] -[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +[node name="CollisionShape3D" type="CollisionShape3D" parent="Body"] shape = SubResource("BoxShape3D_bckw3") -[node name="Movable" type="Node" parent="."] +[node name="Movable" type="Node" parent="Body"] 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 +[node name="Model" type="Node3D" parent="Body"] + +[node name="WallsMesh" type="MeshInstance3D" parent="Body/Model"] +skeleton = NodePath("../../..") + +[node name="FloorMesh" type="MeshInstance3D" parent="Body/Model"] +skeleton = NodePath("../../..") diff --git a/app/lib/utils/mesh/construct_room_mesh.gd b/app/lib/utils/mesh/construct_room_mesh.gd index 602cfc2..b0045ce 100644 --- a/app/lib/utils/mesh/construct_room_mesh.gd +++ b/app/lib/utils/mesh/construct_room_mesh.gd @@ -127,6 +127,21 @@ static func generate_ceiling_mesh_grid(corners, grid: Vector2=Vector2(0.1, 0.1)) var size = max_val - min_val + # Subdivide edges to grid + for i in range(corners.size()): + var corner = corners[i] + var next_index = (i + 1) % corners.size() + var next_corner = corners[next_index] + + var steps = ceil(Vector2((next_corner - corner).length() / grid.x, size.y / grid.y)) + + var forward_dir = (next_corner - corner).normalized() * grid.x + + for x in range(1, steps.x): + var point = corner + forward_dir * x + + points.append(Vector2(point.x, point.y)) + ## Fill points insde the polygon for y in range(1, int(size.y / grid.y)): var x_intersections: Array[float] = []