GodotShade/smooth_world.gd
2025-11-26 19:07:10 +01:00

164 lines
4.2 KiB
GDScript

@tool
extends Node3D
const CENTER := Vector3.ZERO
@export var RADIUS: float = 5.0
var sample_points = {}
var surface_points = {}
@export var world_size = 16
@export var do_the_thing: bool = false
@export var clear_the_thing: bool = false
var mesh
var surface_tool: SurfaceTool = SurfaceTool.new()
var SAMPLE_POINT = preload("res://sample_point.tscn")
var SURFACE_POINT = preload("res://surface_point.tscn")
func _ready() -> void:
initialize_sample_points()
create_surface_points()
create_surface_mesh(world_size)
func _process(_delta: float) -> void:
clear()
create_surface_points()
create_surface_mesh(world_size)
func clear():
sample_points = {}
for child in get_children():
remove_child(child)
child.queue_free()
func get_sample_value(index: Vector3i) -> float:
return CENTER.distance_to(index) - RADIUS
func initialize_sample_points():
for x in range(-world_size + 1, world_size):
for y in range(-world_size + 1, world_size):
for z in range(-world_size + 1, world_size):
var sample_point = SAMPLE_POINT.instantiate()
sample_point.distance = get_sample_value(Vector3i(x, y, z))
sample_point.position = Vector3(float(x), float(y), float(z))
sample_points[Vector3i(x, y, z)] = sample_point
#add_child(sample_point)
func create_surface_points():
for x in range(-world_size + 1, world_size):
for y in range(-world_size + 1, world_size):
for z in range(-world_size + 1, world_size):
create_surface_point(Vector3i(x, y, z))
func create_surface_point(voxel: Vector3i):
var average_distance_from_sample = 0
for sample_point_to_check_index in range(SURFACE_AXIS.size()):
var sample_point_to_check = SURFACE_AXIS[sample_point_to_check_index]
average_distance_from_sample += get_sample_value(voxel + sample_point_to_check)
average_distance_from_sample /= 8
if average_distance_from_sample <= 0:
var surface_point = SURFACE_POINT.instantiate()
surface_point.position = Vector3(voxel)
surface_points[voxel] = surface_point
add_child(surface_point)
func create_surface_mesh(size: int = 6):
surface_tool = SurfaceTool.new()
surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
for x in range(-size, size):
for y in range(-size, size):
for z in range(-size, size):
create_surface_mesh_quad(Vector3i(x,y,z));
mesh = surface_tool.commit()
var meshinstance = MeshInstance3D.new()
meshinstance.mesh = mesh
add_child(meshinstance)
func create_surface_mesh_quad(index: Vector3i):
for axis_index in range(AXIS.size()):
var axis = AXIS[axis_index]
var sample_value1 = get_sample_value(index)
var sample_value2 = get_sample_value(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)
surface_tool.set_normal(AXIS[axis_index])
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])
func add_reversed_quad(index: Vector3i, axis_index: int):
var points = get_quad_points(index, axis_index)
surface_tool.set_normal(-AXIS[axis_index])
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])
func get_quad_points(index: Vector3i, axis_index: int):
return [
index + QUAD_POINTS[axis_index][0],
index + QUAD_POINTS[axis_index][1],
index + QUAD_POINTS[axis_index][2],
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)
],
]