D5 (t_e81aed01): Render-Nachweis tools/probe_d5_render.gd (Fels/Kaktus/Stein/Decal platziert)
This commit is contained in:
parent
0f86182a2c
commit
ebe3dd276b
1 changed files with 97 additions and 0 deletions
97
tools/probe_d5_render.gd
Normal file
97
tools/probe_d5_render.gd
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
extends SceneTree
|
||||||
|
## D5-Bau-Nachweis (t_e81aed01): platziert je 1 Natur-Objekt (Fels, Kaktus, Decal)
|
||||||
|
## ueber die EDITOR-eigene Aufloesung (GlbMeshStore.mesh_fuer — Registry-glb +
|
||||||
|
## Fusspunkt-Normalisierung) auf einer Bodenplatte und rendert ein PNG.
|
||||||
|
## Beweist visuell: Fels/Kaktus STEHEN auf dem Boden, das Decal LIEGT FLACH
|
||||||
|
## (2 cm Lift gegen Z-Fighting).
|
||||||
|
##
|
||||||
|
## xvfb-run -a godot4 --rendering-driver opengl3 --path . --script res://tools/probe_d5_render.gd
|
||||||
|
## Ausgabe: PROBE_D5_RENDER_OK + PNG-Pfad
|
||||||
|
|
||||||
|
const AUSGABE := "user://probe_d5_platzierung.png"
|
||||||
|
const PLANUNG := [
|
||||||
|
{"oid": "rock_003", "pos": Vector3(-3.2, 0.0, 0.0)},
|
||||||
|
{"oid": "cactus_008", "pos": Vector3(0.0, 0.0, 0.0)},
|
||||||
|
{"oid": "stone_016", "pos": Vector3(2.4, 0.0, 1.2)},
|
||||||
|
{"oid": "decal_001", "pos": Vector3(-1.0, 0.02, 3.2)},
|
||||||
|
]
|
||||||
|
|
||||||
|
var vp: SubViewport
|
||||||
|
var kamera: Camera3D
|
||||||
|
var rahmen := 0
|
||||||
|
var fehler: Array = []
|
||||||
|
|
||||||
|
|
||||||
|
func _initialize() -> void:
|
||||||
|
vp = SubViewport.new()
|
||||||
|
vp.size = Vector2i(900, 600)
|
||||||
|
vp.own_world_3d = true
|
||||||
|
vp.render_target_update_mode = SubViewport.UPDATE_ALWAYS
|
||||||
|
root.add_child(vp)
|
||||||
|
|
||||||
|
var env := Environment.new()
|
||||||
|
env.background_mode = Environment.BG_COLOR
|
||||||
|
env.background_color = Color(0.55, 0.62, 0.72)
|
||||||
|
env.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
|
||||||
|
env.ambient_light_color = Color(1, 1, 1)
|
||||||
|
env.ambient_light_energy = 0.8
|
||||||
|
var we := WorldEnvironment.new()
|
||||||
|
we.environment = env
|
||||||
|
vp.add_child(we)
|
||||||
|
|
||||||
|
var sonne := DirectionalLight3D.new()
|
||||||
|
sonne.rotation_degrees = Vector3(-50.0, 40.0, 0.0)
|
||||||
|
sonne.light_energy = 1.2
|
||||||
|
vp.add_child(sonne)
|
||||||
|
|
||||||
|
# Bodenplatte: genau das, worauf Spieler laufen (Terrain-Ersatz)
|
||||||
|
var boden := MeshInstance3D.new()
|
||||||
|
var pm := PlaneMesh.new()
|
||||||
|
pm.size = Vector2(40.0, 40.0)
|
||||||
|
boden.mesh = pm
|
||||||
|
var mat := StandardMaterial3D.new()
|
||||||
|
mat.albedo_color = Color(0.78, 0.68, 0.45)
|
||||||
|
boden.material_override = mat
|
||||||
|
vp.add_child(boden)
|
||||||
|
|
||||||
|
for e in PLANUNG:
|
||||||
|
var oid := str(e["oid"])
|
||||||
|
var mesh: Mesh = GlbMeshStore.mesh_fuer(oid)
|
||||||
|
if mesh == null:
|
||||||
|
fehler.append("%s: GlbMeshStore liefert kein Mesh" % oid)
|
||||||
|
continue
|
||||||
|
var mi := MeshInstance3D.new()
|
||||||
|
mi.name = "Platz_%s" % oid
|
||||||
|
mi.mesh = mesh
|
||||||
|
var pos: Vector3 = e["pos"]
|
||||||
|
mi.position = pos
|
||||||
|
vp.add_child(mi)
|
||||||
|
var ab: AABB = mesh.get_aabb()
|
||||||
|
print("%-11s pos.y=%.2f mesh-Unterkante=%.3f m Oberkante=%.3f m XZ-Zentrum=(%.3f, %.3f)" % [
|
||||||
|
oid, pos.y, pos.y + ab.position.y, pos.y + ab.position.y + ab.size.y,
|
||||||
|
ab.position.x + ab.size.x * 0.5, ab.position.z + ab.size.z * 0.5])
|
||||||
|
|
||||||
|
kamera = Camera3D.new()
|
||||||
|
kamera.current = true
|
||||||
|
kamera.fov = 60.0
|
||||||
|
vp.add_child(kamera)
|
||||||
|
|
||||||
|
|
||||||
|
func _process(_delta: float) -> bool:
|
||||||
|
rahmen += 1
|
||||||
|
if rahmen < 4:
|
||||||
|
return false
|
||||||
|
if rahmen == 4:
|
||||||
|
kamera.look_at_from_position(Vector3(2.0, 2.4, 9.0), Vector3(-0.4, 0.8, 0.8), Vector3.UP)
|
||||||
|
return false
|
||||||
|
if rahmen == 8:
|
||||||
|
var pfad := ProjectSettings.globalize_path(AUSGABE)
|
||||||
|
var img := vp.get_texture().get_image()
|
||||||
|
img.save_png(pfad)
|
||||||
|
print("Bild: %s (%dx%d)" % [pfad, img.get_width(), img.get_height()])
|
||||||
|
for f in fehler:
|
||||||
|
print(" FEHLER: %s" % f)
|
||||||
|
print("PROBE_D5_RENDER_%s" % ("FAIL" if not fehler.is_empty() else "OK"))
|
||||||
|
quit(0)
|
||||||
|
return true
|
||||||
|
return false
|
||||||
Loading…
Reference in a new issue