diff options
Diffstat (limited to 'scripts/marching_cubes.gd')
-rw-r--r-- | scripts/marching_cubes.gd | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/scripts/marching_cubes.gd b/scripts/marching_cubes.gd new file mode 100644 index 0000000..09eaa0d --- /dev/null +++ b/scripts/marching_cubes.gd @@ -0,0 +1,81 @@ +extends Node + +# Marching cubes algorithm ported from https://graphics.stanford.edu/~mdfisher/MarchingCubes.html + +const mc = preload("res://scripts/marching_cubes_data.gd") + +class Cell: + var position: Array[Vector3] + var value: Array[float] + + func _init(): + position.resize(8) + value.resize(8) + +func march_cube(cell: Cell, triangles: PackedInt32Array, verticies: PackedVector3Array): + var cube_index : int = 0 + + var vertex_list: Array[Vector3] = [] + vertex_list.resize(12) + + var starting_vertex_count = verticies.size() + + for i in 8: + if cell.value[i] < 0: cube_index |= (1 << i) + + if mc._edge_table[cube_index] == 0: + return + + if mc._edge_table[cube_index] & 1 != 0: + vertex_list[0] = (vertex_interpolate(cell.position[0], cell.position[1], cell.value[0], cell.value[1])) + if mc._edge_table[cube_index] & 2 != 0: + vertex_list[1] = (vertex_interpolate(cell.position[1], cell.position[2], cell.value[1], cell.value[2])) + if mc._edge_table[cube_index] & 4 != 0: + vertex_list[2] = (vertex_interpolate(cell.position[2], cell.position[3], cell.value[2], cell.value[3])) + if mc._edge_table[cube_index] & 8 != 0: + vertex_list[3] = (vertex_interpolate(cell.position[3], cell.position[0], cell.value[3], cell.value[0])) + if mc._edge_table[cube_index] & 16 != 0: + vertex_list[4] = (vertex_interpolate(cell.position[4], cell.position[5], cell.value[4], cell.value[5])) + if mc._edge_table[cube_index] & 32 != 0: + vertex_list[5] = (vertex_interpolate(cell.position[5], cell.position[6], cell.value[5], cell.value[6])) + if mc._edge_table[cube_index] & 64 != 0: + vertex_list[6] = (vertex_interpolate(cell.position[6], cell.position[7], cell.value[6], cell.value[7])) + if mc._edge_table[cube_index] & 128 != 0: + vertex_list[7] = (vertex_interpolate(cell.position[7], cell.position[4], cell.value[7], cell.value[4])) + if mc._edge_table[cube_index] & 256 != 0: + vertex_list[8] = (vertex_interpolate(cell.position[0], cell.position[4], cell.value[0], cell.value[4])) + if mc._edge_table[cube_index] & 512 != 0: + vertex_list[9] = (vertex_interpolate(cell.position[1], cell.position[5], cell.value[1], cell.value[5])) + if mc._edge_table[cube_index] & 1024 != 0: + vertex_list[10] = (vertex_interpolate(cell.position[2], cell.position[6], cell.value[2], cell.value[6])) + if mc._edge_table[cube_index] & 2048 != 0: + vertex_list[11] = (vertex_interpolate(cell.position[3], cell.position[7], cell.value[3], cell.value[7])) + + var new_vertex_count: int = 0 + var local_remap: Array[int] = [] + local_remap.resize(12) + local_remap.fill(-1) + + var new_vertex_list: Array[Vector3] = [] + new_vertex_list.resize(12) + + var tri_index: int = 0 + while mc._tri_table[cube_index][tri_index] != -1: + if local_remap[mc._tri_table[cube_index][tri_index]] == -1: + new_vertex_list[new_vertex_count] = vertex_list[mc._tri_table[cube_index][tri_index]] + local_remap[mc._tri_table[cube_index][tri_index]] = new_vertex_count + new_vertex_count += 1 + tri_index += 1 + + for vert in new_vertex_list: + verticies.push_back(vert) + + tri_index = 0 + while mc._tri_table[cube_index][tri_index] != -1: + triangles.push_back(local_remap[mc._tri_table[cube_index][tri_index + 0]] + starting_vertex_count) + triangles.push_back(local_remap[mc._tri_table[cube_index][tri_index + 1]] + starting_vertex_count) + triangles.push_back(local_remap[mc._tri_table[cube_index][tri_index + 2]] + starting_vertex_count) + tri_index += 3 + +func vertex_interpolate(p1: Vector3, p2: Vector3, val1: float, val2: float): + return (p1 + (-val1 / (val2 - val1)) * (p2 - p1)) |