OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / proc_nodes_terrain_test.gd

157 lines · gd ref:
@tool
extends Node3D

## Phase 8: proc-nodes / dc-terrain integration test
##
## Side-by-side comparison:
##   Left:  DCTerrain with ProcTerrainGenerator (GDScript density function)
##   Right: ProcGeometryNode with MeshGrid+Displace (proc-nodes mesh generation)
##
## Setup:
##   1. Create a Node3D scene, attach this script
##   2. Add a DCTerrain child named "DCTerrain"
##   3. Add a ProcGeometryNode child named "ProcTerrain"
##   4. Run the scene — this script configures both

@export var spacing: float = 60.0

@export_group("DC Terrain (Script Generator)")
@export var dc_terrain_size: float = 64.0
@export var dc_voxel_size: float = 0.5
@export var dc_octree_depth: int = 4

@export_group("Proc-Nodes Terrain (MeshGrid + Displace)")
@export var proc_grid_size: float = 50.0
@export var proc_grid_resolution: int = 300
@export var proc_noise_strength: float = 8.0
@export var proc_noise_scale: float = 0.05
@export var proc_noise_octaves: int = 6

@export_group("Actions")
@export var rebuild: bool = false:
	set(v):
		if v:
			_setup()
		rebuild = false

func _ready() -> void:
	call_deferred("_setup")

func _setup() -> void:
	_setup_dc_terrain()
	_setup_proc_terrain()
	print("Phase 8 test: DC terrain (left) vs proc-nodes terrain (right)")

func _setup_dc_terrain() -> void:
	var dc = get_node_or_null("DCTerrain")
	if not dc:
		push_warning("proc_nodes_terrain_test: add a DCTerrain child named 'DCTerrain'")
		return

	# Position on the left
	dc.position.x = -spacing * 0.5

	# Assign the ProcTerrainGenerator resource
	var gen = ProcTerrainGenerator.new()
	gen.ground_height = 0.0
	gen.primary_frequency = 0.02
	gen.primary_amplitude = 15.0
	gen.primary_octaves = 4
	gen.detail_frequency = 0.08
	gen.detail_amplitude = 3.0
	gen.ridge_enabled = true
	gen.ridge_frequency = 0.015
	gen.ridge_amplitude = 20.0
	dc.generator = gen

	# Configure terrain parameters
	dc.terrain_size = dc_terrain_size
	dc.voxel_size = dc_voxel_size
	dc.octree_depth = dc_octree_depth
	dc.use_noise = false  # We're using the script generator, not built-in noise

	dc.rebuild()
	print("  DC terrain: script generator, size=", dc_terrain_size, " voxel=", dc_voxel_size)

func _setup_proc_terrain() -> void:
	var proc = get_node_or_null("ProcTerrain")
	if not proc:
		push_warning("proc_nodes_terrain_test: add a ProcGeometryNode child named 'ProcTerrain'")
		return

	# Position on the right
	proc.position.x = spacing * 0.5

	# Build proc-nodes graph: MeshGrid -> Displace
	var g = ProcNodeGraph.new()

	# 0: Grid
	var grid = MeshGridNode.new()
	g.add_node(grid)

	# 1-2: Grid size
	var sx = ValueNode.new()
	sx.value = proc_grid_size
	g.add_node(sx)
	var sy = ValueNode.new()
	sy.value = proc_grid_size
	g.add_node(sy)

	# 3-4: Grid resolution
	var vx = ValueNode.new()
	vx.value = float(proc_grid_resolution)
	g.add_node(vx)
	var vy = ValueNode.new()
	vy.value = float(proc_grid_resolution)
	g.add_node(vy)

	# 5: Displace (noise-based terrain displacement)
	var displace = DisplaceNode.new()
	g.add_node(displace)

	# 6-9: Noise parameters
	var strength = ValueNode.new()
	strength.value = proc_noise_strength
	g.add_node(strength)

	var nscale = ValueNode.new()
	nscale.value = proc_noise_scale
	g.add_node(nscale)

	var ndetail = ValueNode.new()
	ndetail.value = float(proc_noise_octaves)
	g.add_node(ndetail)

	var nrough = ValueNode.new()
	nrough.value = 0.5
	g.add_node(nrough)

	# Connections
	g.connect_sockets(1, 0, 0, 0)  # sx -> grid.SizeX
	g.connect_sockets(2, 0, 0, 1)  # sy -> grid.SizeY
	g.connect_sockets(3, 0, 0, 2)  # vx -> grid.VertsX
	g.connect_sockets(4, 0, 0, 3)  # vy -> grid.VertsY
	g.connect_sockets(0, 0, 5, 0)  # grid -> displace.geometry
	g.connect_sockets(6, 0, 5, 1)  # strength -> displace.strength
	g.connect_sockets(7, 0, 5, 2)  # scale -> displace.scale
	g.connect_sockets(8, 0, 5, 3)  # detail -> displace.detail
	g.connect_sockets(9, 0, 5, 4)  # roughness -> displace.roughness

	proc.graph = g
	var verts = proc_grid_resolution * proc_grid_resolution
	print("  Proc terrain: MeshGrid+Displace, ", verts, " verts, GPU-accelerated")

	# Apply terrain material
	call_deferred("_apply_proc_material")

func _apply_proc_material() -> void:
	var proc = get_node_or_null("ProcTerrain")
	if not proc:
		return
	var mesh_child = proc.get_node_or_null("MeshOutput")
	if mesh_child and mesh_child is MeshInstance3D:
		var mat = StandardMaterial3D.new()
		mat.albedo_color = Color(0.35, 0.5, 0.3)
		mat.roughness = 0.8
		mesh_child.material_override = mat