первые наработки по рендеру

This commit is contained in:
2026-05-23 00:08:32 +04:00
parent 1a56b22e38
commit bba203aa53
25 changed files with 1841 additions and 110 deletions
+93 -3
View File
@@ -520,6 +520,7 @@ static func _build_mesh_instance_from_payload(payload: Dictionary) -> MeshInstan
static func _build_tile_water_root(data: Dictionary, origin_offset: Vector3) -> Node3D:
var root := Node3D.new()
root.name = "Water"
var surfaces: Dictionary = {}
for chunk in data.get("chunks", []) as Array:
if chunk.is_empty():
@@ -527,13 +528,102 @@ static func _build_tile_water_root(data: Dictionary, origin_offset: Vector3) ->
for liquid in chunk.get("liquids", []) as Array:
if liquid.is_empty():
continue
var water_mesh := _build_liquid_mesh(chunk, liquid, origin_offset)
if water_mesh:
root.add_child(water_mesh)
var liquid_id := int(liquid.get("liquid_id", 0))
if not surfaces.has(liquid_id):
surfaces[liquid_id] = {
"verts": PackedVector3Array(),
"nrms": PackedVector3Array(),
"uvs": PackedVector2Array(),
"indices": PackedInt32Array(),
}
_append_liquid_geometry(chunk, liquid, origin_offset, surfaces[liquid_id])
for liquid_id in surfaces.keys():
var surface: Dictionary = surfaces[liquid_id]
var verts: PackedVector3Array = surface["verts"]
if verts.is_empty():
continue
var arrays := []
arrays.resize(Mesh.ARRAY_MAX)
arrays[Mesh.ARRAY_VERTEX] = verts
arrays[Mesh.ARRAY_NORMAL] = surface["nrms"]
arrays[Mesh.ARRAY_TEX_UV] = surface["uvs"]
arrays[Mesh.ARRAY_INDEX] = surface["indices"]
var mesh := ArrayMesh.new()
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
mesh.surface_set_material(0, _build_liquid_material(int(liquid_id)))
var mi := MeshInstance3D.new()
mi.mesh = mesh
mi.name = "Liquid_%d" % int(liquid_id)
root.add_child(mi)
return root if root.get_child_count() > 0 else null
static func _append_liquid_geometry(
chunk: Dictionary,
liquid: Dictionary,
origin_offset: Vector3,
surface: Dictionary) -> void:
var liquid_mask: PackedByteArray = liquid.get("mask", PackedByteArray())
var liquid_heights: PackedFloat32Array = liquid.get("heights", PackedFloat32Array())
if liquid_mask.size() < 8 * 8 or liquid_heights.size() < 9 * 9:
return
var chunk_origin: Vector3 = chunk.get("origin", Vector3.ZERO)
var tile_local_origin := chunk_origin - origin_offset
var verts: PackedVector3Array = surface["verts"]
var nrms: PackedVector3Array = surface["nrms"]
var uvs_arr: PackedVector2Array = surface["uvs"]
var indices: PackedInt32Array = surface["indices"]
for z in range(8):
for x in range(8):
if liquid_mask[z * 8 + x] == 0:
continue
var base := verts.size()
var x0 := tile_local_origin.x + x * UNIT_SIZE
var x1 := tile_local_origin.x + (x + 1) * UNIT_SIZE
var z0 := tile_local_origin.z + z * UNIT_SIZE
var z1 := tile_local_origin.z + (z + 1) * UNIT_SIZE
var y00 := liquid_heights[z * 9 + x] - origin_offset.y
var y10 := liquid_heights[z * 9 + x + 1] - origin_offset.y
var y01 := liquid_heights[(z + 1) * 9 + x] - origin_offset.y
var y11 := liquid_heights[(z + 1) * 9 + x + 1] - origin_offset.y
verts.append(Vector3(x0, y00, z0))
verts.append(Vector3(x0, y01, z1))
verts.append(Vector3(x1, y11, z1))
verts.append(Vector3(x1, y10, z0))
nrms.append(Vector3.UP)
nrms.append(Vector3.UP)
nrms.append(Vector3.UP)
nrms.append(Vector3.UP)
uvs_arr.append(Vector2(float(x) / 8.0, float(z) / 8.0))
uvs_arr.append(Vector2(float(x) / 8.0, float(z + 1) / 8.0))
uvs_arr.append(Vector2(float(x + 1) / 8.0, float(z + 1) / 8.0))
uvs_arr.append(Vector2(float(x + 1) / 8.0, float(z) / 8.0))
indices.append(base)
indices.append(base + 1)
indices.append(base + 2)
indices.append(base)
indices.append(base + 2)
indices.append(base + 3)
surface["verts"] = verts
surface["nrms"] = nrms
surface["uvs"] = uvs_arr
surface["indices"] = indices
static func _build_liquid_mesh(
chunk: Dictionary,
liquid: Dictionary,