summaryrefslogtreecommitdiff
path: root/chunk.gd
diff options
context:
space:
mode:
authorDaniel Weipert <git@mail.dweipert.de>2025-01-11 12:31:00 +0100
committerDaniel Weipert <git@mail.dweipert.de>2025-01-11 12:31:00 +0100
commitf448ca4259d7f76fc58bc3b5c12ea8d04ab49a87 (patch)
tree679e0b6186253a9becd8fbe5ade5bbb679ba06a0 /chunk.gd
parentb1d9bfe7e80b4d95acd26d0ab6a1ce34ad18d91c (diff)
next commit
Diffstat (limited to 'chunk.gd')
-rw-r--r--chunk.gd164
1 files changed, 126 insertions, 38 deletions
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)