|
@@ -9,14 +9,17 @@ const TEXTURE_SHEET_WIDTH = 8
|
|
|
|
|
|
const CHUNK_LAST_INDEX = CHUNK_SIZE - 1
|
|
|
const TEXTURE_TILE_SIZE = 1.0 / TEXTURE_SHEET_WIDTH
|
|
|
+const DIRECTIONS: Array[Vector3i] = [Vector3i.LEFT, Vector3i.RIGHT, Vector3i.DOWN, Vector3i.UP, Vector3i.FORWARD, Vector3i.BACK]
|
|
|
|
|
|
var data := {}
|
|
|
var chunk_position := Vector3i()
|
|
|
+var is_initial_mesh_generated: bool = false
|
|
|
|
|
|
var _thread: Thread
|
|
|
|
|
|
@onready var voxel_world := get_parent()
|
|
|
|
|
|
+
|
|
|
func _ready() -> void:
|
|
|
transform.origin = Vector3(chunk_position * CHUNK_SIZE)
|
|
|
name = str(chunk_position)
|
|
@@ -27,7 +30,14 @@ func _ready() -> void:
|
|
|
|
|
|
# We can only add colliders in the main thread due to physics limitations.
|
|
|
_generate_chunk_collider()
|
|
|
- # However, we can use a thread for mesh generation.
|
|
|
+
|
|
|
+
|
|
|
+func try_initial_generate_mesh(all_chunks: Dictionary[Vector3i, Chunk]) -> void:
|
|
|
+ # We can use a thread for mesh generation.
|
|
|
+ for dir in DIRECTIONS:
|
|
|
+ if not all_chunks.has(chunk_position + dir):
|
|
|
+ return
|
|
|
+ is_initial_mesh_generated = true
|
|
|
_thread = Thread.new()
|
|
|
_thread.start(_generate_chunk_mesh)
|
|
|
|
|
@@ -73,7 +83,6 @@ func _generate_chunk_mesh() -> void:
|
|
|
_draw_block_mesh(surface_tool, block_position, block_id)
|
|
|
|
|
|
# Create the chunk's mesh from the SurfaceTool data.
|
|
|
- surface_tool.generate_normals()
|
|
|
surface_tool.generate_tangents()
|
|
|
surface_tool.index()
|
|
|
var array_mesh := surface_tool.commit()
|
|
@@ -91,10 +100,10 @@ func _draw_block_mesh(surface_tool: SurfaceTool, block_sub_position: Vector3i, b
|
|
|
|
|
|
# Bush blocks get drawn in their own special way.
|
|
|
if block_id == 27 or block_id == 28:
|
|
|
- _draw_block_face(surface_tool, [verts[2], verts[0], verts[7], verts[5]], uvs)
|
|
|
- _draw_block_face(surface_tool, [verts[7], verts[5], verts[2], verts[0]], uvs)
|
|
|
- _draw_block_face(surface_tool, [verts[3], verts[1], verts[6], verts[4]], uvs)
|
|
|
- _draw_block_face(surface_tool, [verts[6], verts[4], verts[3], verts[1]], uvs)
|
|
|
+ _draw_block_face(surface_tool, [verts[2], verts[0], verts[7], verts[5]], uvs, Vector3(-1, 0, 1).normalized())
|
|
|
+ _draw_block_face(surface_tool, [verts[7], verts[5], verts[2], verts[0]], uvs, Vector3(1, 0, -1).normalized())
|
|
|
+ _draw_block_face(surface_tool, [verts[3], verts[1], verts[6], verts[4]], uvs, Vector3(1, 0, 1).normalized())
|
|
|
+ _draw_block_face(surface_tool, [verts[6], verts[4], verts[3], verts[1]], uvs, Vector3(-1, 0, -1).normalized())
|
|
|
return
|
|
|
|
|
|
# Allow some blocks to have different top/bottom textures.
|
|
@@ -112,62 +121,76 @@ func _draw_block_mesh(surface_tool: SurfaceTool, block_sub_position: Vector3i, b
|
|
|
bottom_uvs = top_uvs
|
|
|
|
|
|
# Main rendering code for normal blocks.
|
|
|
- var other_block_position := block_sub_position + Vector3i.LEFT
|
|
|
+ #var other_block_position := block_sub_position
|
|
|
var other_block_id := 0
|
|
|
- if other_block_position.x == -1:
|
|
|
- other_block_id = voxel_world.get_block_global_position(other_block_position + chunk_position * CHUNK_SIZE)
|
|
|
- elif data.has(other_block_position):
|
|
|
- other_block_id = data[other_block_position]
|
|
|
+ if block_sub_position.x == 0:
|
|
|
+ var other_sub_pos: Vector3i = Vector3i(15, block_sub_position.y, block_sub_position.z)
|
|
|
+ other_block_id = voxel_world.get_block_in_chunk(chunk_position + Vector3i.LEFT, other_sub_pos)
|
|
|
+ else:
|
|
|
+ var other_block_sub_pos: Vector3i = block_sub_position + Vector3i.LEFT
|
|
|
+ if data.has(other_block_sub_pos):
|
|
|
+ other_block_id = data[other_block_sub_pos]
|
|
|
if block_id != other_block_id and Chunk.is_block_transparent(other_block_id):
|
|
|
- _draw_block_face(surface_tool, [verts[2], verts[0], verts[3], verts[1]], uvs)
|
|
|
+ _draw_block_face(surface_tool, [verts[2], verts[0], verts[3], verts[1]], uvs, Vector3.LEFT)
|
|
|
|
|
|
- other_block_position = block_sub_position + Vector3i.RIGHT
|
|
|
other_block_id = 0
|
|
|
- if other_block_position.x == CHUNK_SIZE:
|
|
|
- other_block_id = voxel_world.get_block_global_position(other_block_position + chunk_position * CHUNK_SIZE)
|
|
|
- elif data.has(other_block_position):
|
|
|
- other_block_id = data[other_block_position]
|
|
|
+ if block_sub_position.x == CHUNK_SIZE - 1:
|
|
|
+ var other_sub_pos: Vector3i = Vector3i(0, block_sub_position.y, block_sub_position.z)
|
|
|
+ other_block_id = voxel_world.get_block_in_chunk(chunk_position + Vector3i.RIGHT, other_sub_pos)
|
|
|
+ else:
|
|
|
+ var other_block_sub_pos: Vector3i = block_sub_position + Vector3i.RIGHT
|
|
|
+ if data.has(other_block_sub_pos):
|
|
|
+ other_block_id = data[other_block_sub_pos]
|
|
|
if block_id != other_block_id and Chunk.is_block_transparent(other_block_id):
|
|
|
- _draw_block_face(surface_tool, [verts[7], verts[5], verts[6], verts[4]], uvs)
|
|
|
+ _draw_block_face(surface_tool, [verts[7], verts[5], verts[6], verts[4]], uvs, Vector3.RIGHT)
|
|
|
|
|
|
- other_block_position = block_sub_position + Vector3i.FORWARD
|
|
|
other_block_id = 0
|
|
|
- if other_block_position.z == -1:
|
|
|
- other_block_id = voxel_world.get_block_global_position(other_block_position + chunk_position * CHUNK_SIZE)
|
|
|
- elif data.has(other_block_position):
|
|
|
- other_block_id = data[other_block_position]
|
|
|
+ if block_sub_position.z == 0:
|
|
|
+ var other_sub_pos: Vector3i = Vector3i(block_sub_position.x, block_sub_position.y, CHUNK_SIZE - 1)
|
|
|
+ other_block_id = voxel_world.get_block_in_chunk(chunk_position + Vector3i.FORWARD, other_sub_pos)
|
|
|
+ else:
|
|
|
+ var other_block_sub_pos: Vector3i = block_sub_position + Vector3i.FORWARD
|
|
|
+ if data.has(other_block_sub_pos):
|
|
|
+ other_block_id = data[other_block_sub_pos]
|
|
|
if block_id != other_block_id and Chunk.is_block_transparent(other_block_id):
|
|
|
- _draw_block_face(surface_tool, [verts[6], verts[4], verts[2], verts[0]], uvs)
|
|
|
+ _draw_block_face(surface_tool, [verts[6], verts[4], verts[2], verts[0]], uvs, Vector3.FORWARD)
|
|
|
|
|
|
- other_block_position = block_sub_position + Vector3i.BACK
|
|
|
other_block_id = 0
|
|
|
- if other_block_position.z == CHUNK_SIZE:
|
|
|
- other_block_id = voxel_world.get_block_global_position(other_block_position + chunk_position * CHUNK_SIZE)
|
|
|
- elif data.has(other_block_position):
|
|
|
- other_block_id = data[other_block_position]
|
|
|
+ if block_sub_position.z == CHUNK_SIZE - 1:
|
|
|
+ var other_sub_pos: Vector3i = Vector3i(block_sub_position.x, block_sub_position.y, 0)
|
|
|
+ other_block_id = voxel_world.get_block_in_chunk(chunk_position + Vector3i.BACK, other_sub_pos)
|
|
|
+ else:
|
|
|
+ var other_block_sub_pos: Vector3i = block_sub_position + Vector3i.BACK
|
|
|
+ if data.has(other_block_sub_pos):
|
|
|
+ other_block_id = data[other_block_sub_pos]
|
|
|
if block_id != other_block_id and Chunk.is_block_transparent(other_block_id):
|
|
|
- _draw_block_face(surface_tool, [verts[3], verts[1], verts[7], verts[5]], uvs)
|
|
|
+ _draw_block_face(surface_tool, [verts[3], verts[1], verts[7], verts[5]], uvs, Vector3.BACK)
|
|
|
|
|
|
- other_block_position = block_sub_position + Vector3i.DOWN
|
|
|
other_block_id = 0
|
|
|
- if other_block_position.y == -1:
|
|
|
- other_block_id = voxel_world.get_block_global_position(other_block_position + chunk_position * CHUNK_SIZE)
|
|
|
- elif data.has(other_block_position):
|
|
|
- other_block_id = data[other_block_position]
|
|
|
+ if block_sub_position.y == 0:
|
|
|
+ var other_sub_pos: Vector3i = Vector3i(block_sub_position.x, CHUNK_SIZE - 1, block_sub_position.z)
|
|
|
+ other_block_id = voxel_world.get_block_in_chunk(chunk_position + Vector3i.DOWN, other_sub_pos)
|
|
|
+ else:
|
|
|
+ var other_block_sub_pos: Vector3i = block_sub_position + Vector3i.DOWN
|
|
|
+ if data.has(other_block_sub_pos):
|
|
|
+ other_block_id = data[other_block_sub_pos]
|
|
|
if block_id != other_block_id and Chunk.is_block_transparent(other_block_id):
|
|
|
- _draw_block_face(surface_tool, [verts[4], verts[5], verts[0], verts[1]], bottom_uvs)
|
|
|
+ _draw_block_face(surface_tool, [verts[4], verts[5], verts[0], verts[1]], bottom_uvs, Vector3.DOWN)
|
|
|
|
|
|
- other_block_position = block_sub_position + Vector3i.UP
|
|
|
other_block_id = 0
|
|
|
- if other_block_position.y == CHUNK_SIZE:
|
|
|
- other_block_id = voxel_world.get_block_global_position(other_block_position + chunk_position * CHUNK_SIZE)
|
|
|
- elif data.has(other_block_position):
|
|
|
- other_block_id = data[other_block_position]
|
|
|
+ if block_sub_position.y == CHUNK_SIZE - 1:
|
|
|
+ var other_sub_pos: Vector3i = Vector3i(block_sub_position.x, 0, block_sub_position.z)
|
|
|
+ other_block_id = voxel_world.get_block_in_chunk(chunk_position + Vector3i.UP, other_sub_pos)
|
|
|
+ else:
|
|
|
+ var other_block_sub_pos: Vector3i = block_sub_position + Vector3i.UP
|
|
|
+ if data.has(other_block_sub_pos):
|
|
|
+ other_block_id = data[other_block_sub_pos]
|
|
|
if block_id != other_block_id and Chunk.is_block_transparent(other_block_id):
|
|
|
- _draw_block_face(surface_tool, [verts[2], verts[3], verts[6], verts[7]], top_uvs)
|
|
|
+ _draw_block_face(surface_tool, [verts[2], verts[3], verts[6], verts[7]], top_uvs, Vector3.UP)
|
|
|
|
|
|
|
|
|
-func _draw_block_face(surface_tool: SurfaceTool, verts: Array[Vector3], uvs: Array[Vector2]) -> void:
|
|
|
+func _draw_block_face(surface_tool: SurfaceTool, verts: Array[Vector3], uvs: Array[Vector2], normal: Vector3) -> void:
|
|
|
+ surface_tool.set_normal(normal)
|
|
|
surface_tool.set_uv(uvs[1]); surface_tool.add_vertex(verts[1])
|
|
|
surface_tool.set_uv(uvs[2]); surface_tool.add_vertex(verts[2])
|
|
|
surface_tool.set_uv(uvs[3]); surface_tool.add_vertex(verts[3])
|