From 7a24584c7d1ac275d11004cc756d053d2ebf9372 Mon Sep 17 00:00:00 2001 From: Jonas Reith Date: Wed, 26 Aug 2026 19:26:07 +0200 Subject: [PATCH] Add hex-diamond island terrain prototype New standalone debug prototype exploring the "gem-cut" flying island shape: a flat hexagonal table (center region) surrounded by 6 sloped trapezoidal facets down to the girdle (6 outer regions), with a non-walkable 6-sided pavilion pyramid below for the underside. Crown gets trimesh collision for later player testing; all 6 outer facets stay visually neutral (alternating flat color only) since theming comes later. Doesn't touch main.tscn or the old cross-layout prototype. --- debug/HexDiamondIsland.gd | 105 ++++++++++++++++++++++++++++++++++ debug/hex_diamond_island.tscn | 32 +++++++++++ 2 files changed, 137 insertions(+) create mode 100644 debug/HexDiamondIsland.gd create mode 100644 debug/hex_diamond_island.tscn diff --git a/debug/HexDiamondIsland.gd b/debug/HexDiamondIsland.gd new file mode 100644 index 0000000..673f24b --- /dev/null +++ b/debug/HexDiamondIsland.gd @@ -0,0 +1,105 @@ +extends Node3D + +# ═══════════════════════════════════════════════════════════════ +# HEX-DIAMANT-INSEL — Blockout +# Krone (begehbar): flaches 6-Eck-Tisch + 6 Trapez-Facetten zur Rundiste +# Pavillon (rein optisch): steile 6-seitige Pyramide unter der Rundiste +# ═══════════════════════════════════════════════════════════════ + +@export var table_radius : float = 80.0 # flaches Sechseck in der Mitte +@export var girdle_radius : float = 260.0 # äußerer Sechseck-Rand (Rundiste) +@export var crown_drop : float = 30.0 # Höhenabfall Tisch -> Rundiste +@export var pavilion_depth : float = 190.0 # Höhenabfall Rundiste -> Spitze +@export var angle_offset_deg: float = 0.0 + +const COLOR_TABLE := Color(0.75, 0.74, 0.70) +const COLOR_FACET_A := Color(0.55, 0.55, 0.48) +const COLOR_FACET_B := Color(0.49, 0.49, 0.43) +const COLOR_PAVILION := Color(0.30, 0.28, 0.26) + +func _ready() -> void: + _build_crown() + _build_pavilion() + +func _hex_angle(k: int) -> float: + return deg_to_rad(angle_offset_deg) + float(k) / 6.0 * TAU + +func _add_tri(st: SurfaceTool, a: Vector3, b: Vector3, c: Vector3, col: Color) -> void: + var n := (b - a).cross(c - a).normalized() + for v in [a, b, c]: + st.set_normal(n) + st.set_color(col) + st.add_vertex(v) + +# ═══════════════════════════════════════════════ +# KRONE — Tisch + 6 Facetten (begehbar, mit Kollision) +# ═══════════════════════════════════════════════ +func _build_crown() -> void: + var st := SurfaceTool.new() + st.begin(Mesh.PRIMITIVE_TRIANGLES) + + var center := Vector3.ZERO + var table_pts : Array[Vector3] = [] + var girdle_pts : Array[Vector3] = [] + for k in range(6): + var a := _hex_angle(k) + table_pts.append(Vector3(cos(a) * table_radius, 0.0, sin(a) * table_radius)) + girdle_pts.append(Vector3(cos(a) * girdle_radius, -crown_drop, sin(a) * girdle_radius)) + + # Tisch-Fan (Zentrum-Region) + for k in range(6): + var k1 := (k + 1) % 6 + _add_tri(st, center, table_pts[k1], table_pts[k], COLOR_TABLE) + + # 6 Facetten (Außenregionen), abwechselnd eingefärbt für sichtbare Nähte + for k in range(6): + var k1 := (k + 1) % 6 + var col := COLOR_FACET_A if k % 2 == 0 else COLOR_FACET_B + _add_tri(st, table_pts[k], table_pts[k1], girdle_pts[k], col) + _add_tri(st, table_pts[k1], girdle_pts[k1], girdle_pts[k], col) + + var mesh := st.commit() + var mat := StandardMaterial3D.new() + mat.vertex_color_use_as_albedo = true + mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED + mat.cull_mode = BaseMaterial3D.CULL_DISABLED + mesh.surface_set_material(0, mat) + + var body := StaticBody3D.new() + body.name = "Crown" + var mi := MeshInstance3D.new() + mi.mesh = mesh + body.add_child(mi) + var cs := CollisionShape3D.new() + cs.shape = mesh.create_trimesh_shape() + body.add_child(cs) + add_child(body) + +# ═══════════════════════════════════════════════ +# PAVILLON — Pyramide unter der Rundiste (rein optisch) +# ═══════════════════════════════════════════════ +func _build_pavilion() -> void: + var st := SurfaceTool.new() + st.begin(Mesh.PRIMITIVE_TRIANGLES) + + var apex := Vector3(0, -crown_drop - pavilion_depth, 0) + var girdle_pts: Array[Vector3] = [] + for k in range(6): + var a := _hex_angle(k) + girdle_pts.append(Vector3(cos(a) * girdle_radius, -crown_drop, sin(a) * girdle_radius)) + + for k in range(6): + var k1 := (k + 1) % 6 + _add_tri(st, girdle_pts[k], girdle_pts[k1], apex, COLOR_PAVILION) + + var mesh := st.commit() + var mat := StandardMaterial3D.new() + mat.vertex_color_use_as_albedo = true + mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED + mat.cull_mode = BaseMaterial3D.CULL_DISABLED + mesh.surface_set_material(0, mat) + + var mi := MeshInstance3D.new() + mi.name = "Pavilion" + mi.mesh = mesh + add_child(mi) diff --git a/debug/hex_diamond_island.tscn b/debug/hex_diamond_island.tscn new file mode 100644 index 0000000..924dad2 --- /dev/null +++ b/debug/hex_diamond_island.tscn @@ -0,0 +1,32 @@ +[gd_scene format=3] + +[ext_resource type="Script" uid="uid://bia8axed2ndwj" path="res://debug/FreeCam.gd" id="1_freecam"] +[ext_resource type="Script" path="res://debug/HexDiamondIsland.gd" id="2_hexdi"] + +[sub_resource type="Environment" id="Environment_hexdi"] +background_mode = 1 +background_color = Color(0.16470589, 0.25490198, 0.36078432, 1) +ambient_light_source = 2 +ambient_light_color = Color(0.23529412, 0.25490198, 0.29411766, 1) +ambient_light_energy = 0.8 + +[node name="HexDiamondIsland" type="Node3D"] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_hexdi") + +[node name="Sun" type="DirectionalLight3D" parent="."] +transform = Transform3D(0.8660254, -0.35355338, 0.35355338, 0, 0.70710677, 0.70710677, -0.5, -0.6123724, 0.6123724, 0, 0, 0) +light_energy = 1.2 + +[node name="FlyCamera" type="Node3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 0.92718387, 0.3746066, 0, -0.3746066, 0.92718387, 0, 120, 350) +script = ExtResource("1_freecam") + +[node name="Camera3D" type="Camera3D" parent="FlyCamera"] +fov = 65.0 +near = 0.1 +far = 1000.0 + +[node name="HexDiamondIsland" type="Node3D" parent="."] +script = ExtResource("2_hexdi")