Files
nodewars/addons/curved_lines_2d/adaptable_vector_shape_3d.gd
2026-05-13 18:52:00 +02:00

115 lines
3.8 KiB
GDScript

@tool
extends Node3D
class_name AdaptableVectorShape3D
const STORED_CURVE_META_NAME := "_stored_curve_data_"
const STORED_ARC_LIST_META_NAME := "_stored_arc_list_data_"
const STORED_SHAPE_TYPE_META_NAME := "_stored_shape_type_"
const STORED_SIZE_META_NAME := "_stored_shape_size_"
const STORED_RX_META_NAME := "_stored_shape_rx_"
const STORED_RY_META_NAME := "_stored_shape_ry_"
const STORED_OFFSET_META_NAME := "_stored_shape_offset_"
const STORED_STROKE_WIDTH_META_NAME := "_stored_stroke_width_"
const STORED_JOINT_MODE_META_NAME := "_stored_joint_mode_"
const STORED_LINE_CAP_META_NAME := "_stored_line_cap_"
@export var guide_svs : ScalableVectorShape2D:
set(svs):
if is_instance_valid(guide_svs) and guide_svs != svs:
if guide_svs.polygons_updated.is_connected(_on_guide_svs_polygons_updated):
guide_svs.polygons_updated.disconnect(_on_guide_svs_polygons_updated)
guide_svs = svs
if is_instance_valid(guide_svs):
_on_guide_svs_assigned()
@export var fill_polygons : Array[CSGPolygon3D] = []
@export var stroke_polygons : Array[CSGPolygon3D] = []
var _update_locked := false
func _on_guide_svs_assigned():
guide_svs.update_curve_at_runtime = true
guide_svs.polygons_updated.connect(_on_guide_svs_polygons_updated)
guide_svs.curve_changed()
func _on_guide_svs_polygons_updated(polygons : Array[PackedVector2Array],
poly_strokes : Array[PackedVector2Array], _svs : ScalableVectorShape2D):
if _update_locked:
return
_update_locked = true
for p in fill_polygons + stroke_polygons:
p.hide()
for i in polygons.size():
if i < fill_polygons.size():
fill_polygons[i].show()
fill_polygons[i].polygon = polygons[i]
else:
var extra_fp := fill_polygons[i - 1].duplicate()
extra_fp.polygon = polygons[i]
fill_polygons.append(extra_fp)
add_child(extra_fp, true)
extra_fp.owner = owner
for i in poly_strokes.size():
if i < stroke_polygons.size():
stroke_polygons[i].show()
stroke_polygons[i].polygon = poly_strokes[i]
else:
var extra_sp := stroke_polygons[i - 1].duplicate()
extra_sp.polygon = poly_strokes[i]
stroke_polygons.append(extra_sp)
add_child(extra_sp, true)
extra_sp.owner = owner
_update_locked = false
static func is_stroke_in_front_of_fill(svs : ScalableVectorShape2D) -> bool:
var stroke_node : Node2D = (svs.line if is_instance_valid(svs.line) else svs.poly_stroke)
if not is_instance_valid(stroke_node):
return false
if not is_instance_valid(svs.polygon):
return true
var fill_found := false
for ch in svs.get_children():
if ch == svs.polygon:
fill_found = true
if ch == stroke_node and fill_found:
return true
return false
static func extract_csg_polygons_from_scalable_vector_shapes(svs : ScalableVectorShape2D,
is_strokes := false, is_line_2d_strokes := false, z_index := 0.0) -> Array[CSGPolygon3D]:
var result : Array[CSGPolygon3D] = []
var polygons = (
svs.cached_poly_strokes
if is_strokes else
([svs.cached_outline] if svs.clip_paths.is_empty() else svs.cached_clipped_polygons)
)
for poly : PackedVector2Array in polygons:
var csg_polygon := CSGPolygon3D.new()
csg_polygon.depth = 0.01
csg_polygon.position.z = 0.01 * z_index
csg_polygon.polygon = poly
csg_polygon.material = StandardMaterial3D.new()
csg_polygon.material.shading_mode = BaseMaterial3D.SHADING_MODE_PER_PIXEL
csg_polygon.material.transparency = BaseMaterial3D.TRANSPARENCY_DISABLED
if is_strokes:
csg_polygon.material.albedo_color = svs.stroke_color
if is_line_2d_strokes:
csg_polygon.name = svs.line.name
else:
csg_polygon.name = svs.poly_stroke.name
csg_polygon.material.albedo_texture = svs.poly_stroke.texture
else:
csg_polygon.name = svs.polygon.name
csg_polygon.material.albedo_color = svs.polygon.color
csg_polygon.material.albedo_texture = svs.polygon.texture
result.append(csg_polygon)
return result