From 2274eab9e157a9b328496b11dcc43d188a058d80 Mon Sep 17 00:00:00 2001 From: Florian Date: Tue, 16 Sep 2025 00:19:40 +0200 Subject: [PATCH] Wrote a shader --- building.gd | 27 +++++++++++++++++++++++++++ building.gd.uid | 1 + building.gdshader | 34 ++++++++++++++++++++++++++++++++++ building.gdshader.uid | 1 + building.tscn | 22 ++++++++++++++++++++++ draw_circle.gd | 2 +- earth.tscn | 11 ++++++++--- grid.gd | 24 +++++++++++++++++++----- 8 files changed, 113 insertions(+), 9 deletions(-) create mode 100644 building.gd create mode 100644 building.gd.uid create mode 100644 building.gdshader create mode 100644 building.gdshader.uid create mode 100644 building.tscn diff --git a/building.gd b/building.gd new file mode 100644 index 0000000..e252fdd --- /dev/null +++ b/building.gd @@ -0,0 +1,27 @@ +class_name Building extends Node2D + +var location : Vector2i # x is the angle, y is the height in the grid +var dimension : Vector2i = Vector2.ONE # same as above +@onready var grid : Grid = get_parent() + +# make sure location is set before adding a building to the scene tree +# also make sure that the buildings are instantiated as children of the grid +func _ready() -> void: + var angle = location.x * TAU / grid.num_collumns; # currently assumes anchor is bottom left + var height = grid.ground_radius + location.y * grid.cell_height; + position = height * Vector2.from_angle(angle) + print(angle, " ", height, " ", position) + +func overlaps(other : Building): + # heights don't overlap + if location.y >= other.location.y + other.dimension.y: return false # other is below + if location.y + dimension.y <= other.location.y: return false # other is above + + # angles overlap. We can now assume heights overlap + var relative_other_loc = (other.location.x - location.x + grid.num_collumns) % grid.num_collumns + if dimension.x > relative_other_loc: return true + if relative_other_loc + other.dimension > grid.num_collumns: return true + + # If we get here, angles do not overlap + return false + diff --git a/building.gd.uid b/building.gd.uid new file mode 100644 index 0000000..9a1e17b --- /dev/null +++ b/building.gd.uid @@ -0,0 +1 @@ +uid://b2ji03ekijjnn diff --git a/building.gdshader b/building.gdshader new file mode 100644 index 0000000..ff2b604 --- /dev/null +++ b/building.gdshader @@ -0,0 +1,34 @@ +shader_type canvas_item; + +uniform ivec2 location; +uniform ivec2 dimension = ivec2(1,1); + +uniform float ground_height = 3000.; +uniform float cell_height = 300.; +uniform int num_cells = 60; + +varying vec2 world_position; + +void vertex() +{ + world_position = (MODEL_MATRIX * vec4(VERTEX, 0.0, 1.0)).xy; +} + +void fragment() { + float radius = sqrt(world_position.x * world_position.x + world_position.y * world_position.y); + float angle = atan(world_position.y, world_position.x); + + float sample_y = 1. - ((radius - ground_height) / cell_height - float( location.y)) / float(dimension.y); + float sample_x = mod(fract(angle / TAU + 1.) * float(num_cells) - float(location.x) + float(num_cells), float(num_cells)) / float(dimension.x); + + if(sample_y > 1. || sample_y < 0. || sample_x > 1. || sample_x < 0.) { + discard; + } + COLOR = texture(TEXTURE, vec2(sample_x, sample_y)); + +} + +//void light() { +// // Called for every pixel for every light affecting the CanvasItem. +// // Uncomment to replace the default light processing function with this one. +//} diff --git a/building.gdshader.uid b/building.gdshader.uid new file mode 100644 index 0000000..984dac8 --- /dev/null +++ b/building.gdshader.uid @@ -0,0 +1 @@ +uid://c7gb1nqwvkr37 diff --git a/building.tscn b/building.tscn new file mode 100644 index 0000000..16ffed3 --- /dev/null +++ b/building.tscn @@ -0,0 +1,22 @@ +[gd_scene load_steps=5 format=3 uid="uid://djawvtdwp423v"] + +[ext_resource type="Script" uid="uid://b2ji03ekijjnn" path="res://building.gd" id="1_5j34s"] +[ext_resource type="Texture2D" uid="uid://cy70quh6k3s1j" path="res://icon.svg" id="2_2yopf"] +[ext_resource type="Shader" uid="uid://c7gb1nqwvkr37" path="res://building.gdshader" id="2_f1gjg"] + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_qnfc1"] +resource_local_to_scene = true +shader = ExtResource("2_f1gjg") +shader_parameter/location = Vector2i(45, 0) +shader_parameter/dimension = Vector2i(1, 1) +shader_parameter/ground_height = 3000.0 +shader_parameter/cell_height = 300.0 +shader_parameter/num_cells = 60 + +[node name="Building" type="Node2D"] +script = ExtResource("1_5j34s") + +[node name="Sprite2D" type="Sprite2D" parent="."] +material = SubResource("ShaderMaterial_qnfc1") +scale = Vector2(7, 7) +texture = ExtResource("2_2yopf") diff --git a/draw_circle.gd b/draw_circle.gd index 2d87a9c..d9ac2d5 100644 --- a/draw_circle.gd +++ b/draw_circle.gd @@ -1,4 +1,4 @@ -extends Sprite2D +extends Node2D @export var radius : float; func _draw(): diff --git a/earth.tscn b/earth.tscn index a2b03e5..8b3dd35 100644 --- a/earth.tscn +++ b/earth.tscn @@ -1,8 +1,8 @@ [gd_scene load_steps=5 format=3 uid="uid://33k5v6skcbsm"] -[ext_resource type="Texture2D" uid="uid://cy70quh6k3s1j" path="res://icon.svg" id="1_qbwya"] [ext_resource type="Script" uid="uid://b5fhsy1xlreco" path="res://draw_circle.gd" id="2_2bhor"] [ext_resource type="Script" uid="uid://m3vyyfk8gnma" path="res://grid.gd" id="3_2bhor"] +[ext_resource type="PackedScene" uid="uid://djawvtdwp423v" path="res://building.tscn" id="3_5i67w"] [sub_resource type="CircleShape2D" id="CircleShape2D_5i67w"] radius = 3000.0 @@ -14,8 +14,7 @@ radius = 3000.0 [node name="CollisionShape2D" type="CollisionShape2D" parent="Ground"] shape = SubResource("CircleShape2D_5i67w") -[node name="Sprite2D" type="Sprite2D" parent="Ground"] -texture = ExtResource("1_qbwya") +[node name="GroundVisual" type="Node2D" parent="Ground"] script = ExtResource("2_2bhor") radius = 3000.0 @@ -29,3 +28,9 @@ cell_height = 300.0 num_collumns = 60 debug = true metadata/_custom_type_script = "uid://m3vyyfk8gnma" + +[node name="Building" parent="." instance=ExtResource("3_5i67w")] +position = Vector2(-5212, -1497) + +[node name="Building2" parent="." instance=ExtResource("3_5i67w")] +position = Vector2(49, 25) diff --git a/grid.gd b/grid.gd index 0c7c74e..1f56b8a 100644 --- a/grid.gd +++ b/grid.gd @@ -5,6 +5,8 @@ class_name Grid extends Node2D @export var num_collumns : int @export var debug : bool +var buildings : Array[Building] = [] + func _draw() -> void: if !debug: return @@ -16,8 +18,20 @@ func _draw() -> void: var angle = i * TAU / num_collumns; draw_line(Vector2.ZERO, 10000 * Vector2.from_angle(angle), Color.SKY_BLUE); -#func cart_to_sphere(cart : Vector2): - #var x = cart.x; var y = cart.y; - #var radius = sqrt(x*x + y*y); - #var angle = tan(y/x) - ## TODO +func add_building_to_collumn(building : Building, collumn : int): + # find the height of the top building in the buildings list: + building.location = Vector2(collumn, 0) + var height = 0 + + # TODO: support other dimensions for buildings + + # add the new building one higher than the previous + height += 1 + building.location = Vector2i(collumn, height); + +# for testing +func _ready() -> void: + var packed : PackedScene = preload("res://building.tscn") + var test_building = packed.instantiate() + test_building.location = Vector2(45, 1) + add_child(test_building)