81 lines
3.1 KiB
GDScript
81 lines
3.1 KiB
GDScript
extends RefCounted
|
|
## Formen aus Regeln: jedes Ding hat eine Grundform aus Godot-Primitiven, und
|
|
## Regeln setzen Teile darauf - Rand, Bänder, Reifen, Kappe. Kanten sind
|
|
## schmale Ringe statt Fasen. Kein Mesh kommt aus einer Datei.
|
|
## Kein class_name: den Klassencache baut nur der Editor, headless fehlt er.
|
|
|
|
const Stoffe = preload("res://scripts/stoffe.gd")
|
|
|
|
|
|
static func _teil(mesh: Mesh, stoff: Material, pos: Vector3, eltern: Node3D) -> MeshInstance3D:
|
|
var mi := MeshInstance3D.new()
|
|
mi.mesh = mesh
|
|
mi.material_override = stoff
|
|
mi.position = pos
|
|
eltern.add_child(mi)
|
|
return mi
|
|
|
|
|
|
static func _zylinder(oben: float, unten: float, hoehe: float, segmente := 28) -> CylinderMesh:
|
|
var c := CylinderMesh.new()
|
|
c.top_radius = oben
|
|
c.bottom_radius = unten
|
|
c.height = hoehe
|
|
c.radial_segments = segmente
|
|
return c
|
|
|
|
|
|
static func _ring(radius: float, dicke: float) -> TorusMesh:
|
|
var t := TorusMesh.new()
|
|
t.inner_radius = radius - dicke
|
|
t.outer_radius = radius + dicke
|
|
t.rings = 32
|
|
t.ring_segments = 8
|
|
return t
|
|
|
|
|
|
## Würfelbecher: Kegelstumpf aus dunklem Holz, oben ein Messingrand, zwei
|
|
## Messingbänder um den Bauch. Der Deckel oben ist geschlossen - die Kamera
|
|
## schaut von oben, ein offener Becher zeigte nur ein schwarzes Loch.
|
|
static func becher(hoehe := 0.44, oben := 0.33, unten := 0.42) -> Node3D:
|
|
var n := Node3D.new()
|
|
_teil(_zylinder(oben, unten, hoehe), Stoffe.holz_dunkel(), Vector3(0, hoehe * 0.5, 0), n)
|
|
_teil(_ring(oben, 0.012), Stoffe.messing(), Vector3(0, hoehe - 0.004, 0), n)
|
|
for k in [0.22, 0.62]:
|
|
var r: float = lerpf(unten, oben, k)
|
|
_teil(_ring(r, 0.008), Stoffe.messing(), Vector3(0, hoehe * k, 0), n)
|
|
return n
|
|
|
|
|
|
## Fass: bauchiger Zylinder, drei Reifen, Boden und Deckel etwas kleiner.
|
|
static func fass(hoehe := 0.6, radius := 0.24) -> Node3D:
|
|
var n := Node3D.new()
|
|
_teil(_zylinder(radius * 0.86, radius * 0.86, hoehe), Stoffe.holz(), Vector3(0, hoehe * 0.5, 0), n)
|
|
_teil(_zylinder(radius, radius, hoehe * 0.5), Stoffe.holz(), Vector3(0, hoehe * 0.5, 0), n)
|
|
for k in [0.12, 0.5, 0.88]:
|
|
var r: float = radius if absf(k - 0.5) < 0.2 else radius * 0.88
|
|
_teil(_ring(r, 0.012), Stoffe.messing(), Vector3(0, hoehe * k, 0), n)
|
|
return n
|
|
|
|
|
|
## Laterne: Sockel, Glaskörper (leuchtend), Kappe mit Ring.
|
|
static func laterne(hoehe := 0.5) -> Node3D:
|
|
var n := Node3D.new()
|
|
_teil(_zylinder(0.09, 0.11, 0.05), Stoffe.messing(), Vector3(0, 0.025, 0), n)
|
|
var glas := StandardMaterial3D.new()
|
|
glas.albedo_color = Color(1.0, 0.85, 0.5, 0.75)
|
|
glas.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
|
glas.emission_enabled = true
|
|
glas.emission = Color(1.0, 0.75, 0.35)
|
|
glas.emission_energy_multiplier = 2.5
|
|
_teil(_zylinder(0.07, 0.08, hoehe * 0.6), glas, Vector3(0, 0.05 + hoehe * 0.3, 0), n)
|
|
_teil(_zylinder(0.03, 0.10, 0.08), Stoffe.messing(), Vector3(0, 0.05 + hoehe * 0.6 + 0.04, 0), n)
|
|
_teil(_ring(0.035, 0.006), Stoffe.messing(), Vector3(0, 0.05 + hoehe * 0.6 + 0.10, 0), n)
|
|
var licht := OmniLight3D.new()
|
|
licht.light_color = Color(1.0, 0.8, 0.45)
|
|
licht.light_energy = 1.2
|
|
licht.omni_range = 1.8
|
|
licht.position = Vector3(0, 0.05 + hoehe * 0.3, 0)
|
|
n.add_child(licht)
|
|
return n
|