#@tool extends Node3D const CENTER := Vector3.ZERO @export var RADIUS: float = 5.0 var sample_points = {} var SamplePoint = preload("res://sample_point.gd") var surface_points = {} var SurfacePoint = preload("res://surface_point.gd") var ComputeSdf = preload("res://compute_test.gd") var gpu_sdf var generate_mesh_shader = preload("res://generate_mesh.tres") var regenerate_mesh = false @export var world_size = 16 @export var show_sample_points = false @export var show_surface_points = false @export var show_surface = true @export var do_the_thing: bool = false @export var clear_the_thing: bool = false var color = Color.CORAL var surface_point_color = Color.CRIMSON var mesh var surface_tool: SurfaceTool = SurfaceTool.new() var meshinstance = MeshInstance3D.new() var material = ShaderMaterial.new() func _ready() -> void: material.shader = generate_mesh_shader meshinstance.material_override = material add_child(meshinstance) gpu_sdf = ComputeSdf.new() gpu_sdf.create_device() var dictionaries = gpu_sdf.compute(world_size, RADIUS) surface_points = dictionaries.surface_points_dict sample_points = dictionaries.sample_points_dict create_surface_mesh() func _process(_delta: float) -> void: if !surface_points.is_empty(): #create_surface_points_gpu() #create_surface_points() if show_surface_points: draw_surface_points() if show_surface && regenerate_mesh: clear() var dictionaries = gpu_sdf.compute(world_size, RADIUS) surface_points = dictionaries.surface_points_dict sample_points = dictionaries.sample_points_dict create_surface_mesh() if show_sample_points: draw_sample_points() func clear(): surface_points = {} sample_points = {} mesh = ArrayMesh.new() func get_index_from_coords(coords: Vector3i): return coords.x + coords.y * world_size + coords.z * world_size * world_size func draw_sample_points(): for x in range(world_size): for y in range(world_size): for z in range(world_size): if sample_points.has(Vector3i(x, y, z)): DebugDraw3D.draw_square(Vector3i(x, y, z), 0.2, color) #DebugDraw3D.draw_text(Vector3i(x, y, z), str(Vector3i(x, y, z))) func draw_surface_points(): for surface_point in surface_points: if surface_points[surface_point] != Vector3(0, 0, 0): DebugDraw3D.draw_square(surface_points[surface_point] , 0.3, surface_point_color) DebugDraw3D.draw_text(surface_points[surface_point], str(surface_points[surface_point])) func calculate_surface_point_position(voxel: Vector3i): var final_point = Vector3(voxel) return final_point func create_surface_mesh(): surface_tool = SurfaceTool.new() surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES) for x in range(world_size): for y in range(world_size): for z in range(world_size): if surface_points.has(Vector3i(x, y, z)): create_surface_mesh_quad(Vector3i(x,y,z)); mesh = surface_tool.commit() meshinstance.mesh = mesh func create_surface_mesh_quad(index: Vector3i): for axis_index in range(AXIS.size()): var axis = AXIS[axis_index] if sample_points.has(index + axis): var sample_value1 = sample_points[index] var sample_value2 = sample_points[index + axis] if sample_value1 < 0 and sample_value2 >= 0: add_quad(index, axis_index) elif sample_value1 >= 0 and sample_value2 < 0: add_reversed_quad(index, axis_index) const AXIS := [ Vector3i(1,0,0), Vector3i(0,1,0), Vector3i(0,0,1), ] const SURFACE_AXIS := [ Vector3i(1,0,0), Vector3i(0,1,0), Vector3i(0,0,1), Vector3i(1,0,1), Vector3i(0,1,1), Vector3i(1,1,0), Vector3i(1,1,1), Vector3i(0,0,0), ] func add_quad(index: Vector3i, axis_index: int): var points = get_quad_points(index, axis_index) if points != null: surface_tool.add_vertex(points[0]) surface_tool.add_vertex(points[1]) surface_tool.add_vertex(points[2]) surface_tool.add_vertex(points[0]) surface_tool.add_vertex(points[2]) surface_tool.add_vertex(points[3]) surface_tool.generate_normals() func add_reversed_quad(index: Vector3i, axis_index: int): var points = get_quad_points(index, axis_index) if points != null: surface_tool.add_vertex(points[0]) surface_tool.add_vertex(points[2]) surface_tool.add_vertex(points[1]) surface_tool.add_vertex(points[0]) surface_tool.add_vertex(points[3]) surface_tool.add_vertex(points[2]) surface_tool.generate_normals() func get_quad_points(index: Vector3i, axis_index: int): if surface_points.has(index + QUAD_POINTS[axis_index][0]) and surface_points.has(index + QUAD_POINTS[axis_index][1]) and surface_points.has(index + QUAD_POINTS[axis_index][2]) and surface_points.has(index + QUAD_POINTS[axis_index][3]): return [ surface_points[index + QUAD_POINTS[axis_index][0]], surface_points[index + QUAD_POINTS[axis_index][1]], surface_points[index + QUAD_POINTS[axis_index][2]], surface_points[index + QUAD_POINTS[axis_index][3]], ] const QUAD_POINTS := [ # x axis [ Vector3i(0,0,-1), Vector3i(0,-1,-1), Vector3i(0,-1,0), Vector3i(0,0,0) ], # y axis [ Vector3i(0,0,-1), Vector3i(0,0,0), Vector3i(-1,0,0), Vector3i(-1,0,-1) ], # z axis [ Vector3i(0,0,0), Vector3i(0,-1,0), Vector3i(-1,-1,0), Vector3i(-1,0,0) ], ]