This commit is contained in:
Team3
2026-09-16 01:23:42 +02:00
parent 12cbb88692
commit 936773c4e9
13 changed files with 1300 additions and 314 deletions

View File

@@ -108,9 +108,10 @@ static func label(parent: Node, pos: Vector3, text: String, size: float = 0.35,
## door_dir: Vector3.FORWARD/BACK/LEFT/RIGHT -- auf welcher Seite die Lücke sitzt.
static func room(parent: Node, center: Vector3, size: Vector3, wall_c: Color,
floor_c: Color, door_dir: Vector3, door_w: float = 3.0,
with_floor: bool = true) -> void:
with_floor: bool = true) -> Array:
var t := 0.4
var h := size.y
var waende: Array = []
if with_floor:
box(parent, center + Vector3(0, -0.1, 0), Vector3(size.x, 0.2, size.z), floor_c)
var seiten: Array[Vector3] = [Vector3.FORWARD, Vector3.BACK, Vector3.LEFT, Vector3.RIGHT]
@@ -126,9 +127,90 @@ static func room(parent: Node, center: Vector3, size: Vector3, wall_c: Color,
var seg_size: Vector3 = Vector3(seg, h, t) if quer else Vector3(t, h, seg)
for s: float in [-1.0, 1.0]:
var seg_pos: Vector3 = center + off + along * (s * (door_w * 0.5 + seg * 0.5))
box(parent, seg_pos, seg_size, wall_c)
waende.append(_wand(box(parent, seg_pos, seg_size, wall_c), d))
if h >= 3.0:
var sturz: Vector3 = Vector3(door_w, h * 0.3, t) if quer else Vector3(t, h * 0.3, door_w)
box(parent, center + off + Vector3(0, h * 0.35, 0), sturz, wall_c)
waende.append(_wand(box(parent, center + off + Vector3(0, h * 0.35, 0), sturz, wall_c), d))
else:
box(parent, center + off, voll, wall_c)
waende.append(_wand(box(parent, center + off, voll, wall_c), d))
return waende
static func _meshes_von(b: Dictionary) -> Array:
var out: Array = []
for n in b["etagen"]:
_sammle(n, out)
for n in b["dach"]:
_sammle(n, out)
for liste in b["waende"]:
for w in liste:
if not out.has(w):
out.append(w)
return out
static func _sammle(n: Node, out: Array) -> void:
if n is MeshInstance3D and not out.has(n):
out.append(n)
for k in n.get_children():
_sammle(k, out)
static func _wand(mi: MeshInstance3D, normale: Vector3) -> MeshInstance3D:
mi.set_meta("normal", normale)
return mi
## Etagenschnitt wie bei den Sims: steht der Spieler in einem Bau, verschwinden
## das Dach, die Etagen über ihm und die beiden Wände, die zur Kamera zeigen.
## Ein Bau: {c, size, hoch, etagen, dach, waende, voll}. "voll" heißt: ein
## geschlossener Klotz, der ganz verschwindet.
## Ein Bau zwischen Kamera und Spieler wird durchsichtig, sonst verschwände
## der Spieler hinter jedem Nachbarhaus.
static func schnitt(bauten: Array, spieler: Vector3, kamera: Vector3) -> void:
for b in bauten:
var c: Vector3 = b["c"]
var g: Vector2 = b["size"]
var drin: bool = absf(spieler.x - c.x) < g.x * 0.5 + 0.3 \
and absf(spieler.z - c.z) < g.y * 0.5 + 0.3 \
and spieler.y > c.y - 0.5 and spieler.y < c.y + float(b["hoch"]) + 0.5
var kasten := AABB(Vector3(c.x - g.x * 0.5, c.y, c.z - g.y * 0.5),
Vector3(g.x, float(b["hoch"]), g.y))
var im_weg: bool = not drin \
and kasten.intersects_segment(kamera, spieler + Vector3(0, 0.8, 0)) != null
if bool(b.get("im_weg", false)) != im_weg:
b["im_weg"] = im_weg
if not b.has("meshes"):
b["meshes"] = _meshes_von(b)
for mi in b["meshes"]:
(mi as GeometryInstance3D).transparency = 0.82 if im_weg else 0.0
var etagen: Array = b["etagen"]
var pf := clampi(int(floor((spieler.y - c.y + 0.6) / Orte.ETAGE)), 0, maxi(0, etagen.size() - 1))
for f in range(etagen.size()):
(etagen[f] as Node3D).visible = not drin or (f <= pf and not bool(b.get("voll", false)))
for d in b["dach"]:
(d as Node3D).visible = not drin
var waende: Array = b["waende"]
for f in range(waende.size()):
for w in waende[f]:
var n: Vector3 = w.get_meta("normal")
(w as Node3D).visible = not (drin and f == pf and n.dot(kamera - c) > 0.0)
## Ein Satteldach: ein geschlossenes Prisma über den Wänden. Der First läuft
## entlang der längeren Seite, das Dach steht ringsum 0,6 über.
static func dach(parent: Node, center: Vector3, size: Vector3, c: Color) -> MeshInstance3D:
var quer := size.x >= size.z # First entlang X
var spann: float = (size.z if quer else size.x) + 1.2
var laenge: float = (size.x if quer else size.z) + 1.2
var hoehe := spann * 0.5 * tan(0.62)
var mi := MeshInstance3D.new()
var pm := PrismMesh.new()
pm.size = Vector3(spann, hoehe, laenge)
mi.mesh = pm
mi.material_override = mat(c.darkened(0.3))
mi.position = center + Vector3(0, size.y + hoehe * 0.5, 0)
if quer:
mi.rotation.y = PI * 0.5
parent.add_child(mi)
return mi