GodotShade/chunk.gd
Guillaume Vern a342f96089 init project
2025-10-07 16:20:44 +02:00

176 lines
5.0 KiB
GDScript

@tool
extends MeshInstance3D
@export var backface_culling: bool
@export var tex_div = Vector2(1.0/4.0, 1.0/3.0)
var chunk_size: int
var array_mesh = ArrayMesh.new()
var vertices = PackedVector3Array()
var indices = PackedInt32Array()
var uvs = PackedVector2Array()
var face_count: int
var blocks = []
var first_load = true
const AXIS := [
Vector3i(1, 0, 0),
Vector3i(0, 1, 0),
Vector3i(0, 0, 1),
]
func _ready() -> void:
pass
func _process(delta: float) -> void:
pass
func init_blocks(_chunk_size: int, pos: Vector3i):
chunk_size = _chunk_size
blocks.resize(chunk_size)
for x in range(chunk_size):
blocks[x] = []
for y in range(chunk_size):
blocks[x].append([])
for z in range(chunk_size):
var block_type = get_parent().GetBlock(Vector3i(pos.x + x, pos.y + y, pos.z + z), first_load)
blocks[x][y].append(block_type)
first_load = false
func SetBlockAtPosition(pos: Vector3i, block_type: Block.BlockType):
blocks[pos.x][pos.y][pos.z] = block_type
func GetBlockAtPosition(pos: Vector3i):
return blocks[pos.x][pos.y][pos.z]
func generate_chunk():
array_mesh = ArrayMesh.new()
vertices = PackedVector3Array()
indices = PackedInt32Array()
uvs = PackedVector2Array()
face_count = 0
for x in range(chunk_size):
for y in range(chunk_size):
for z in range(chunk_size):
if blocks[x][y][z] == Block.BlockType.Air:
pass
else:
generate_cube_mesh(Vector3i(x, y, z))
if not vertices.size() == 0:
var array = []
array.resize(Mesh.ARRAY_MAX)
array[Mesh.ARRAY_VERTEX] = vertices
array[Mesh.ARRAY_INDEX] = indices
array[Mesh.ARRAY_TEX_UV] = uvs
array_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, array)
var trimesh_collision = array_mesh.create_trimesh_shape()
var collisionShape3D: CollisionShape3D = find_child("StaticBody3D").find_child("CollisionShape3D")
collisionShape3D.set_shape(trimesh_collision)
mesh = array_mesh
func add_uvs(x, y):
uvs.append(Vector2(tex_div.x * x, tex_div.y * y))
uvs.append(Vector2(tex_div.x * x + tex_div.x, tex_div.y * y))
uvs.append(Vector2(tex_div.x * x + tex_div.x, tex_div.y * y + tex_div.y))
uvs.append(Vector2(tex_div.x * x, tex_div.y * y + tex_div.y))
func add_triangles():
indices.append(face_count * 4 + 0)
indices.append(face_count * 4 + 1)
indices.append(face_count * 4 + 2)
indices.append(face_count * 4 + 0)
indices.append(face_count * 4 + 2)
indices.append(face_count * 4 + 3)
face_count += 1
#func generate_smooth_mesh(pos: Vector3i):
func generate_cube_mesh(pos: Vector3):
var is_top_block = false
# face +y
if is_block_air(pos + Vector3(0, 1, 0)) || not backface_culling:
vertices.append(pos + Vector3(-0.5, 0.5, -0.5))
vertices.append(pos + Vector3(0.5, 0.5, -0.5))
vertices.append(pos + Vector3(0.5, 0.5, 0.5))
vertices.append(pos + Vector3(-0.5, 0.5, 0.5))
add_triangles()
add_uvs(1, 0)
is_top_block = true
# face +x
if is_block_air(pos + Vector3(1, 0, 0)) || not backface_culling:
vertices.append(pos + Vector3(0.5, 0.5, 0.5))
vertices.append(pos + Vector3(0.5, 0.5, -0.5))
vertices.append(pos + Vector3(0.5, -0.5, -0.5))
vertices.append(pos + Vector3(0.5, -0.5, 0.5))
add_triangles()
if is_top_block:
add_uvs(1, 1)
else:
add_uvs(1, 2)
# face +z
if is_block_air(pos + Vector3(0, 0, 1)) || not backface_culling:
vertices.append(pos + Vector3(-0.5, 0.5, 0.5))
vertices.append(pos + Vector3(0.5, 0.5, 0.5))
vertices.append(pos + Vector3(0.5, -0.5, 0.5))
vertices.append(pos + Vector3(-0.5, -0.5, 0.5))
add_triangles()
if is_top_block:
add_uvs(0, 1)
else:
add_uvs(1, 2)
# face -y
if is_block_air(pos + Vector3(0, -1, 0)) || not backface_culling:
vertices.append(pos + Vector3(0.5, -0.5, 0.5))
vertices.append(pos + Vector3(0.5, -0.5, -0.5))
vertices.append(pos + Vector3(-0.5, -0.5, -0.5))
vertices.append(pos + Vector3(-0.5, -0.5, 0.5))
add_triangles()
add_uvs(1, 2)
# face -x
if is_block_air(pos + Vector3(-1, 0, 0)) || not backface_culling:
vertices.append(pos + Vector3(-0.5, 0.5, -0.5))
vertices.append(pos + Vector3(-0.5, 0.5, 0.5))
vertices.append(pos + Vector3(-0.5, -0.5, 0.5))
vertices.append(pos + Vector3(-0.5, -0.5, -0.5))
add_triangles()
if is_top_block:
add_uvs(2, 1)
else:
add_uvs(1, 2)
# face -z
if is_block_air(pos + Vector3(0, 0, -1)) || not backface_culling:
vertices.append(pos + Vector3(0.5, 0.5, -0.5))
vertices.append(pos + Vector3(-0.5, 0.5, -0.5))
vertices.append(pos + Vector3(-0.5, -0.5, -0.5))
vertices.append(pos + Vector3(0.5, -0.5, -0.5))
add_triangles()
if is_top_block:
add_uvs(0, 1)
else:
add_uvs(1, 2)
func is_block_air(pos: Vector3):
# outside of chunk
if pos.x < 0 or pos.y < 0 or pos.z < 0:
var block = get_parent().GetBlock(pos + position, first_load)
return block == Block.BlockType.Air
elif pos.x >= chunk_size or pos.y >= chunk_size or pos.z >= chunk_size:
var block = get_parent().GetBlock(pos + position, first_load)
return block == Block.BlockType.Air
else:
return blocks[pos.x][pos.y][pos.z] == Block.BlockType.Air