]> git.za3k.com Git - the_dome.git/commitdiff
make an actual geodesic dome
authorZachary Vance <za3k@za3k.com>
Mon, 1 Jul 2024 15:00:10 +0000 (11:00 -0400)
committerZachary Vance <za3k@za3k.com>
Mon, 1 Jul 2024 15:00:10 +0000 (11:00 -0400)
13 files changed:
geodesic.avi [new file with mode: 0644]
geodesic_dome.gd
geodesic_dome.tscn
geodesic_dome_edge.gd [new file with mode: 0644]
geodesic_dome_edge.tscn [new file with mode: 0644]
glass_triangle.gd [new file with mode: 0644]
glass_triangle.tscn [new file with mode: 0644]
ico_vertex.gd
ico_vertex.tscn
pbr_glass.gdshader [new file with mode: 0644]
project.godot
world.gd
world.tscn

diff --git a/geodesic.avi b/geodesic.avi
new file mode 100644 (file)
index 0000000..565ce97
Binary files /dev/null and b/geodesic.avi differ
index b6c3ffa8ea54c4b91a7c0ee66dcbc6db97430da6..9e09b85f5827f2460bdf6a2905eb68b2e7681bbe 100644 (file)
@@ -1,23 +1,80 @@
 extends Node3D
 
 @export var vertex_scene: PackedScene
+@export var edge_scene: PackedScene
+@export var face_scene: PackedScene
 
-func random_position():
-       return Vector3(
-               randf_range(-2,2),
-               randf_range(-2,2),
-               randf_range(-2,2)
-       )
+var VERTICES : Array[Vector3] = [
+       Vector3(0, 1, 0),
+       Vector3(0, -1, 0),
+       Vector3(cos(deg_to_rad(36*0)),  1/sqrt(5), sin(deg_to_rad(36*0))).normalized(),
+       Vector3(cos(deg_to_rad(36*1)), -1/sqrt(5), sin(deg_to_rad(36*1))).normalized(),
+       Vector3(cos(deg_to_rad(36*2)),  1/sqrt(5), sin(deg_to_rad(36*2))).normalized(),
+       Vector3(cos(deg_to_rad(36*3)), -1/sqrt(5), sin(deg_to_rad(36*3))).normalized(),
+       Vector3(cos(deg_to_rad(36*4)),  1/sqrt(5), sin(deg_to_rad(36*4))).normalized(),
+       Vector3(cos(deg_to_rad(36*5)), -1/sqrt(5), sin(deg_to_rad(36*5))).normalized(),
+       Vector3(cos(deg_to_rad(36*6)),  1/sqrt(5), sin(deg_to_rad(36*6))).normalized(),
+       Vector3(cos(deg_to_rad(36*7)), -1/sqrt(5), sin(deg_to_rad(36*7))).normalized(),
+       Vector3(cos(deg_to_rad(36*8)),  1/sqrt(5), sin(deg_to_rad(36*8))).normalized(),
+       Vector3(cos(deg_to_rad(36*9)), -1/sqrt(5), sin(deg_to_rad(36*9))).normalized(),
+]
+@export var level = 1 # Detail level
 
-func add_vertex(p : Vector3):
-       var vertex = vertex_scene.instantiate()
-       vertex.position = p
+func is_edge(v1 : Vector3, v2 : Vector3):
+       return (VERTICES.find(v1) < VERTICES.find(v2) and 
+                       (v1-v2).length() < 1.3)
+
+func add_vertex(v1 : Vector3):
+       var vertex : IsoVertex = vertex_scene.instantiate()
+       vertex.position = v1
        add_child(vertex)
 
-# Called when the node enters the scene tree for the first time.
+func add_edge(v1 : Vector3, v2: Vector3, level : int):
+       if level == 1:
+               var edge : DomeEdge = edge_scene.instantiate()
+               edge.v1 = v1
+               edge.v2 = v2
+               add_child(edge)
+       elif level > 1:
+               var v12 = sphere_midpoint(v1, v2)
+               add_edge(v1, v12, level-1)
+               add_edge(v12, v2, level-1)
+
+func sphere_midpoint(v1 : Vector3, v2 : Vector3):
+       return ((v1 + v2) / 2).normalized()
+
+func add_face(v1 : Vector3, v2: Vector3, v3: Vector3, level : int):
+       # Precondition: EXTERIOR edges are already drawn
+       if level == 1:
+               var face : GlassTriangle = face_scene.instantiate()
+               face.v1 = v1
+               face.v2 = v2
+               face.v3 = v3
+               add_child(face)
+       elif level > 1:
+               var v12 = sphere_midpoint(v1, v2)
+               var v13 = sphere_midpoint(v1, v3)
+               var v23 = sphere_midpoint(v2, v3)
+               add_vertex(v12)
+               add_vertex(v13)
+               add_vertex(v23)
+               add_edge(v12, v23, level-1)
+               add_edge(v13, v23, level-1)
+               add_edge(v12, v13, level-1)
+               add_face(v1, v12, v13, level-1)
+               add_face(v2, v12, v23, level-1)
+               add_face(v3, v13, v23, level-1)
+               add_face(v12, v13, v23, level-1)
+
 func _ready():
-       for i in range(11):
-               add_vertex(random_position())           
+       for v1 in VERTICES:
+               add_vertex(v1)
+               for v2 in VERTICES:
+                       if is_edge(v1, v2):
+                               add_edge(v1, v2, level)
+                               for v3 in VERTICES:
+                                       if is_edge(v1, v3) and is_edge(v2, v3):
+                                               add_face(v1, v2, v3, level)             
 
 # Called every frame. 'delta' is the elapsed time since the previous frame.
 func _process(delta):
index 56f109231ceea9a55d0682067d02a6651d45c7b7..4ee329b2e2d60c696b76976e10e9bc7eac56915b 100644 (file)
@@ -1,7 +1,9 @@
-[gd_scene load_steps=4 format=3 uid="uid://cr06eruxv1iyp"]
+[gd_scene load_steps=6 format=3 uid="uid://cr06eruxv1iyp"]
 
 [ext_resource type="Script" path="res://geodesic_dome.gd" id="1_ewsyw"]
 [ext_resource type="PackedScene" uid="uid://bn7wa6in76pce" path="res://ico_vertex.tscn" id="2_loxxg"]
+[ext_resource type="PackedScene" uid="uid://d11qr1jxoxt8b" path="res://geodesic_dome_edge.tscn" id="3_o0t1j"]
+[ext_resource type="PackedScene" uid="uid://dnfk0fawcv6pb" path="res://glass_triangle.tscn" id="4_t0bv2"]
 
 [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_dw2k7"]
 transparency = 1
@@ -11,11 +13,12 @@ albedo_color = Color(1, 1, 1, 0.254902)
 [node name="GeodesicDome" type="Node3D"]
 script = ExtResource("1_ewsyw")
 vertex_scene = ExtResource("2_loxxg")
+edge_scene = ExtResource("3_o0t1j")
+face_scene = ExtResource("4_t0bv2")
 
 [node name="UnitSphere" type="CSGSphere3D" parent="."]
+visible = false
 radius = 0.9
+radial_segments = 48
+rings = 24
 material = SubResource("StandardMaterial3D_dw2k7")
-
-[node name="TopVertex" parent="." instance=ExtResource("2_loxxg")]
-transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
-fixed = true
diff --git a/geodesic_dome_edge.gd b/geodesic_dome_edge.gd
new file mode 100644 (file)
index 0000000..48ac9d0
--- /dev/null
@@ -0,0 +1,23 @@
+class_name DomeEdge extends StaticBody3D
+
+@export var v1 : Vector3
+@export var v2 : Vector3
+
+# Called when the node enters the scene tree for the first time.
+func _ready():
+       var length = (v2-v1).length()
+       var center = (v1 + v2) / 2
+       var direction = (v2-v1).normalized()
+       
+       position = center
+       #rotation = direction
+       var cyclinder_mesh : CylinderMesh = $MeshInstance3D.mesh
+       cyclinder_mesh.height = length
+       look_at(v2)
+       pass # Replace with function body.
+
+
+# Called every frame. 'delta' is the elapsed time since the previous frame.
+func _process(delta):
+       pass
+       #get_tree().current_scene.draw_line(v1, v2)
diff --git a/geodesic_dome_edge.tscn b/geodesic_dome_edge.tscn
new file mode 100644 (file)
index 0000000..8ffec9b
--- /dev/null
@@ -0,0 +1,18 @@
+[gd_scene load_steps=4 format=3 uid="uid://d11qr1jxoxt8b"]
+
+[ext_resource type="Script" path="res://geodesic_dome_edge.gd" id="1_m4hun"]
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_qgvan"]
+albedo_color = Color(0.205117, 0.205117, 0.205117, 1)
+
+[sub_resource type="CylinderMesh" id="CylinderMesh_v76vy"]
+material = SubResource("StandardMaterial3D_qgvan")
+top_radius = 0.01
+bottom_radius = 0.01
+
+[node name="GeodesicDomeEdge" type="StaticBody3D"]
+script = ExtResource("1_m4hun")
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0)
+mesh = SubResource("CylinderMesh_v76vy")
diff --git a/glass_triangle.gd b/glass_triangle.gd
new file mode 100644 (file)
index 0000000..1e9311f
--- /dev/null
@@ -0,0 +1,45 @@
+class_name GlassTriangle extends StaticBody3D
+
+const thickness = 0.05
+@export var v1 : Vector3
+@export var v2 : Vector3
+@export var v3 : Vector3
+var v1_inner
+var v2_inner
+var v3_inner
+@export var material : Material
+
+func is_clockwise():
+       var center = (v1 + v2 + v3) / 3
+       return v1.signed_angle_to(v2, center) < 0
+
+func _ready():
+       # Re-order vertices are in clockwise order
+       if not is_clockwise():
+               var temp = v2
+               v2 = v3
+               v3 = temp
+       v1_inner = v1 * (1-thickness)
+       v2_inner = v2 * (1-thickness)
+       v3_inner = v3 * (1-thickness)
+       update_mesh()
+
+func _process(delta):
+       pass
+
+func update_mesh():
+       var vertices = [v1, v2, v3, v1_inner, v2_inner, v3_inner]
+       
+       var st = SurfaceTool.new()
+       st.begin(Mesh.PRIMITIVE_TRIANGLES)
+       st.set_color(Color(1, 1, 1))
+       st.set_uv(Vector2(0, 0))
+       st.set_material(material)
+       for vertex in vertices:
+               #st.add_vertex(Vector3(0, 0, 0))
+               st.add_vertex(vertex)
+       var am = st.commit()    
+       $VisibleShape.mesh = am
+       
+       var cps : ConvexPolygonShape3D = $CollisionShape.shape
+       cps.points = vertices
diff --git a/glass_triangle.tscn b/glass_triangle.tscn
new file mode 100644 (file)
index 0000000..bbe679d
--- /dev/null
@@ -0,0 +1,24 @@
+[gd_scene load_steps=5 format=3 uid="uid://dnfk0fawcv6pb"]
+
+[ext_resource type="Script" path="res://glass_triangle.gd" id="1_w50by"]
+[ext_resource type="Shader" path="res://pbr_glass.gdshader" id="2_hi517"]
+
+[sub_resource type="ShaderMaterial" id="ShaderMaterial_kvcah"]
+render_priority = 0
+shader = ExtResource("2_hi517")
+shader_parameter/albedo = Color(1, 1, 1, 0.156863)
+shader_parameter/roughness = 0.15
+shader_parameter/normal_strength = 1.0
+shader_parameter/edge_color = Color(0, 0, 0, 1)
+
+[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_nt2r6"]
+points = PackedVector3Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+
+[node name="GlassTriangle" type="StaticBody3D"]
+script = ExtResource("1_w50by")
+material = SubResource("ShaderMaterial_kvcah")
+
+[node name="VisibleShape" type="MeshInstance3D" parent="."]
+
+[node name="CollisionShape" type="CollisionShape3D" parent="."]
+shape = SubResource("ConvexPolygonShape3D_nt2r6")
index 9406e9895df69121e63573d3fc88d513b29ffd97..67733811a3920ecff0b997608db77738709d891f 100644 (file)
@@ -1,34 +1,9 @@
 class_name IsoVertex extends RigidBody3D
 
-@export var fixed : bool = false
-
 # Called when the node enters the scene tree for the first time.
 func _ready():
        pass # Replace with function body.
 
 # Called every frame. 'delta' is the elapsed time since the previous frame.
 func _process(delta):
-       get_tree().call_group("vertex", "maybe_draw_line", self)
-
-func maybe_draw_line(other : IsoVertex):
-       if self == other: return
-       var v1 := self.position
-       var v2 := other.position
-       var midpoint = (v1 + v2) / 2
-       if midpoint.length() > 0.75: # If it doesn't pass through the 'middle'
-               get_tree().current_scene.draw_line(v1, v2)
-
-func push_away_from(other : IsoVertex, delta : float):
-       if self == other: return
-       if fixed: return
-       var displacement = self.position - other.position
-       var forceDirection = displacement.normalized()
-       var forceStrength = 10 / displacement.length_squared() # Some function of
-       apply_force(forceDirection * forceStrength * delta)
-
-func _physics_process(delta):
-       # Step 1, get a list of all other vertices
-       # Step 2, apply force to each
-       get_tree().call_group("vertex", "push_away_from", self, delta)
-       # Step 3, normalize current position
-       position = position.normalized()
+       pass
index 56455d4c4e989b477cba8b0ccfbbb1682ca43b2e..d035dd34cd853d2fc82407f8483e9a15e41d1e49 100644 (file)
@@ -12,5 +12,5 @@ gravity_scale = 0.0
 script = ExtResource("1_31hj6")
 
 [node name="Dot" type="CSGSphere3D" parent="."]
-radius = 0.05
+radius = 0.01
 material = SubResource("StandardMaterial3D_2qrn4")
diff --git a/pbr_glass.gdshader b/pbr_glass.gdshader
new file mode 100644 (file)
index 0000000..e756af2
--- /dev/null
@@ -0,0 +1,56 @@
+shader_type spatial;
+
+render_mode diffuse_burley, specular_schlick_ggx, blend_mix;
+
+group_uniforms albedo;
+uniform vec4 albedo : source_color = vec4(1.0, 1.0, 1.0, 0.0);
+uniform sampler2D albedo_texture : source_color, hint_default_white;
+
+group_uniforms roughness;
+uniform float roughness : hint_range(0.0, 1.0) = 0.15;
+uniform sampler2D roughness_texture : hint_roughness_r;
+
+group_uniforms normal;
+uniform float normal_strength : hint_range(-16.0, 16.0) = 1.0;
+uniform sampler2D normal_map : hint_normal;
+
+group_uniforms misc;
+uniform vec4 edge_color : source_color = vec4(0.0, 0.0, 0.0, 1.0);
+
+float SchlickFresnel(float u) {
+       float m = 1.0 - u;
+       float m2 = m * m;
+       return m2 * m2 * m;
+}
+
+void fragment() {
+       // calculate fresnel values
+       float VdotN = dot(VIEW, NORMAL);
+       float fresnel = clamp(SchlickFresnel(VdotN), 0.0, 1.0);
+       
+       // sample and mix textures
+       vec4 _albedo = texture(albedo_texture, UV) * albedo;
+       float _roughness = texture(roughness_texture, UV).r * roughness;
+       
+       // apply glass look
+       float a = mix(0.001, 1.0, _albedo.a);
+       ALPHA = mix(fresnel * edge_color.a, 1.0, a);
+       ALBEDO = mix(edge_color.rgb * edge_color.a, _albedo.rgb, a);
+       
+       ROUGHNESS = _roughness;
+       NORMAL_MAP = texture(normal_map, UV).xyz;
+       NORMAL_MAP_DEPTH = normal_strength;
+       
+       // function to compensate specular for alpha blend
+       // 0.5 * ALPHA^-0.5
+       SPECULAR = 0.5 * inversesqrt(ALPHA);
+}
+
+void vertex() {
+       // Called for every vertex the material is visible on.
+}
+
+//void light() {
+       // Called for every pixel for every light affecting the material.
+       // Uncomment to replace the default light processing function with this one.
+//}
index 858ed5e3d22c3ed60eadef8a4c0fdc78d11ab749..d426ae2dbb5734bba1ca921e4c94d7b80de28d86 100644 (file)
@@ -18,3 +18,29 @@ config/icon="res://icon.svg"
 [autoload]
 
 DrawLine3d="*res://DrawLine3D.gd"
+
+[display]
+
+window/size/viewport_width=1080
+window/size/viewport_height=720
+
+[editor]
+
+movie_writer/movie_file="/home/zachary/the_dome/geodesic.avi"
+
+[input]
+
+quit={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"echo":false,"script":null)
+]
+}
+restart={
+"deadzone": 0.5,
+"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":114,"echo":false,"script":null)
+]
+}
+
+[physics]
+
+3d/default_gravity=0.0
index 818357368b7cb75f19ff0ccb96aa123c6bf0338a..7524a02da9bdb3815db243bdfc9e4ea340310e50 100644 (file)
--- a/world.gd
+++ b/world.gd
@@ -3,7 +3,7 @@ extends Node3D
 var LineDrawer = preload("res://DrawLine3D.gd").new()
 
 func draw_line(v1 : Vector3, v2 : Vector3):
-       LineDrawer.DrawLine(v1, v2, Color.BROWN, 0.1)
+       LineDrawer.DrawLine(v1, v2, Color.BROWN, 1/60)
 
 # Called when the node enters the scene tree for the first time.
 func _ready(): 
@@ -11,4 +11,8 @@ func _ready():
 
 # Called every frame. 'delta' is the elapsed time since the previous frame.
 func _process(delta):
-       pass
+       $CameraPivot.position += Vector3(
+               Input.get_axis("ui_left", "ui_right"),
+               0, 0) * delta
+       if Input.is_action_pressed("quit"):
+               get_tree().quit()
index 645362ca9aada829e38f78ccef16e9603bd0d07e..56f0588e5bd85113b68fef50ef59699e7fd81dd4 100644 (file)
@@ -1,8 +1,18 @@
-[gd_scene load_steps=3 format=3 uid="uid://cotgytv6xac3l"]
+[gd_scene load_steps=6 format=3 uid="uid://cotgytv6xac3l"]
 
 [ext_resource type="PackedScene" uid="uid://cr06eruxv1iyp" path="res://geodesic_dome.tscn" id="1_j3sin"]
 [ext_resource type="Script" path="res://world.gd" id="1_lxwr8"]
 
+[sub_resource type="BoxShape3D" id="BoxShape3D_njt1i"]
+size = Vector3(10, 1, 10)
+
+[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tajc4"]
+albedo_color = Color(0.100215, 0.230141, 0.0754749, 1)
+
+[sub_resource type="BoxMesh" id="BoxMesh_6hk8v"]
+material = SubResource("StandardMaterial3D_tajc4")
+size = Vector3(10, 1, 10)
+
 [node name="World" type="Node3D"]
 script = ExtResource("1_lxwr8")
 
@@ -10,8 +20,20 @@ script = ExtResource("1_lxwr8")
 transform = Transform3D(1, 0, 0, 0, 0.846797, 0.531916, 0, -0.531916, 0.846797, 0.0169442, 1.0738, 1.64421)
 
 [node name="Camera3D" type="Camera3D" parent="CameraPivot"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.0485562, 0.137679)
 
 [node name="GeodesicDome" parent="." instance=ExtResource("1_j3sin")]
+level = 3
 
 [node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
-transform = Transform3D(1, 0, 0, 0, -0.258819, 0.965926, 0, -0.965926, -0.258819, 0, 2.14709, 3)
+transform = Transform3D(1, 0, 0, 0, 0.560234, 0.828334, 0, -0.828334, 0.560234, 0, 4.51738, 2.88875)
+
+[node name="Ground" type="StaticBody3D" parent="."]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0)
+
+[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground"]
+shape = SubResource("BoxShape3D_njt1i")
+
+[node name="MeshInstance3D" type="MeshInstance3D" parent="Ground"]
+transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
+mesh = SubResource("BoxMesh_6hk8v")