update
This commit is contained in:
@@ -1,7 +1,14 @@
|
||||
class_name Prims
|
||||
## Kleine Helfer, um die Welt aus Godot-Primitiven zusammenzusetzen.
|
||||
|
||||
## Gleiche Farbe, gleiches Material: tausend Klötze brauchen keine tausend
|
||||
## Materialien. Wer ein Material verändern will, dupliziert es sich.
|
||||
static var _materialien: Dictionary = {}
|
||||
|
||||
static func mat(c: Color, emis: float = 0.0, rough: float = 0.85) -> StandardMaterial3D:
|
||||
var key := "%s|%.2f|%.2f" % [str(c), emis, rough]
|
||||
if _materialien.has(key):
|
||||
return _materialien[key]
|
||||
var m := StandardMaterial3D.new()
|
||||
m.albedo_color = c
|
||||
m.roughness = rough
|
||||
@@ -12,6 +19,7 @@ static func mat(c: Color, emis: float = 0.0, rough: float = 0.85) -> StandardMat
|
||||
m.emission_energy_multiplier = emis
|
||||
if c.a < 1.0:
|
||||
m.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
_materialien[key] = m
|
||||
return m
|
||||
|
||||
|
||||
@@ -159,35 +167,44 @@ static func _wand(mi: MeshInstance3D, normale: Vector3) -> MeshInstance3D:
|
||||
return mi
|
||||
|
||||
|
||||
const STUMPF := 0.6 # so hoch bleiben die Wände, wenn man drinnen steht
|
||||
|
||||
## Schnitt wie bei den Sims: steht der Spieler in einem Bau, verschwinden Dach
|
||||
## (bei Klötzen der ganze Klotz) und die beiden Wände, die zur Kamera zeigen.
|
||||
## Ein Bau: {c, size, hoch, teile, waende}. 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:
|
||||
## und Schild, und alle Wände des Hauses werden zu kniehohen Stümpfen gekürzt.
|
||||
## Nichts wird durchsichtig. Ein Bau: {c, size, hoch, teile, waende}.
|
||||
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
|
||||
(mi as GeometryInstance3D).cast_shadow = \
|
||||
GeometryInstance3D.SHADOW_CASTING_SETTING_OFF if im_weg \
|
||||
else GeometryInstance3D.SHADOW_CASTING_SETTING_ON
|
||||
if drin == bool(b.get("drin", false)):
|
||||
continue # nur anfassen, wenn sich etwas ändert
|
||||
b["drin"] = drin
|
||||
for t in b["teile"]:
|
||||
(t as Node3D).visible = not drin
|
||||
for w in b["waende"]:
|
||||
var n: Vector3 = w.get_meta("normal")
|
||||
(w as Node3D).visible = not (drin and n.dot(kamera - c) > 0.0)
|
||||
_stumpf(w as MeshInstance3D, c.y, drin)
|
||||
|
||||
|
||||
## Eine Wand kürzen oder wiederherstellen. Was ganz oben sitzt (der Türsturz),
|
||||
## verschwindet drinnen ganz.
|
||||
static func _stumpf(w: MeshInstance3D, boden: float, kurz: bool) -> void:
|
||||
var bm := w.mesh as BoxMesh
|
||||
if bm == null:
|
||||
w.visible = not kurz
|
||||
return
|
||||
if not w.has_meta("voll"):
|
||||
w.set_meta("voll", Vector2(bm.size.y, w.position.y))
|
||||
var voll: Vector2 = w.get_meta("voll")
|
||||
var unten: float = voll.y - voll.x * 0.5 - boden
|
||||
if unten > 0.3:
|
||||
w.visible = not kurz
|
||||
return
|
||||
w.visible = true
|
||||
bm.size.y = STUMPF if kurz else voll.x
|
||||
w.position.y = (boden + STUMPF * 0.5) if kurz else voll.y
|
||||
|
||||
|
||||
## Ein Satteldach: ein geschlossenes Prisma über den Wänden. Der First läuft
|
||||
|
||||
Reference in New Issue
Block a user