extends Node @export var outer_polygon: PackedVector2Array @export var inner_polygons: Array[PackedVector2Array] @export var edge_non_fracture: float = 0.1 @onready var camera: Camera3D = get_node("/root/Node3D/Camera3D") @onready var meshInstance = MeshInstance3D.new() @onready var parentNode = get_node("..") var depth: float: set(value): if value > 0: depth = -value depth = value var static_body: StaticBody3D func _ready() -> void: assert(camera, "camera was not found") assert(len(outer_polygon) > 2, "outer polygon does not meet the required length") camera.connect("wall_hit", _handle_hit_signal) self.add_child(meshInstance) _draw() func _draw(): var vector_indexes = GeoPolyTriangulization.triangulate(outer_polygon, inner_polygons) var vectors = [] vectors.append_array(outer_polygon) for ip in inner_polygons: vectors.append_array(ip) var meshGenerator = GeoPolyMesh.new(vector_indexes, vectors) var mesh = meshGenerator.commit_mesh() meshInstance.mesh = mesh meshInstance.create_trimesh_collision() static_body = _find_static_body() func _re_draw(): meshInstance.remove_child(static_body) static_body.queue_free() var vector_indexes = GeoPolyTriangulization.triangulate(outer_polygon, inner_polygons) var vectors = [] vectors.append_array(outer_polygon) for ip in inner_polygons: vectors.append_array(ip) var meshGenerator = GeoPolyMesh.new(vector_indexes, vectors) var mesh = meshGenerator.commit_mesh() meshInstance.mesh = mesh meshInstance.create_trimesh_collision() static_body = _find_static_body() func _handle_hit_signal(wall_id: int, position: Vector3, cutter: PackedVector2Array): # validate that the hit was to this wall, if not return if wall_id != static_body.get_instance_id(): return var hole_position_offset = self.position + position var hole_vector2_offset = Vector2(hole_position_offset.x, hole_position_offset.y) # translate the cutter var hole_vectors = Transform2D(0, hole_vector2_offset) * cutter _add_hole(hole_vectors) _re_draw() func _add_hole(new_hole: PackedVector2Array): var values_to_remove = [] var merged: PackedVector2Array = new_hole for index in range(len(self.inner_polygons)): var result = Geometry2D.merge_polygons(merged, self.inner_polygons[index]) if len(result) == 1: merged = result[0] values_to_remove.append(self.inner_polygons[index]) elif len(result) > 1: # need to check that they have no overlapping area if they do clip var overlap = Geometry2D.intersect_polygons(result[0], result[1]) if len(overlap) != 0: merged = Geometry2D.clip_polygons(result[0], result[1])[0] values_to_remove.append(self.inner_polygons[index]) for i in values_to_remove: self.inner_polygons.erase(i) inner_polygons.append(merged) func _find_static_body(): for child in meshInstance.get_children(): if child is StaticBody3D: return child