OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / gate_custom1_voxel.gd

83 lines · gd ref:
extends SceneTree
## Does CUSTOM1.y actually reach the material as the chunk's voxel size?
##
## The whole density-normal gate divides by this value. If it is zero the
## coarseness ratio collapses and the effect silently switches ITSELF off --
## which is indistinguishable, on screen, from a dozen other causes. Four
## iterations of that gate were tuned from screenshots without this ever being
## checked. So check it: read the mesh arrays back off the real terrain.
##
##   "$HYPER_TPS_GODOT" --headless --path . \
##       --script res://scenes/test/gate_custom1_voxel.gd
var MAP := "res://scenes/maps/map_dc_erosion.tscn"
var _map: Node = null
var _frames := 0

func _initialize() -> void:
	var packed := load(MAP) as PackedScene
	if packed == null:
		print("FAIL — %s did not load" % MAP); quit(2); return
	_map = packed.instantiate()
	root.add_child(_map)
	print("GATE: reading ARRAY_CUSTOM1 off real terrain meshes")

func _find_meshes(n: Node, out: Array) -> void:
	if n is MeshInstance3D and (n as MeshInstance3D).mesh != null:
		out.append(n)
	for c in n.get_children():
		_find_meshes(c, out)

func _process(_dt: float) -> bool:
	_frames += 1
	# Chunks are meshed on a worker; give them real time to arrive.
	if _frames < 400:
		return false
	var meshes: Array = []
	_find_meshes(_map, meshes)
	if meshes.is_empty():
		print("FAIL — no MeshInstance3D with a mesh after %d frames" % _frames)
		quit(1); return true
	print("  found %d terrain mesh instances" % meshes.size())

	var checked := 0
	var with_custom1 := 0
	var voxels := {}
	for mi in meshes:
		var mesh: Mesh = (mi as MeshInstance3D).mesh
		if mesh.get_surface_count() == 0:
			continue
		var arrays: Array = mesh.surface_get_arrays(0)
		checked += 1
		# Mesh.ARRAY_CUSTOM1 == 7. (13 is ARRAY_MAX, which is out of bounds --
		# and an out-of-bounds read here reports nothing rather than failing
		# the gate, so the first run of this looked like a terrain problem.)
		var custom1 = arrays[Mesh.ARRAY_CUSTOM1]
		if custom1 == null:
			continue
		with_custom1 += 1
		var vcount: int = (arrays[0] as PackedVector3Array).size()
		var f := custom1 as PackedFloat32Array
		if f.size() != vcount * 2:
			print("  FAIL — CUSTOM1 has %d floats for %d verts (expected %d, i.e. RG_FLOAT)"
				% [f.size(), vcount, vcount * 2])
			quit(1); return true
		# .y of the first few vertices: the chunk's voxel size.
		var v: float = f[1]
		voxels[v] = int(voxels.get(v, 0)) + 1
	print("  surfaces checked: %d, carrying CUSTOM1: %d" % [checked, with_custom1])
	if with_custom1 == 0:
		print("FAIL — no surface carries ARRAY_CUSTOM1 at all. CUSTOM1.y is 0 in")
		print("       the shader and any gate dividing by it is dead.")
		quit(1); return true
	var keys: Array = voxels.keys()
	keys.sort()
	print("  distinct CUSTOM1.y values (voxel size -> chunk count):")
	for k in keys:
		print("    %8.3f m : %d" % [k, voxels[k]])
	if keys.size() == 1 and float(keys[0]) == 0.0:
		print("FAIL — CUSTOM1.y is zero everywhere.")
		quit(1); return true
	print("PASS — CUSTOM1.y carries real voxel sizes; the gate's divisor is live.")
	quit(0)
	return true