mirror of
https://github.com/Relintai/broken_seals.git
synced 2024-12-25 01:17:10 +01:00
476 lines
14 KiB
GDScript3
476 lines
14 KiB
GDScript3
|
extends VoxelMesherTransvoxel
|
||
|
class_name TVVoxelMesher
|
||
|
|
||
|
# Copyright Péter Magyar relintai@gmail.com
|
||
|
# MIT License, might be merged into the Voxelman engine module
|
||
|
|
||
|
var transition_sides : int = 0
|
||
|
|
||
|
const VOXEL_CHUNK_SIDE_FRONT : int = 1 << 0
|
||
|
const VOXEL_CHUNK_SIDE_BACK : int = 1 << 1
|
||
|
const VOXEL_CHUNK_SIDE_LEFT : int = 1 << 2
|
||
|
const VOXEL_CHUNK_SIDE_RIGHT : int = 1 << 3
|
||
|
const VOXEL_CHUNK_SIDE_TOP : int = 1 << 4
|
||
|
const VOXEL_CHUNK_SIDE_BOTTOM : int = 1 << 5
|
||
|
|
||
|
enum {
|
||
|
CHUNK_INDEX_UP = 0,
|
||
|
CHUNK_INDEX_DOWN = 1,
|
||
|
CHUNK_INDEX_LEFT = 2,
|
||
|
CHUNK_INDEX_RIGHT = 3,
|
||
|
CHUNK_INDEX_FRONT = 4,
|
||
|
CHUNK_INDEX_BACK = 5,
|
||
|
}
|
||
|
|
||
|
var lod_data : Array = [
|
||
|
1, #CHUNK_INDEX_UP
|
||
|
1, #CHUNK_INDEX_DOWN
|
||
|
1, #CHUNK_INDEX_LEFT
|
||
|
1, #CHUNK_INDEX_RIGHT
|
||
|
1, #CHUNK_INDEX_FRONT
|
||
|
1 #CHUNK_INDEX_BACK
|
||
|
]
|
||
|
|
||
|
func get_case_code(buffer : VoxelChunk, x : int, y : int, z : int, size : int = 1) -> int:
|
||
|
var case_code : int = 0
|
||
|
|
||
|
if (buffer.get_voxel(x, y, z, VoxelChunk.DEFAULT_CHANNEL_TYPE) != 0):
|
||
|
case_code = case_code | VOXEL_ENTRY_MASK_000
|
||
|
|
||
|
if (buffer.get_voxel(x, y + size, z, VoxelChunk.DEFAULT_CHANNEL_TYPE) != 0):
|
||
|
case_code = case_code | VOXEL_ENTRY_MASK_010
|
||
|
|
||
|
if (buffer.get_voxel(x, y, z + size, VoxelChunk.DEFAULT_CHANNEL_TYPE) != 0):
|
||
|
case_code = case_code | VOXEL_ENTRY_MASK_001
|
||
|
|
||
|
if (buffer.get_voxel(x, y + size, z + size, VoxelChunk.DEFAULT_CHANNEL_TYPE) != 0):
|
||
|
case_code = case_code | VOXEL_ENTRY_MASK_011
|
||
|
|
||
|
if (buffer.get_voxel(x + size, y, z, VoxelChunk.DEFAULT_CHANNEL_TYPE) != 0):
|
||
|
case_code = case_code | VOXEL_ENTRY_MASK_100
|
||
|
|
||
|
if (buffer.get_voxel(x + size, y + size, z, VoxelChunk.DEFAULT_CHANNEL_TYPE) != 0):
|
||
|
case_code = case_code | VOXEL_ENTRY_MASK_110
|
||
|
|
||
|
if (buffer.get_voxel(x + size, y, z + size, VoxelChunk.DEFAULT_CHANNEL_TYPE) != 0):
|
||
|
case_code = case_code | VOXEL_ENTRY_MASK_101
|
||
|
|
||
|
if (buffer.get_voxel(x + size, y + size, z + size, VoxelChunk.DEFAULT_CHANNEL_TYPE) != 0):
|
||
|
case_code = case_code | VOXEL_ENTRY_MASK_111
|
||
|
|
||
|
return case_code
|
||
|
|
||
|
func get_voxel_type(buffer : VoxelChunk, x : int, y : int, z : int, size : int = 1) -> int:
|
||
|
var type : int = 0
|
||
|
|
||
|
type = buffer.get_voxel(x, y + size, z, VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
if type != 0:
|
||
|
return type
|
||
|
|
||
|
type = buffer.get_voxel(x, y, z + size, VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
if type != 0:
|
||
|
return type
|
||
|
|
||
|
type = buffer.get_voxel(x, y + size, z + size, VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
if type != 0:
|
||
|
return type
|
||
|
|
||
|
type = buffer.get_voxel(x + size, y + size, z + size, VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
if type != 0:
|
||
|
return type
|
||
|
|
||
|
type = buffer.get_voxel(x, y, z, VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
if type != 0:
|
||
|
return type
|
||
|
|
||
|
type = buffer.get_voxel(x + size, y + size, z, VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
if type != 0:
|
||
|
return type
|
||
|
|
||
|
type = buffer.get_voxel(x + size, y, z, VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
if type != 0:
|
||
|
return type
|
||
|
|
||
|
type = buffer.get_voxel(x + size, y, z + size, VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
return type
|
||
|
|
||
|
func _add_chunk(buffer : VoxelChunk) -> void:
|
||
|
var b : bool = true
|
||
|
|
||
|
for l in lod_data:
|
||
|
if l != 1:
|
||
|
b = false
|
||
|
break
|
||
|
|
||
|
if lod_size == 1 and b:
|
||
|
add_buffer_normal(buffer)
|
||
|
else:
|
||
|
add_buffer_lod(buffer)
|
||
|
|
||
|
func add_buffer_normal(buffer : VoxelChunk) -> void:
|
||
|
buffer.generate_ao()
|
||
|
|
||
|
var x_size : int = buffer.get_size_x()
|
||
|
var y_size : int = buffer.get_size_y()
|
||
|
var z_size : int = buffer.get_size_z()
|
||
|
|
||
|
for y in range(0, y_size, lod_size):
|
||
|
for z in range(0, z_size, lod_size):
|
||
|
for x in range(0, x_size, lod_size):
|
||
|
|
||
|
var case_code : int = get_case_code(buffer, x, y, z, lod_size)
|
||
|
|
||
|
if case_code == 0 or case_code == 255:
|
||
|
continue
|
||
|
|
||
|
var regular_cell_class : int = get_regular_cell_class(case_code)
|
||
|
|
||
|
var cell_data : TransvoxelCellData = get_regular_cell_data(regular_cell_class)
|
||
|
|
||
|
var index_count : int = cell_data.get_triangle_count() * 3
|
||
|
var vertex_count : int = cell_data.get_vertex_count()
|
||
|
|
||
|
for i in range(index_count):
|
||
|
var ind : int = get_vertex_count() + cell_data.get_vertex_index(i)
|
||
|
add_indices(ind)
|
||
|
|
||
|
var temp_verts : Array = Array()
|
||
|
|
||
|
var type_id : int = get_voxel_type(buffer, x, y, z, lod_size)
|
||
|
|
||
|
var surface : VoxelSurface = library.get_voxel_surface(type_id)
|
||
|
|
||
|
for i in range(vertex_count):
|
||
|
var fv : int = get_regular_vertex_data_first_vertex(case_code, i)
|
||
|
var sv : int = get_regular_vertex_data_second_vertex(case_code, i)
|
||
|
|
||
|
var offs0 : Vector3 = corner_id_to_vertex(fv) * lod_size
|
||
|
var offs1 : Vector3 = corner_id_to_vertex(sv) * lod_size
|
||
|
|
||
|
var type0 : int = buffer.get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
# var type1 : int = buffer.get_voxel(int(x + offs1.x), int(y + offs1.y), int(z + offs1.z), VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
var fill : int = 0
|
||
|
|
||
|
var vert_pos : Vector3
|
||
|
var vert_dir : Vector3
|
||
|
|
||
|
if type0 == 0:
|
||
|
fill = buffer.get_voxel(int(x + offs1.x), int(y + offs1.y), int(z + offs1.z), VoxelChunk.DEFAULT_CHANNEL_ISOLEVEL)
|
||
|
|
||
|
vert_pos = get_regular_vertex_second_position(case_code, i)
|
||
|
vert_dir = get_regular_vertex_first_position(case_code, i)
|
||
|
else:
|
||
|
fill = buffer.get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunk.DEFAULT_CHANNEL_ISOLEVEL)
|
||
|
|
||
|
vert_pos = get_regular_vertex_first_position(case_code, i)
|
||
|
vert_dir = get_regular_vertex_second_position(case_code, i)
|
||
|
|
||
|
vert_dir = vert_dir - vert_pos
|
||
|
|
||
|
vert_pos += vert_dir * (fill / 256.0)
|
||
|
|
||
|
temp_verts.append(vert_pos)
|
||
|
|
||
|
# if regular_uv_entries.size() > uvs[i]:
|
||
|
# add_uv(Vector2(regular_uv_entries[uvs[i]][0], regular_uv_entries[uvs[i]][1]));
|
||
|
|
||
|
# add_uv(Vector2(0, 0))
|
||
|
|
||
|
var temp_normals : Array = Array()
|
||
|
|
||
|
#warning-ignore:unused_variable
|
||
|
for i in range(len(temp_verts)):
|
||
|
temp_normals.append(Vector3())
|
||
|
|
||
|
#generate normals
|
||
|
for i in range(0, index_count, 3):
|
||
|
var indices : Array = [
|
||
|
cell_data.get_vertex_index(i),
|
||
|
cell_data.get_vertex_index(i + 1),
|
||
|
cell_data.get_vertex_index(i + 2)
|
||
|
]
|
||
|
|
||
|
var vertices : Array = [
|
||
|
temp_verts[indices[0]],
|
||
|
temp_verts[indices[1]],
|
||
|
temp_verts[indices[2]],
|
||
|
]
|
||
|
|
||
|
temp_normals[indices[0]] += (vertices[1] - vertices[0]).cross(vertices[0] - vertices[2])
|
||
|
temp_normals[indices[1]] += (vertices[2] - vertices[1]).cross(vertices[1] - vertices[0])
|
||
|
temp_normals[indices[2]] += (vertices[2] - vertices[1]).cross(vertices[2] - vertices[0])
|
||
|
|
||
|
for i in range(len(temp_verts)):
|
||
|
temp_normals[i] = (temp_normals[i] as Vector3).normalized()
|
||
|
|
||
|
for cvi in range(len(temp_verts)):
|
||
|
var vertex : Vector3 = temp_verts[cvi]
|
||
|
var normal : Vector3 = temp_normals[cvi]
|
||
|
|
||
|
var s : Vector3 = Vector3()
|
||
|
var t : Vector3 = Vector3()
|
||
|
t.x = vertex.z
|
||
|
t.y = vertex.z
|
||
|
t.z = vertex.y
|
||
|
|
||
|
s.x = vertex.y
|
||
|
s.y = vertex.x
|
||
|
s.z = vertex.x
|
||
|
|
||
|
var bx : float = abs(normal.x)
|
||
|
var by : float = abs(normal.y)
|
||
|
var bz : float = abs(normal.z)
|
||
|
|
||
|
# if case_code == 7 and cvi == 0:
|
||
|
# print(str(bx) + " " + str(by) + " " + str(bz))
|
||
|
# add_uv(surface.transform_uv(VoxelSurface.VOXEL_SIDE_SIDE, Vector2(s.z, t.z)))
|
||
|
|
||
|
if (bx + 0.0001 > by and bx + 0.0001 > bz):
|
||
|
var uv : Vector2 = Vector2(s.x, t.x)
|
||
|
var umargin : Rect2 = uv_margin
|
||
|
uv.x *= umargin.size.x
|
||
|
uv.y *= umargin.size.y
|
||
|
|
||
|
uv.x += umargin.position.x
|
||
|
uv.y += umargin.position.y
|
||
|
|
||
|
add_uv(surface.transform_uv(VoxelSurface.VOXEL_SIDE_SIDE, uv))
|
||
|
elif (bz + 0.0001 > bx and bz + 0.0001 > by):
|
||
|
var uv : Vector2 = Vector2(s.z, t.z)
|
||
|
var umargin : Rect2 = uv_margin
|
||
|
uv.x *= umargin.size.x
|
||
|
uv.y *= umargin.size.y
|
||
|
|
||
|
uv.x += umargin.position.x
|
||
|
uv.y += umargin.position.y
|
||
|
|
||
|
add_uv(surface.transform_uv(VoxelSurface.VOXEL_SIDE_SIDE, uv))
|
||
|
else:
|
||
|
var uv : Vector2 = Vector2(s.y, t.y)
|
||
|
var umargin : Rect2 = uv_margin
|
||
|
uv.x *= umargin.size.x
|
||
|
uv.y *= umargin.size.y
|
||
|
|
||
|
uv.x += umargin.position.x
|
||
|
uv.y += umargin.position.y
|
||
|
|
||
|
add_uv(surface.transform_uv(VoxelSurface.VOXEL_SIDE_TOP, uv))
|
||
|
|
||
|
for i in range(len(temp_verts)):
|
||
|
|
||
|
var vert_pos : Vector3 = temp_verts[i] as Vector3
|
||
|
|
||
|
vert_pos *= float(lod_size)
|
||
|
vert_pos += Vector3(x, y, z)
|
||
|
|
||
|
var normal : Vector3 = temp_normals[i] as Vector3
|
||
|
|
||
|
var vpx : int = int(vert_pos.x)
|
||
|
var vpy : int = int(vert_pos.y)
|
||
|
var vpz : int = int(vert_pos.z)
|
||
|
|
||
|
var light : Color = Color(buffer.get_voxel(vpx, vpy, vpz, VoxelChunk.DEFAULT_CHANNEL_LIGHT_COLOR_R) / 255.0, buffer.get_voxel(vpx, vpy, vpz, VoxelChunk.DEFAULT_CHANNEL_LIGHT_COLOR_G) / 255.0, buffer.get_voxel(vpx, vpy, vpz, VoxelChunk.DEFAULT_CHANNEL_LIGHT_COLOR_B) / 255.0)
|
||
|
var ao : float = (buffer.get_voxel(vpx, vpy, vpz, VoxelChunk.DEFAULT_CHANNEL_AO) / 255.0) * ao_strength
|
||
|
var rao : float = (buffer.get_voxel(vpx, vpy, vpz, VoxelChunk.DEFAULT_CHANNEL_RANDOM_AO) / 255.0)
|
||
|
ao += rao
|
||
|
|
||
|
light.r += base_light_value
|
||
|
light.g += base_light_value
|
||
|
light.b += base_light_value
|
||
|
|
||
|
light.r -= ao
|
||
|
light.g -= ao
|
||
|
light.b -= ao
|
||
|
|
||
|
light.r = clamp(light.r, 0, 1.0)
|
||
|
light.g = clamp(light.g, 0, 1.0)
|
||
|
light.b = clamp(light.b, 0, 1.0)
|
||
|
|
||
|
# if regular_cell_class == 11:
|
||
|
# print("asd")
|
||
|
# if case_code == 112 + 2:
|
||
|
## print(regular_cell_class)
|
||
|
## print("asd")
|
||
|
# light.r = 1
|
||
|
# light.g = 1
|
||
|
# light.b = 1
|
||
|
|
||
|
|
||
|
add_color(light)
|
||
|
|
||
|
vert_pos *= float(voxel_scale)
|
||
|
|
||
|
add_normal(normal)
|
||
|
add_vertex(vert_pos)
|
||
|
|
||
|
|
||
|
# if case_code == 7:
|
||
|
#
|
||
|
# #reset
|
||
|
# set_regular_vertex_data(case_code, 2, 0x3304)
|
||
|
#
|
||
|
# set_regular_vertex_data(case_code, 3, 0x2315)
|
||
|
# set_regular_vertex_data(case_code, 4, 0x4113)
|
||
|
# set_regular_vertex_data(case_code, 5, 0x1326)
|
||
|
#
|
||
|
# set_regular_vertex_data(case_code, 6, 0x3304)
|
||
|
# set_regular_vertex_data(case_code, 7, 0x2315)
|
||
|
# set_regular_vertex_data(case_code, 8, 0x2315)
|
||
|
|
||
|
func add_buffer_lod(buffer : VoxelChunk) -> void:
|
||
|
if lod_data[CHUNK_INDEX_UP] < lod_size:
|
||
|
# generate_side_lod_mesh(0, buffer)
|
||
|
pass
|
||
|
|
||
|
# CHUNK_INDEX_DOWN = 1,
|
||
|
# CHUNK_INDEX_LEFT = 2,
|
||
|
# CHUNK_INDEX_RIGHT = 3,
|
||
|
# CHUNK_INDEX_FRONT = 4,
|
||
|
# CHUNK_INDEX_BACK = 5,
|
||
|
|
||
|
#generate_main_lod_mesh(buffer)
|
||
|
|
||
|
func generate_side_lod_mesh(sx : int, ex : int, sy : int, ey : int, sz : int, ez : int, buffer : VoxelChunk) -> void:
|
||
|
pass
|
||
|
|
||
|
func generate_main_lod_mesh(buffer : VoxelChunk) -> void:
|
||
|
buffer.generate_ao()
|
||
|
|
||
|
var x_size : int = buffer.get_size_x() - 1
|
||
|
var y_size : int = buffer.get_size_y() - 1
|
||
|
var z_size : int = buffer.get_size_z() - 1
|
||
|
|
||
|
for y in range(0, y_size, lod_size):
|
||
|
for z in range(0, z_size, lod_size):
|
||
|
for x in range(0, x_size, lod_size):
|
||
|
|
||
|
var case_code : int = get_case_code(buffer, x, y, z, lod_size)
|
||
|
|
||
|
if case_code == 0 or case_code == 255:
|
||
|
continue
|
||
|
|
||
|
var regular_cell_class : int = get_regular_cell_class(case_code)
|
||
|
|
||
|
var cell_data : TransvoxelCellData = get_regular_cell_data(regular_cell_class)
|
||
|
|
||
|
var index_count : int = cell_data.get_triangle_count() * 3
|
||
|
var vertex_count : int = cell_data.get_vertex_count()
|
||
|
|
||
|
for i in range(index_count):
|
||
|
var ind : int = get_vertex_count() + cell_data.get_vertex_index(i)
|
||
|
add_indices(ind)
|
||
|
|
||
|
var temp_verts : Array = Array()
|
||
|
|
||
|
for i in range(vertex_count):
|
||
|
var fv : int = get_regular_vertex_data_first_vertex(case_code, i)
|
||
|
var sv : int = get_regular_vertex_data_second_vertex(case_code, i)
|
||
|
|
||
|
var offs0 : Vector3 = corner_id_to_vertex(fv) * lod_size
|
||
|
var offs1 : Vector3 = corner_id_to_vertex(sv) * lod_size
|
||
|
|
||
|
var type0 : int = buffer.get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
# var type1 : int = buffer.get_voxel(int(x + offs1.x), int(y + offs1.y), int(z + offs1.z), VoxelChunk.DEFAULT_CHANNEL_TYPE)
|
||
|
|
||
|
var fill : int = 0
|
||
|
|
||
|
var vert_pos : Vector3
|
||
|
var vert_dir : Vector3
|
||
|
|
||
|
if type0 == 0:
|
||
|
fill = buffer.get_voxel(int(x + offs1.x), int(y + offs1.y), int(z + offs1.z), VoxelChunk.DEFAULT_CHANNEL_ISOLEVEL)
|
||
|
|
||
|
vert_pos = get_regular_vertex_second_position(case_code, i)
|
||
|
vert_dir = get_regular_vertex_first_position(case_code, i)
|
||
|
else:
|
||
|
fill = buffer.get_voxel(int(x + offs0.x), int(y + offs0.y), int(z + offs0.z), VoxelChunk.DEFAULT_CHANNEL_ISOLEVEL)
|
||
|
|
||
|
vert_pos = get_regular_vertex_first_position(case_code, i)
|
||
|
vert_dir = get_regular_vertex_second_position(case_code, i)
|
||
|
|
||
|
vert_dir = vert_dir - vert_pos
|
||
|
|
||
|
vert_pos += vert_dir * (fill / 256.0)
|
||
|
|
||
|
temp_verts.append(vert_pos)
|
||
|
|
||
|
# if regular_uv_entries.size() > uvs[i]:
|
||
|
# add_uv(Vector2(regular_uv_entries[uvs[i]][0], regular_uv_entries[uvs[i]][1]));
|
||
|
|
||
|
# add_uv(Vector2(0, 0))
|
||
|
|
||
|
var temp_normals : Array = Array()
|
||
|
|
||
|
#warning-ignore:unused_variable
|
||
|
for i in range(len(temp_verts)):
|
||
|
temp_normals.append(Vector3())
|
||
|
|
||
|
#generate normals
|
||
|
for i in range(0, index_count, 3):
|
||
|
var indices : Array = [
|
||
|
cell_data.get_vertex_index(i),
|
||
|
cell_data.get_vertex_index(i + 1),
|
||
|
cell_data.get_vertex_index(i + 2)
|
||
|
]
|
||
|
|
||
|
var vertices : Array = [
|
||
|
temp_verts[indices[0]],
|
||
|
temp_verts[indices[1]],
|
||
|
temp_verts[indices[2]],
|
||
|
]
|
||
|
|
||
|
temp_normals[indices[0]] += (vertices[1] - vertices[0]).cross(vertices[0] - vertices[2])
|
||
|
temp_normals[indices[1]] += (vertices[2] - vertices[1]).cross(vertices[1] - vertices[0])
|
||
|
temp_normals[indices[2]] += (vertices[2] - vertices[1]).cross(vertices[2] - vertices[0])
|
||
|
|
||
|
for i in range(len(temp_verts)):
|
||
|
temp_normals[i] = (temp_normals[i] as Vector3).normalized()
|
||
|
|
||
|
for cvi in range(len(temp_verts)):
|
||
|
var vertex : Vector3 = temp_verts[cvi]
|
||
|
var normal : Vector3 = temp_normals[cvi]
|
||
|
|
||
|
var s : Vector3 = Vector3()
|
||
|
var t : Vector3 = Vector3()
|
||
|
t.x = vertex.z
|
||
|
t.y = vertex.z
|
||
|
t.z = vertex.y
|
||
|
|
||
|
s.x = vertex.y
|
||
|
s.y = vertex.x
|
||
|
s.z = vertex.x
|
||
|
|
||
|
var bx : float = abs(normal.x)
|
||
|
var by : float = abs(normal.y)
|
||
|
var bz : float = abs(normal.z)
|
||
|
|
||
|
if (bx > by and bx > bz):
|
||
|
add_uv(Vector2(s.x, t.x))
|
||
|
elif (bz > bx and bz > by):
|
||
|
add_uv(Vector2(s.z, t.z))
|
||
|
else:
|
||
|
add_uv(Vector2(s.y, t.y))
|
||
|
|
||
|
for i in range(len(temp_verts)):
|
||
|
|
||
|
var vert_pos : Vector3 = temp_verts[i] as Vector3
|
||
|
|
||
|
vert_pos *= float(lod_size)
|
||
|
vert_pos += Vector3(x, y, z)
|
||
|
|
||
|
var normal : Vector3 = temp_normals[i] as Vector3
|
||
|
|
||
|
vert_pos *= float(voxel_scale)
|
||
|
|
||
|
add_normal(normal)
|
||
|
add_vertex(vert_pos)
|