class_name Generator extends Node3D @export var scene: PackedScene @export var noise: Noise @export var size_x: float @export var size_z: float @export var step: float = 1 @export var density: float @export var scale_min := 1.0 @export var scale_max := 1.0 @export var tilt := 0.0 func _ready(): if !visible: return rebuild() func rebuild(): remove_children() for x in range(-size_x, size_x, step): for z in range(-size_z, size_z, step): if noise.get_noise_2d(x, z) < 1 - density * 2: continue var instance := generate(x, z) add_child(instance) func generate(x: int, z: int) -> Node3D: var t := scene.instantiate() as Node3D t.position.x = x t.position.z = z var angle_xz := randf() * TAU t.rotation.x = cos(angle_xz) * randf() * tilt t.rotation.y = randf() * TAU t.rotation.z = sin(angle_xz) * randf() * tilt var uniform_scale := scale_min + randf() * (scale_max - scale_min) t.scale = Vector3(uniform_scale, uniform_scale, uniform_scale) return t func remove_children(): var num_children = get_child_count() for n in range(num_children): get_child(num_children - 1 - n).queue_free()