init
This commit is contained in:
+123
@@ -0,0 +1,123 @@
|
||||
@tool
|
||||
extends Polygon2D
|
||||
|
||||
var _hash: int
|
||||
@export var _floor_mesh: MeshInstance3D
|
||||
@export var _wall_mesh: MeshInstance3D
|
||||
@export var _scale: float = 0.1
|
||||
@export var _seed: int
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if (script_changed.connect(_geometry_update) != OK):
|
||||
push_error("Cannot connect _geometry_update")
|
||||
|
||||
|
||||
# No idea how to make it getter, but whatever.
|
||||
func _process(_delta: float) -> void:
|
||||
var h := Array(polygon).hash() + hash(_scale) + hash(_seed)
|
||||
if h != _hash:
|
||||
_geometry_update()
|
||||
_hash = h
|
||||
|
||||
|
||||
func _geometry_update() -> void:
|
||||
print("Rebuilding level: ", name)
|
||||
if polygon.size() <= 2: return
|
||||
_prepare_polygons()
|
||||
_prepare_mesh()
|
||||
|
||||
|
||||
func _prepare_polygons() -> void:
|
||||
var polys := Geometry2D.triangulate_delaunay(polygon)
|
||||
var pickled := Array()
|
||||
for i in polys.size() / 3:
|
||||
pickled.push_front(PackedInt32Array([polys[i * 3 + 0], polys[i * 3 + 1], polys[i * 3 + 2]]))
|
||||
polygons = pickled
|
||||
_fix_acute_polygons()
|
||||
|
||||
|
||||
func _fix_acute_polygons() -> void:
|
||||
# Outside triangles are in reversed winding, find and eliminate.
|
||||
var new := Array()
|
||||
for poly in polygons as Array[PackedInt32Array]:
|
||||
var ab := polygon[poly[1]] - polygon[poly[0]]
|
||||
var ac := polygon[poly[2]] - polygon[poly[0]]
|
||||
if (ab.x * ac.y - ab.y * ac.x) * 0.5 <= 0:
|
||||
new.push_front(poly)
|
||||
polygons = new
|
||||
|
||||
|
||||
func _prepare_mesh() -> void:
|
||||
_prepare_floor_mesh()
|
||||
_prepare_wall_mesh()
|
||||
|
||||
|
||||
func _prepare_floor_mesh() -> void:
|
||||
var m := ImmediateMesh.new()
|
||||
|
||||
m.surface_begin(Mesh.PRIMITIVE_LINES)
|
||||
for poly in polygons as Array[PackedInt32Array]:
|
||||
m.surface_add_vertex(Vector3(polygon[poly[0]].x * _scale, 0, polygon[poly[0]].y * _scale))
|
||||
m.surface_add_vertex(Vector3(polygon[poly[1]].x * _scale, 0, polygon[poly[1]].y * _scale))
|
||||
m.surface_add_vertex(Vector3(polygon[poly[2]].x * _scale, 0, polygon[poly[2]].y * _scale))
|
||||
m.surface_end()
|
||||
|
||||
m.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||
for poly in polygons as Array[PackedInt32Array]:
|
||||
m.surface_set_uv(Vector2(polygon[poly[0]].x * _scale, polygon[poly[0]].y * _scale))
|
||||
m.surface_add_vertex(Vector3(polygon[poly[0]].x * _scale, 0, polygon[poly[0]].y * _scale))
|
||||
m.surface_set_uv(Vector2(polygon[poly[1]].x * _scale, polygon[poly[1]].y * _scale))
|
||||
m.surface_add_vertex(Vector3(polygon[poly[1]].x * _scale, 0, polygon[poly[1]].y * _scale))
|
||||
m.surface_set_uv(Vector2(polygon[poly[2]].x * _scale, polygon[poly[2]].y * _scale))
|
||||
m.surface_add_vertex(Vector3(polygon[poly[2]].x * _scale, 0, polygon[poly[2]].y * _scale))
|
||||
m.surface_end()
|
||||
|
||||
_floor_mesh.mesh = m
|
||||
|
||||
|
||||
func _prepare_wall_mesh() -> void:
|
||||
var m := ImmediateMesh.new()
|
||||
m.surface_begin(Mesh.PRIMITIVE_TRIANGLES)
|
||||
var x := 0
|
||||
var rng := RandomNumberGenerator.new()
|
||||
var dy := rng.randf_range(-1.0, 1.0)
|
||||
var ndy := rng.randf_range(-1.0, 1.0)
|
||||
rng.seed = _seed
|
||||
for ld in polygon.size():
|
||||
var nd := (ld + 1) % polygon.size()
|
||||
var nnd := (ld + 2) % polygon.size()
|
||||
var nx := x + polygon[ld].distance_to(polygon[nd])
|
||||
# Middle displacement
|
||||
var depth := Vector3(-(polygon[nd].y - polygon[ld].y) * _scale, 0, (polygon[nd].x - polygon[ld].x) * _scale) * 0.2
|
||||
var depth2 := Vector3(-(polygon[nnd].y - polygon[nd].y) * _scale, 0, (polygon[nnd].x - polygon[nd].x) * _scale) * 0.2
|
||||
# Lower half
|
||||
m.surface_set_uv(Vector2(x * _scale, 0))
|
||||
m.surface_add_vertex(Vector3(polygon[ld].x * _scale, 0, polygon[ld].y * _scale))
|
||||
m.surface_set_uv(Vector2(nx * _scale, 0))
|
||||
m.surface_add_vertex(Vector3(polygon[nd].x * _scale, 0, polygon[nd].y * _scale))
|
||||
m.surface_set_uv(Vector2(x * _scale, 3))
|
||||
m.surface_add_vertex(Vector3(polygon[ld].x * _scale, 2 + dy, polygon[ld].y * _scale) + depth)
|
||||
m.surface_set_uv(Vector2(nx * _scale, 0))
|
||||
m.surface_add_vertex(Vector3(polygon[nd].x * _scale, 0, polygon[nd].y * _scale))
|
||||
m.surface_set_uv(Vector2(nx * _scale, 3))
|
||||
m.surface_add_vertex(Vector3(polygon[nd].x * _scale, 2 + ndy, polygon[nd].y * _scale) + depth2)
|
||||
m.surface_set_uv(Vector2(x * _scale, 3))
|
||||
m.surface_add_vertex(Vector3(polygon[ld].x * _scale, 2 + dy, polygon[ld].y * _scale) + depth)
|
||||
# Upper half
|
||||
m.surface_set_uv(Vector2(x * _scale, 0))
|
||||
m.surface_add_vertex(Vector3(polygon[ld].x * _scale, 2 + dy, polygon[ld].y * _scale) + depth)
|
||||
m.surface_set_uv(Vector2(nx * _scale, 0))
|
||||
m.surface_add_vertex(Vector3(polygon[nd].x * _scale, 2 + ndy, polygon[nd].y * _scale) + depth2)
|
||||
m.surface_set_uv(Vector2(x * _scale, 3))
|
||||
m.surface_add_vertex(Vector3(polygon[ld].x * _scale, 5, polygon[ld].y * _scale))
|
||||
m.surface_set_uv(Vector2(nx * _scale, 0))
|
||||
m.surface_add_vertex(Vector3(polygon[nd].x * _scale, 2 + ndy, polygon[nd].y * _scale) + depth2)
|
||||
m.surface_set_uv(Vector2(nx * _scale, 3))
|
||||
m.surface_add_vertex(Vector3(polygon[nd].x * _scale, 5, polygon[nd].y * _scale))
|
||||
m.surface_set_uv(Vector2(x * _scale, 3))
|
||||
m.surface_add_vertex(Vector3(polygon[ld].x * _scale, 5, polygon[ld].y * _scale))
|
||||
dy = ndy
|
||||
ndy = rng.randf_range(-1.0, 1.0)
|
||||
m.surface_end()
|
||||
_wall_mesh.mesh = m
|
||||
Reference in New Issue
Block a user