From f448ca4259d7f76fc58bc3b5c12ea8d04ab49a87 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Sat, 11 Jan 2025 12:31:00 +0100 Subject: next commit --- chunk.gd | 164 ++++++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 126 insertions(+), 38 deletions(-) (limited to 'chunk.gd') diff --git a/chunk.gd b/chunk.gd index 24713a2..c750153 100644 --- a/chunk.gd +++ b/chunk.gd @@ -2,39 +2,31 @@ class_name Chunk extends Node -var chunk_size := Vector3(16, 16, 16) +static var chunks: Array = [] -@export var noise: FastNoiseLite +const CHUNK_SIZE := Vector3i(16, 16, 16) -var blocks: Array = [] +var position := Vector3i.ZERO +var mesh := MeshInstance3D.new() +@export var noise: FastNoiseLite +@export var blocks: Array = [] -func generate_chunk(row, column, depth): - #var material := StandardMaterial3D.new() - #material.albedo_texture = preload("res://new_atlas_texture.tres") - #material.vertex_color_use_as_albedo = true - var material := preload("res://new_shader_material.tres") - var st = SurfaceTool.new() - st.begin(Mesh.PRIMITIVE_TRIANGLES) - st.set_material(material) + +func generate_block_data(row: int, column: int, depth: int, empty: bool = false): + position = Vector3i(row, column, depth) blocks = [] - - for x in chunk_size.x: - #blocks[x] = [] + for x in CHUNK_SIZE.x: blocks.append([]) - for y in chunk_size.y: - #blocks[x][y] = [] + for y in CHUNK_SIZE.y: blocks[x].append([]) - for z in chunk_size.z: - var block_position = Vector3( - row*chunk_size.x + x, - column*chunk_size.y + y, - depth*chunk_size.z + z - #x, - #y, - #z - ) * 2 + for z in CHUNK_SIZE.z: + var block_position = Vector3i( + position.x * CHUNK_SIZE.x + x, + position.y * CHUNK_SIZE.y + y, + position.z * CHUNK_SIZE.z + z + )# * 2 var value = noise.get_noise_3d(block_position.x, block_position.y, block_position.z) * 100 var type = Block.Type.AIR @@ -47,17 +39,63 @@ func generate_chunk(row, column, depth): block.position = block_position block.type = type + if empty: + block.type = Block.Type.AIR + blocks[x][y].append(block) - + + +func generate_mesh() -> MeshInstance3D: + 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 = blocks[x][y][z] - var block_position = block.position + var block: Block = blocks[x][y][z] + + 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(position.x, position.y, position.z + 1): + block_front = chunks[position.x][position.y][position.z + 1].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(position.x, position.y, position.z - 1): + block_back = chunks[position.x][position.y][position.z - 1].blocks[x][y][CHUNK_SIZE.z - 1] + + 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(position.x - 1, position.y, position.z): + block_left = chunks[position.x - 1][position.y][position.z].blocks[CHUNK_SIZE.x - 1][y][z] + + 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(position.x + 1, position.y, position.z): + block_right = chunks[position.x + 1][position.y][position.z].blocks[0][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(position.x, position.y + 1, position.z): + block_top = chunks[position.x][position.y + 1][position.z].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(position.x, position.y - 1, position.z): + block_bottom = chunks[position.x][position.y - 1][position.z].blocks[x][CHUNK_SIZE.y - 1][z] if not block.type == Block.Type.AIR: - if block.type == Block.Type.GRASS and blocks[x].size() > y + 1 and not blocks[x][y + 1][z].type == Block.Type.AIR: - block.type = Block.Type.DIRT + 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() @@ -65,28 +103,78 @@ func generate_chunk(row, column, depth): st.set_uv(Vector2(0, 0)) - if (blocks[x][y].size() > z+1 and blocks[x][y][z + 1].type == Block.Type.AIR) or blocks[x][y].size() == z+1: + if not block_front or block_front.type == Block.Type.AIR: block.add_face(st, Block.Face.FRONT) - if (blocks.size() > x+1 and blocks[x + 1][y][z].type == Block.Type.AIR) or blocks.size() == x+1: + if not block_right or block_right.type == Block.Type.AIR: block.add_face(st, Block.Face.RIGHT) - if blocks[x][y].size() > z-1 and (blocks[x][y][z - 1].type == Block.Type.AIR or z == 0): + if not block_back or block_back.type == Block.Type.AIR: block.add_face(st, Block.Face.BACK) - if blocks.size() > x-1 and (blocks[x - 1][y][z].type == Block.Type.AIR or x == 0): + if not block_left or block_left.type == Block.Type.AIR: block.add_face(st, Block.Face.LEFT) - if (blocks[x].size() > y+1 and blocks[x][y + 1][z].type == Block.Type.AIR) or blocks[x].size() == y+1: + if not block_top or block_top.type == Block.Type.AIR: block.add_face(st, Block.Face.TOP) - if blocks[x].size() > y-1 and (blocks[x][y - 1][z].type == Block.Type.AIR or y == 0): + if not block_bottom or block_bottom.type == Block.Type.AIR: block.add_face(st, Block.Face.BOTTOM) #st.generate_normals() - var mesh = MeshInstance3D.new() + #mesh = MeshInstance3D.new() mesh.mesh = st.commit() - mesh.create_trimesh_collision() + + for child in mesh.get_children(): + child.queue_free() + mesh.create_trimesh_collision.call_deferred() + + mesh.set_meta("chunk", self) return mesh + + +func generate_chunk(row: int, column: int, depth: int): + if blocks.is_empty(): + generate_block_data(row, column, depth) + + generate_mesh() + + +func add_block(block_position: Vector3, block_type: Block.Type = Block.Type.GRASS) -> void: + var block = Block.new() + block.position = Vector3i( + position.x * CHUNK_SIZE.x + block_position.x, + position.y * CHUNK_SIZE.y + block_position.y, + position.z * CHUNK_SIZE.z + block_position.z + ) + block.type = block_type + + blocks[block_position.x][block_position.y][block_position.z] = 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 + generate_mesh.call_deferred() + + +static func chunk_exists(x: int, y: int, z: int): + return x >= 0 and chunks.size() - 1 >= x and y >= 0 and chunks[x].size() - 1 >= y and z >= 0 and chunks[x][y].size() - 1 >= z + +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 == CHUNK_SIZE.x - 1 or y == 0 or y == CHUNK_SIZE.y - 1 or z == 0 or z == CHUNK_SIZE.z - 1 + + +static func global_to_chunk(global_position: Vector3) -> Vector3i: + return floor(global_position / Vector3(CHUNK_SIZE)) + +static func global_to_chunk_block(global_position: Vector3) -> Vector3i: + return global_to_block(global_position) - CHUNK_SIZE * global_to_chunk(global_position) + +static func global_to_block(global_position: Vector3) -> Vector3i: + return floor(global_position) -- cgit v1.2.3