84 lines
2.2 KiB
GDScript
84 lines
2.2 KiB
GDScript
extends Node3D
|
|
|
|
@export var tree: Mesh
|
|
@export var leaves: Mesh
|
|
@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 position_randomness := 1.0
|
|
|
|
const TILE_SIZE := 10
|
|
|
|
func _ready():
|
|
if !visible:
|
|
return
|
|
|
|
var total_count := 0
|
|
var tile_count := 0
|
|
|
|
var old_tile_x := NAN
|
|
var old_tile_z := NAN
|
|
|
|
var offsets: Array[Vector3] = []
|
|
|
|
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 tile_x := x / TILE_SIZE
|
|
var tile_z := z / TILE_SIZE
|
|
|
|
if tile_x != old_tile_x || tile_z != old_tile_z:
|
|
if tile_count > 0:
|
|
var tile := make_tile(old_tile_x, old_tile_z)
|
|
tile.multimesh.instance_count = tile_count
|
|
tile.multimesh.visible_instance_count = tile_count
|
|
|
|
for i in range(tile_count):
|
|
tile.multimesh.set_instance_transform(i, Transform3D(Basis(), offsets[i] - tile.position))
|
|
|
|
add_child(tile)
|
|
|
|
var tile2 := make_tile(old_tile_x, old_tile_z)
|
|
tile2.multimesh.mesh = leaves
|
|
tile2.multimesh.instance_count = tile_count
|
|
tile2.multimesh.visible_instance_count = tile_count
|
|
|
|
for i in range(tile_count):
|
|
tile2.multimesh.set_instance_transform(i, Transform3D(Basis(), offsets[i] - tile.position))
|
|
|
|
add_child(tile2)
|
|
|
|
tile_count = 0
|
|
offsets.resize(0)
|
|
|
|
old_tile_x = tile_x
|
|
old_tile_z = tile_z
|
|
|
|
var offset := Vector3.ZERO
|
|
offset.x = x + (randf() - 0.5) * position_randomness
|
|
offset.z = z + (randf() - 0.5) * position_randomness
|
|
offsets.append(offset)
|
|
|
|
tile_count += 1
|
|
total_count += 1
|
|
|
|
print("Generated %d trees" % total_count)
|
|
|
|
func make_tile(x, z) -> MultiMeshInstance3D:
|
|
prints("Tile:", x * TILE_SIZE, z * TILE_SIZE)
|
|
|
|
var instance := MultiMeshInstance3D.new()
|
|
instance.multimesh = MultiMesh.new()
|
|
instance.multimesh.mesh = tree
|
|
instance.multimesh.transform_format = MultiMesh.TRANSFORM_3D
|
|
|
|
var safe_area := Vector3(0, 0, 0)
|
|
instance.position = Vector3(x * TILE_SIZE, 0, z * TILE_SIZE)
|
|
instance.custom_aabb.position = -safe_area
|
|
instance.custom_aabb.size = Vector3(TILE_SIZE, 30, TILE_SIZE) + safe_area * 2
|
|
return instance
|