summaryrefslogtreecommitdiff
path: root/main.gd
blob: 1f125d989fb0305f604beae14a49465302738d03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class_name World
extends Node3D


@onready var noise := FastNoiseLite.new()

var chunks_to_update: Array[Vector3i] = []
var active_task_id: int = -1


func _ready() -> void:
	Global.player = $Player
	noise.seed = randi()
	
	#var world_size := Vector3i(4, 2, 4)
	#
	#for column in range(world_size.y, 0, -1):
		#for row in range(- world_size.x * 0.5, world_size.x * 0.5):
			#for depth in range(- world_size.z * 0.5, world_size.z * 0.5):
				#chunks_to_update.append(Vector3i(row, column, depth))
	chunks_to_update.append(Vector3i(0, 0, 0))
	chunks_to_update.append(Vector3i(0, 1, 0))
	#chunks_to_update.append(Vector3i(0, 2, 0))


func _process(_delta: float) -> void:
	if chunks_to_update.size() > 0:
		if active_task_id == -1:
			active_task_id = WorkerThreadPool.add_group_task(update_chunk_task, chunks_to_update.size())
		else:
			if WorkerThreadPool.is_group_task_completed(active_task_id):
				WorkerThreadPool.wait_for_group_task_completion(active_task_id)
				chunks_to_update.clear()
				active_task_id = -1
	
	# TODO: get player current chunk
	# TODO: get all chunk positions in radius
	# TODO: add missing chunks. remove surplus chunks


func update_chunk_task(index: int) -> void:
	update_chunk(chunks_to_update[index])

func update_chunk(chunk_position: Vector3i) -> void:
	if Chunk.chunk_exists(chunk_position):
		var chunk: Chunk = Global.chunks[chunk_position]
		chunk.generate_mesh()
		chunk.update_mesh.call_deferred()
	
	else:
		var chunk := create_chunk(chunk_position)
		chunk.generate_block_data(chunk_position.x, chunk_position.y, chunk_position.z)
		chunk.generate_mesh()
		chunk.add_to.call_deferred(self)


func create_chunk(chunk_position: Vector3i) -> Chunk:
	var chunk: Chunk = preload("res://chunk.tscn").instantiate()
	chunk.noise = noise
	Global.chunks[chunk_position] = chunk
	
	return chunk


func add_block(target_position: Vector3, normal: Vector3, block_type: Block.Type = Block.Type.AIR):
	var chunk_idx := Chunk.global_to_chunk(target_position + normal, Vector3.ZERO)
	var chunk: Chunk
	
	if Chunk.chunk_exists(chunk_idx):
		chunk = Global.chunks[chunk_idx]
	else:
		chunk = create_chunk(Vector3(chunk_idx.x, chunk_idx.y, chunk_idx.z))
		chunk.generate_block_data(chunk_idx.x, chunk_idx.y, chunk_idx.z, true)
		chunk.add_to.call_deferred(self)
	
	var block_chunk_idx := Chunk.global_to_chunk_block(target_position + normal, normal)
	chunk.add_block(block_chunk_idx, block_type)
	chunks_to_update.append(chunk.grid_position)


func remove_block(target_position: Vector3, normal: Vector3):
	var chunk_idx := Chunk.global_to_chunk(target_position, normal)
	if Chunk.chunk_exists(chunk_idx):
		var chunk: Chunk = Global.chunks[chunk_idx]
		var block_chunk_idx := Chunk.global_to_chunk_block(target_position, normal)
		chunk.remove_block(block_chunk_idx)
		chunks_to_update.append(chunk.grid_position)
		chunks_to_update.append_array(chunk.get_bordering_chunks(block_chunk_idx).filter(func(item):
			return Chunk.chunk_exists(item)
		))