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, normals: 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 i in new_vertex_count: var vert = new_vertex_list[i] verticies.push_back(vert) var normal_list: Array[Vector4] = [] normal_list.resize(new_vertex_count) normal_list.fill(Vector4(0,0,0,0)) tri_index = 0 while mc._tri_table[cube_index][tri_index] != -1: var p1: Vector3 = new_vertex_list[local_remap[mc._tri_table[cube_index][tri_index + 0]]] var p2: Vector3 = new_vertex_list[local_remap[mc._tri_table[cube_index][tri_index + 1]]] var p3: Vector3 = new_vertex_list[local_remap[mc._tri_table[cube_index][tri_index + 2]]] var normal = (p2 - p1).cross(p3 - p1).normalized(); var normal_4 = Vector4(normal.x, normal.y, normal.z, 1) normal_list[local_remap[mc._tri_table[cube_index][tri_index + 0]]] += normal_4 normal_list[local_remap[mc._tri_table[cube_index][tri_index + 1]]] += normal_4 normal_list[local_remap[mc._tri_table[cube_index][tri_index + 2]]] += normal_4 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 for normal in normal_list: var new_normal = Vector3(normal.x, normal.y, normal.z) / normal.w normals.push_back(new_normal.normalized()) func vertex_interpolate(p1: Vector3, p2: Vector3, val1: float, val2: float): return (p1 + (-val1 / (val2 - val1)) * (p2 - p1))