OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / dc_fandisk_test.gd

137 lines · gd ref:
@tool
extends Node3D

@onready var mesh_instance: MeshInstance3D = $MeshInstance3D
@onready var camera: Camera3D = $Camera
@onready var label: Label = $CanvasLayer/StatsLabel

var orbit_angle := 0.0
var orbit_pitch := 0.3
var orbit_radius := 8.0
var orbit_speed := 0.0
var center := Vector3.ZERO
var current_voxel_size := 0.1
var dragging := false
var last_mouse := Vector2.ZERO

func _ready() -> void:
	if Engine.is_editor_hint():
		# Generate in editor too so it shows in viewport
		_generate_fandisk(current_voxel_size)
	else:
		_generate_fandisk(current_voxel_size)

func _generate_fandisk(voxel_size: float) -> void:
	current_voxel_size = voxel_size
	label.text = "Generating fandisk at voxel_size=%.3f..." % voxel_size

	var gen = DCTerrainGeneratorMeshSDF.new()
	gen.mesh_path = "res://fandisk.glb"
	print("Fandisk loaded: ", gen.get_triangle_count(), " source triangles")

	var mesh = DCTerrainUtils.mesh_from_generator_auto(gen, voxel_size)
	mesh_instance.mesh = mesh

	if mesh and mesh.get_surface_count() > 0:
		var aabb = mesh.get_aabb()
		center = aabb.get_center()
		orbit_radius = aabb.size.length() * 1.2
		print("AABB center: ", center, " size: ", aabb.size)

	_update_label()

func _process(delta: float) -> void:
	if Engine.is_editor_hint():
		return
	orbit_angle += orbit_speed * delta
	_update_camera()

func _update_camera() -> void:
	var pitch_clamped = clamp(orbit_pitch, -1.5, 1.5)
	camera.position = center + Vector3(
		cos(orbit_angle) * cos(pitch_clamped) * orbit_radius,
		sin(pitch_clamped) * orbit_radius,
		sin(orbit_angle) * cos(pitch_clamped) * orbit_radius
	)
	camera.look_at(center)

func _update_label() -> void:
	label.text = "Fandisk DC Test | Voxel: %.3f\n" % current_voxel_size
	label.text += "LMB drag: orbit | Scroll: zoom | MMB drag: pan\n"
	label.text += "1/2/3: resolution | Space: auto-rotate | F12: screenshot"

func _unhandled_input(event: InputEvent) -> void:
	if event is InputEventMouseButton:
		match event.button_index:
			MOUSE_BUTTON_LEFT:
				dragging = event.pressed
				last_mouse = event.position
			MOUSE_BUTTON_RIGHT:
				dragging = event.pressed
				last_mouse = event.position
			MOUSE_BUTTON_WHEEL_UP:
				orbit_radius = max(0.5, orbit_radius * 0.9)
				_update_camera()
			MOUSE_BUTTON_WHEEL_DOWN:
				orbit_radius *= 1.1
				_update_camera()
			MOUSE_BUTTON_MIDDLE:
				dragging = event.pressed
				last_mouse = event.position

	elif event is InputEventMouseMotion and dragging:
		var delta = event.position - last_mouse
		last_mouse = event.position

		if Input.is_mouse_button_pressed(MOUSE_BUTTON_MIDDLE):
			# Pan
			var right = camera.global_transform.basis.x
			var up = camera.global_transform.basis.y
			var pan_speed = orbit_radius * 0.002
			center -= right * delta.x * pan_speed
			center += up * delta.y * pan_speed
			_update_camera()
		else:
			# Orbit
			orbit_angle -= delta.x * 0.005
			orbit_pitch += delta.y * 0.005
			_update_camera()

	elif event is InputEventKey and event.pressed:
		match event.keycode:
			KEY_1:
				_generate_fandisk(0.2)
			KEY_2:
				_generate_fandisk(0.1)
			KEY_3:
				_generate_fandisk(0.05)
			KEY_4:
				_generate_fandisk(0.025)
			KEY_SPACE:
				orbit_speed = 0.0 if orbit_speed > 0.0 else 0.5
			KEY_R:
				# Reset view
				orbit_angle = 0.0
				orbit_pitch = 0.3
				if mesh_instance.mesh and mesh_instance.mesh.get_surface_count() > 0:
					var aabb = mesh_instance.mesh.get_aabb()
					center = aabb.get_center()
					orbit_radius = aabb.size.length() * 1.2
				_update_camera()
			KEY_W:
				# Toggle wireframe
				var vp = get_viewport()
				if vp.debug_draw == Viewport.DEBUG_DRAW_WIREFRAME:
					vp.debug_draw = Viewport.DEBUG_DRAW_DISABLED
				else:
					vp.debug_draw = Viewport.DEBUG_DRAW_WIREFRAME
			KEY_F12:
				_take_screenshot()

func _take_screenshot() -> void:
	var img = get_viewport().get_texture().get_image()
	var timestamp = Time.get_datetime_string_from_system().replace(":", "-")
	var path = "user://fandisk_%s.png" % timestamp
	img.save_png(path)
	print("Screenshot saved: ", path)