## Volume to Mesh must actually MESH -- density field in, triangles out.
##
## The extractor is dc-terrain's libdc (Dual Contouring), compiled into this
## library rather than reimplemented. This asserts the wiring works end to end
## and that Resolution 0 still means "carry the volume, do not mesh", which is
## what every graph written before today gets.
extends SceneTree
var _fail := 0
func _ck(n: String, ok: bool, d: String) -> void:
print(" %-38s %s %s" % [n, "PASS" if ok else "FAIL", d])
if not ok: _fail += 1
func _sphere_graph(res: int) -> ProcNodeGraph:
var g := ProcNodeGraph.new()
var s1 := g.add_node(SphereSdfNode.new())
var vtm := g.add_node(VolumeToMeshNode.new())
g.connect_sockets(s1, 0, vtm, 0)
g.get_node(vtm).set_input_default(1, res)
g.get_node(vtm).set_input_default(2, Vector3(-1.5, -1.5, -1.5))
g.get_node(vtm).set_input_default(3, Vector3(3.0, 3.0, 3.0))
return g
func _init() -> void:
# Resolution 0: the pre-existing behaviour, unchanged.
var g0 := _sphere_graph(0)
var geo0 = g0.evaluate_socket(1, 0)
_ck("res 0: volume carried", geo0 != null and geo0.get_volume() != null
and not geo0.get_volume().get_glsl_source().is_empty(), "ProcVolume has GLSL")
_ck("res 0: no mesh", geo0 != null and (geo0.get_mesh() == null
or geo0.get_mesh().vertex_count() == 0), "meshing is opt-in")
# Resolution 16. ⛔ THIS DOES NOT MESH YET, and the gate says so rather than
# asserting a success that is not there. The extractor is wired and reachable
# -- libdc compiles into this library -- but the volume nodes have no CPU
# implementation: SphereSdfNode::execute writes its RADIUS as a placeholder
# ("Since we don't have a single eval position in the mesh context"), so the
# field is constant and Dual Contouring finds no zero crossing.
#
# When the volume nodes evaluate per position, these two flip to
# vertex_count() > 0 and the sphere-radius check below becomes the real one.
var g1 := _sphere_graph(16)
var geo1 = g1.evaluate_socket(1, 0)
var m = geo1.get_mesh() if geo1 != null else null
_ck("res 16: KNOWN GAP, no mesh yet", m == null or m.vertex_count() == 0,
"CPU volume nodes are stubs -- see the comment above")
_ck("res 16: volume still carried", geo1 != null and geo1.get_volume() != null
and not geo1.get_volume().get_glsl_source().is_empty(),
"mesh AND volume on one geometry")
print("\n%d/%d passed" % [4 - _fail, 4])
quit(1 if _fail > 0 else 0)