From 342f12f6ec12c476af813316c37b03041cbe17a4 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Sat, 1 Mar 2025 17:56:20 +0100 Subject: radial chunk generation around player + noise ground level --- chunk.gd | 308 ++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 186 insertions(+), 122 deletions(-) (limited to 'chunk.gd') diff --git a/chunk.gd b/chunk.gd index 4d24eba..2003c4e 100644 --- a/chunk.gd +++ b/chunk.gd @@ -10,142 +10,176 @@ var mesh: ArrayMesh = ArrayMesh.new() func generate_block_data(row: int, column: int, depth: int, empty: bool = false): - Global.mutex.lock() - grid_position = Vector3i(row, column, depth) blocks = [] + blocks.resize(Global.CHUNK_SIZE.x * Global.CHUNK_SIZE.y * Global.CHUNK_SIZE.z) + for x in Global.CHUNK_SIZE.x: - blocks.append([]) - for y in Global.CHUNK_SIZE.y: - blocks[x].append([]) - for z in Global.CHUNK_SIZE.z: - var block_position = Vector3i( - grid_position.x * Global.CHUNK_SIZE.x + x, - grid_position.y * Global.CHUNK_SIZE.y + y, - grid_position.z * Global.CHUNK_SIZE.z + z - )# * 2 - var value = noise.get_noise_3d(block_position.x, block_position.y, block_position.z) * 100 + for z in Global.CHUNK_SIZE.z: + var block_position := Vector3i(x, 0, z) + var block_global_position := Vector3i( + grid_position.x * Global.CHUNK_SIZE.x + block_position.x, + 0, + grid_position.z * Global.CHUNK_SIZE.z + block_position.z + ) + var height := Global.CHUNK_SIZE.y + + if grid_position.y >= Global.GROUND_LEVEL: + var noise_2d := noise.get_noise_2d( + block_global_position.x, + block_global_position.z + ) * 100 + height = round(clamp(abs(noise_2d), 0, Global.CHUNK_SIZE.y)) + + for y in Global.CHUNK_SIZE.y: + block_position.y = y + block_global_position. y = grid_position.y * Global.CHUNK_SIZE.y + block_position.y + + var value = noise.get_noise_3d( + block_global_position.x, + block_global_position.y, + block_global_position.z + ) * 100 - var type = Block.Type.AIR - if value > 4: - type = Block.Type.GRASS - if value < -4: - type = Block.Type.STONE - #if value < -16: - #type = Block.Type.DIRT - if value < -17 and value > -20: - type = Block.Type.SAND - if abs(value) > 21 and abs(value) < 21.25: - type = [Block.Type.STONE, Block.Type.YELLOW_STONE, Block.Type.BLUE_STONE, Block.Type.RED_STONE, Block.Type.BLACK_STONE].pick_random() - #print(value) + var type := Block.Type.AIR + if height < y: + type = Block.Type.AIR + else: + if value > -15: + type = Block.Type.GRASS + elif value > -20: + type = Block.Type.STONE + #if value > 4: + #type = Block.Type.GRASS + #if value < -4: + #type = Block.Type.STONE + ##if value < -16: + ##type = Block.Type.DIRT + #if value < -17 and value > -20: + #type = Block.Type.SAND + #if abs(value) > 21 and abs(value) < 21.25: + #type = [Block.Type.STONE, Block.Type.YELLOW_STONE, Block.Type.BLUE_STONE, Block.Type.RED_STONE, Block.Type.BLACK_STONE].pick_random() + ##print(value) var block = Block.new() block.position = block_position + block.global_position = block_global_position block.type = type - if empty: + if empty or Global.MAX_HEIGHT < block.global_position.y: block.type = Block.Type.AIR - blocks[x][y].append(block) - - Global.mutex.unlock() + var index := x + Global.CHUNK_SIZE.x * y + Global.CHUNK_SIZE.x * Global.CHUNK_SIZE.y * z + blocks[index] = block func generate_mesh(): - Global.mutex.lock() - var material := preload("res://new_shader_material.tres") var st = SurfaceTool.new() st.begin(Mesh.PRIMITIVE_TRIANGLES) st.set_material(material) - for x in blocks.size(): - for y in blocks[x].size(): - for z in blocks[x][y].size(): - var block: Block = blocks[x][y][z] - - if block.type == Block.Type.AIR: - continue - - var block_front: Block - if block_exists(x, y, z + 1): - block_front = blocks[x][y][z + 1] - elif is_chunk_border(x, y, z) and chunk_exists(grid_position + Vector3i(0, 0, 1)): - var chunk_front := Global.chunks[grid_position + Vector3i(0, 0, 1)] - block_front = chunk_front.blocks[x][y][0] - - var block_back: Block - if block_exists(x, y, z - 1): - block_back = blocks[x][y][z - 1] - elif is_chunk_border(x, y, z) and chunk_exists(grid_position + Vector3i(0, 0, -1)): - var chunk_back := Global.chunks[grid_position + Vector3i(0, 0, -1)] - block_back = chunk_back.blocks[x][y][Global.CHUNK_SIZE.z - 1] - - var block_right: Block - if block_exists(x + 1, y, z): - block_right = blocks[x + 1][y][z] - elif is_chunk_border(x, y, z) and chunk_exists(grid_position + Vector3i(1, 0, 0)): - var chunk_right := Global.chunks[grid_position + Vector3i(1, 0, 0)] - block_right = chunk_right.blocks[0][y][z] - - var block_left: Block - if block_exists(x - 1, y, z): - block_left = blocks[x - 1][y][z] - elif is_chunk_border(x, y, z) and chunk_exists(grid_position + Vector3i(-1, 0, 0)): - var chunk_left := Global.chunks[grid_position + Vector3i(-1, 0, 0)] - block_left = chunk_left.blocks[Global.CHUNK_SIZE.x - 1][y][z] - - var block_top: Block - if block_exists(x, y + 1, z): - block_top = blocks[x][y + 1][z] - elif is_chunk_border(x, y, z) and chunk_exists(grid_position + Vector3i(0, 1, 0)): - var chunk_top := Global.chunks[grid_position + Vector3i(0, 1, 0)] - #if chunk_top.is_inside_tree(): - block_top = chunk_top.blocks[x][0][z] - - var block_bottom: Block - if block_exists(x, y - 1, z): - block_bottom = blocks[x][y - 1][z] - elif is_chunk_border(x, y, z) and chunk_exists(grid_position + Vector3i(0, -1, 0)): - var chunk_bottom := Global.chunks[grid_position + Vector3i(0, -1, 0)] - #if chunk_bottom.is_inside_tree(): - block_bottom = chunk_bottom.blocks[x][Global.CHUNK_SIZE.y - 1][z] - - if not block.type == Block.Type.AIR: - if block.type == Block.Type.GRASS: - if block_top and block_top.type != Block.Type.AIR: - block.type = Block.Type.DIRT - - var rng = RandomNumberGenerator.new() - rng.seed = randi() - st.set_color(Color(rng.randf(), rng.randf(), rng.randf())) - - st.set_uv(Vector2(0, 0)) - - if not block_front or block_front.type == Block.Type.AIR: - block.add_face(st, Block.Face.FRONT) - - if not block_back or block_back.type == Block.Type.AIR: - block.add_face(st, Block.Face.BACK) - - if not block_right or block_right.type == Block.Type.AIR: - block.add_face(st, Block.Face.RIGHT) - - if not block_left or block_left.type == Block.Type.AIR: - block.add_face(st, Block.Face.LEFT) - - if not block_top or block_top.type == Block.Type.AIR: - block.add_face(st, Block.Face.TOP) - - if not block_bottom or block_bottom.type == Block.Type.AIR: - block.add_face(st, Block.Face.BOTTOM) + for index in blocks.size(): + var block: Block = blocks[index] + if block.type == Block.Type.AIR: + continue + + var block_front: Block + if is_chunk_border_face(block.position, Block.Face.BACK): + if chunk_exists(grid_position + Vector3i(0, 0, 1)): + var chunk_front := Global.chunks[grid_position + Vector3i(0, 0, 1)] + if chunk_front.is_inside_tree(): + block_front = chunk_front.get_block(Vector3i(block.position.x, block.position.y, 0)) + else: + block_front = get_block(block.position + Vector3i(0, 0, 1)) + + var block_back: Block + if is_chunk_border_face(block.position, Block.Face.FRONT): + if chunk_exists(grid_position + Vector3i(0, 0, -1)): + var chunk_back := Global.chunks[grid_position + Vector3i(0, 0, -1)] + if chunk_back.is_inside_tree(): + block_back = chunk_back.get_block(Vector3i( + block.position.x, block.position.y, Global.CHUNK_SIZE.z - 1) + ) + else: + block_back = get_block(block.position + Vector3i(0, 0, -1)) + + var block_right: Block + if is_chunk_border_face(block.position, Block.Face.RIGHT): + if chunk_exists(grid_position + Vector3i(1, 0, 0)): + var chunk_right := Global.chunks[grid_position + Vector3i(1, 0, 0)] + if chunk_right.is_inside_tree(): + block_right = chunk_right.get_block(Vector3i(0, block.position.y, block.position.z)) + else: + block_right = get_block(block.position + Vector3i(1, 0, 0)) + + var block_left: Block + if is_chunk_border_face(block.position, Block.Face.LEFT): + if chunk_exists(grid_position + Vector3i(-1, 0, 0)): + var chunk_left := Global.chunks[grid_position + Vector3i(-1, 0, 0)] + if chunk_left.is_inside_tree(): + block_left = chunk_left.get_block(Vector3i( + Global.CHUNK_SIZE.x - 1, block.position.y, block.position.z) + ) + else: + block_left = get_block(block.position + Vector3i(-1, 0, 0)) + + var block_top: Block + if is_chunk_border_face(block.position, Block.Face.TOP): + if chunk_exists(grid_position + Vector3i(0, 1, 0)): + var chunk_top := Global.chunks[grid_position + Vector3i(0, 1, 0)] + if chunk_top.is_inside_tree(): + block_top = chunk_top.get_block(Vector3i(block.position.x, 0, block.position.z)) + else: + block_top = get_block(block.position + Vector3i(0, 1, 0)) + + var block_bottom: Block + if is_chunk_border_face(block.position, Block.Face.BOTTOM): + if chunk_exists(grid_position + Vector3i(0, -1, 0)): + var chunk_bottom := Global.chunks[grid_position + Vector3i(0, -1, 0)] + if chunk_bottom.is_inside_tree(): + block_bottom = chunk_bottom.get_block(Vector3i( + block.position.x, Global.CHUNK_SIZE.y - 1, block.position.z) + ) + else: + block_bottom = get_block(block.position + Vector3i(0, -1, 0)) + + if not block.type == Block.Type.AIR: + if block.type == Block.Type.GRASS: + if block_top and block_top.type != Block.Type.AIR: + block.type = Block.Type.DIRT + elif block.type == Block.Type.DIRT: + if not block_top or block_top.type == Block.Type.AIR: + block.type = Block.Type.GRASS + + var rng = RandomNumberGenerator.new() + rng.seed = randi() + st.set_color(Color(rng.randf(), rng.randf(), rng.randf())) + + st.set_uv(Vector2(0, 0)) + + if not block_front or block_front.type == Block.Type.AIR: + block.add_face(st, Block.Face.FRONT) + + if not block_back or block_back.type == Block.Type.AIR: + block.add_face(st, Block.Face.BACK) + + if not block_right or block_right.type == Block.Type.AIR: + block.add_face(st, Block.Face.RIGHT) + + if not block_left or block_left.type == Block.Type.AIR: + block.add_face(st, Block.Face.LEFT) + + if not block_top or block_top.type == Block.Type.AIR: + block.add_face(st, Block.Face.TOP) + + if not block_bottom or block_bottom.type == Block.Type.AIR: + block.add_face(st, Block.Face.BOTTOM) #st.generate_normals() mesh = st.commit() - - Global.mutex.unlock() func update_mesh() -> void: @@ -159,7 +193,8 @@ func update_mesh() -> void: func add_to(node: Node) -> void: - node.add_child(self) + name = "Chunk_%s_%s_%s" % [grid_position.x, grid_position.y, grid_position.z] + node.add_child(self, true) update_mesh() @@ -172,19 +207,32 @@ func generate_chunk(row: int, column: int, depth: int): func add_block(block_position: Vector3, block_type: Block.Type = Block.Type.GRASS) -> void: var block = Block.new() - block.position = Vector3i( - grid_position.x * Global.CHUNK_SIZE.x + int(block_position.x), - grid_position.y * Global.CHUNK_SIZE.y + int(block_position.y), - grid_position.z * Global.CHUNK_SIZE.z + int(block_position.z) + block.position = Vector3i(block_position) + block.global_position = Vector3i( + grid_position.x * Global.CHUNK_SIZE.x + block.position.x, + grid_position.y * Global.CHUNK_SIZE.y + block.position.y, + grid_position.z * Global.CHUNK_SIZE.z + block.position.z ) block.type = block_type - blocks[block_position.x][block_position.y][block_position.z] = block + #blocks[block_position.x][block_position.y][block_position.z] = block + set_block(block.position, block) #generate_mesh.call_deferred() func remove_block(block_position: Vector3) -> void: - blocks[block_position.x][block_position.y][block_position.z].type = Block.Type.AIR + #blocks[block_position.x][block_position.y][block_position.z].type = Block.Type.AIR + var block := get_block(block_position) + block.type = Block.Type.AIR + set_block(block.position, block) + print(block_position) + + +func get_block(p: Vector3i) -> Block: + return blocks[p.x + Global.CHUNK_SIZE.x * p.y + Global.CHUNK_SIZE.x * Global.CHUNK_SIZE.y * p.z] + +func set_block(p: Vector3i, block: Block) -> void: + blocks[p.x + Global.CHUNK_SIZE.x * p.y + Global.CHUNK_SIZE.x * Global.CHUNK_SIZE.y * p.z] = block static func chunk_exists(chunk_position: Vector3i): @@ -194,13 +242,29 @@ static func chunk_exists(chunk_position: Vector3i): func block_exists(x: int, y: int, z: int): return x >= 0 and blocks.size() - 1 >= x and y >= 0 and blocks[x].size() - 1 >= y and z >= 0 and blocks[x][y].size() - 1 >= z -func is_chunk_border(x: int, y: int, z: int): - return x == 0 or x == Global.CHUNK_SIZE.x - 1 or y == 0 or y == Global.CHUNK_SIZE.y - 1 or z == 0 or z == Global.CHUNK_SIZE.z - 1 +func is_chunk_border(p: Vector3i): + return p.x == 0 or p.x == Global.CHUNK_SIZE.x - 1 or p.y == 0 or p.y == Global.CHUNK_SIZE.y - 1 or p.z == 0 or p.z == Global.CHUNK_SIZE.z - 1 + +func is_chunk_border_face(block_position: Vector3i, face: Block.Face) -> bool: + if face == Block.Face.FRONT: + return block_position.z == 0 + elif face == Block.Face.BACK: + return block_position.z == Global.CHUNK_SIZE.z - 1 + elif face == Block.Face.LEFT: + return block_position.x == 0 + elif face == Block.Face.RIGHT: + return block_position.x == Global.CHUNK_SIZE.z - 1 + elif face == Block.Face.BOTTOM: + return block_position.y == 0 + elif face == Block.Face.TOP: + return block_position.y == Global.CHUNK_SIZE.y - 1 + + return false func get_bordering_chunks(block_position: Vector3i) -> Array[Vector3i]: var bordering_chunks := [] as Array[Vector3i] - if not is_chunk_border(block_position.x, block_position.y, block_position.z): + if not is_chunk_border(block_position): return bordering_chunks if block_position.z == 0: -- cgit v1.2.3