summaryrefslogtreecommitdiff
path: root/chunk.gd
diff options
context:
space:
mode:
Diffstat (limited to 'chunk.gd')
-rw-r--r--chunk.gd353
1 files changed, 282 insertions, 71 deletions
diff --git a/chunk.gd b/chunk.gd
index 8dcd416..2003c4e 100644
--- a/chunk.gd
+++ b/chunk.gd
@@ -1,90 +1,301 @@
class_name Chunk
-extends Node
+extends Node3D
-var chunk_size := Vector3(16, 16, 16)
+var grid_position := Vector3i.ZERO
+var mesh: ArrayMesh = ArrayMesh.new()
@export var noise: FastNoiseLite
+@export var blocks: Array = []
-var blocks: Array[Block] = []
-
-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):
+ grid_position = Vector3i(row, column, depth)
- var blocks = []
+ blocks = []
+ blocks.resize(Global.CHUNK_SIZE.x * Global.CHUNK_SIZE.y * Global.CHUNK_SIZE.z)
- for x in chunk_size.x:
- #blocks[x] = []
- blocks.append([])
- for y in chunk_size.y:
- #blocks[x][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
- var value = noise.get_noise_3d(block_position.x, block_position.y, block_position.z) * 100
+ for x in Global.CHUNK_SIZE.x:
+ 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 > -15:
- type = Block.Type.GRASS
- elif value > -20:
- type = Block.Type.STONE
+ 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
- blocks[x][y].append(block)
-
- 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
+ if empty or Global.MAX_HEIGHT < block.global_position.y:
+ block.type = Block.Type.AIR
- 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
-
- var rng = RandomNumberGenerator.new()
- rng.seed = randi()
- st.set_color(Color(rng.randf(), rng.randf(), rng.randf()))
-
- 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:
- block.add_face(st, Block.Face.FRONT, block)
-
- if (blocks.size() > x+1 and blocks[x + 1][y][z].type == Block.Type.AIR) or blocks.size() == x+1:
- 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):
- 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):
- 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:
- 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):
- block.add_face(st, Block.Face.BOTTOM)
+ var index := x + Global.CHUNK_SIZE.x * y + Global.CHUNK_SIZE.x * Global.CHUNK_SIZE.y * z
+ blocks[index] = block
+
+
+func generate_mesh():
+ var material := preload("res://new_shader_material.tres")
+ var st = SurfaceTool.new()
+ st.begin(Mesh.PRIMITIVE_TRIANGLES)
+ st.set_material(material)
+
+ 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()
- var mesh = MeshInstance3D.new()
- mesh.mesh = st.commit()
- mesh.create_trimesh_collision()
+ mesh = st.commit()
+
+
+func update_mesh() -> void:
+ $MeshInstance3D.mesh = mesh
+
+ var shape := ConcavePolygonShape3D.new()
+ var faces := mesh.get_faces()
+ if faces.size() > 0:
+ shape.set_faces(mesh.get_faces())
+ $StaticBody3D/CollisionShape3D.shape = shape
+
+
+func add_to(node: Node) -> void:
+ name = "Chunk_%s_%s_%s" % [grid_position.x, grid_position.y, grid_position.z]
+ node.add_child(self, true)
+ update_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(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
+ 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
+ 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):
+ return Global.chunks.has(chunk_position)
+ #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(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):
+ return bordering_chunks
+
+ if block_position.z == 0:
+ bordering_chunks.append(grid_position + Vector3i(0, 0, -1))
+ elif block_position.z == Global.CHUNK_SIZE.z - 1:
+ bordering_chunks.append(grid_position + Vector3i(0, 0, 1))
+
+ if block_position.x == 0:
+ bordering_chunks.append(grid_position + Vector3i(-1, 0, 0))
+ elif block_position.x == Global.CHUNK_SIZE.x - 1:
+ bordering_chunks.append(grid_position + Vector3i(1, 0, 0))
+
+ if block_position.y == 0:
+ bordering_chunks.append(grid_position + Vector3i(0, -1, 0))
+ elif block_position.y == Global.CHUNK_SIZE.y - 1:
+ bordering_chunks.append(grid_position + Vector3i(0, 1, 0))
+
+ return bordering_chunks
+
+func get_neighboring_blocks(_block_position: Vector3i) -> Array[Vector3i]:
+ return []
+
+
+@warning_ignore("shadowed_variable_base_class")
+static func global_to_chunk(global_position: Vector3, normal: Vector3) -> Vector3i:
+ return floor((global_position - normal * (Block.BLOCK_SIZE * 0.5)) / Vector3(Global.CHUNK_SIZE))
+
+@warning_ignore("shadowed_variable_base_class")
+static func global_to_chunk_block(global_position: Vector3, normal: Vector3) -> Vector3i:
+ return global_to_block(global_position, normal) - Global.CHUNK_SIZE * global_to_chunk(global_position, normal)
+
+@warning_ignore("shadowed_variable_base_class")
+static func global_to_block(global_position: Vector3, normal: Vector3) -> Vector3i:
+ return floor(global_position - normal * (Block.BLOCK_SIZE * 0.5))