89 lines
1.9 KiB
GDScript
89 lines
1.9 KiB
GDScript
@tool
|
|
|
|
extends Node3D
|
|
|
|
@onready var mesh: MeshInstance3D = $Line
|
|
@onready var plane: MeshInstance3D = $Plane
|
|
@onready var x_axis: Sprite3D = $XAxis
|
|
|
|
const RADIUS = 0.005
|
|
const STEPS = 5
|
|
|
|
@export var size: Vector2 = Vector2(0.5, 0.3)
|
|
|
|
var points = R.state([])
|
|
|
|
var minmax = R.computed(func(_arg):
|
|
if points.value.size() == 0:
|
|
return [Vector2(0, 0), Vector2(0, 0)]
|
|
|
|
var min=points.value[0]
|
|
var max=points.value[0]
|
|
|
|
for point in points.value:
|
|
min.x=min(min.x, point.x)
|
|
min.y=min(min.y, point.y)
|
|
max.x=max(max.x, point.x)
|
|
max.y=max(max.y, point.y)
|
|
|
|
return [min, max]
|
|
)
|
|
|
|
var relative_points = R.computed(func(_arg):
|
|
var min=minmax.value[0]
|
|
var max=minmax.value[1]
|
|
|
|
return points.value.map(func(point):
|
|
return Vector2(inverse_lerp(min.x, max.x, point.x), inverse_lerp(min.y, max.y, point.y))
|
|
)
|
|
)
|
|
|
|
func _ready():
|
|
for i in range(100):
|
|
points.value.append(Vector2(i, sin(i / 10.0)))
|
|
|
|
R.effect(func(_arg):
|
|
mesh.mesh=generate_mesh(relative_points.value)
|
|
)
|
|
|
|
plane.position = Vector3(size.x / 2, size.y / 2, -0.001)
|
|
plane.mesh.size = size
|
|
|
|
func generate_mesh(points: Array):
|
|
if points.size() < 2:
|
|
return null
|
|
|
|
var sf = SurfaceTool.new()
|
|
|
|
sf.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
|
|
|
for i in range(points.size() - 1):
|
|
var point = points[i]
|
|
var next_point = points[i + 1]
|
|
|
|
var angle = (next_point - point).angle_to(Vector2(1, 0))
|
|
|
|
var up = Vector2(0, 1).rotated( - angle)
|
|
|
|
var p0 = point + up * RADIUS * 2
|
|
var p1 = point + up * - RADIUS * 2
|
|
|
|
sf.add_vertex(Vector3(p0.x * size.x, p0.y * size.y, 0))
|
|
sf.add_vertex(Vector3(p1.x * size.x, p1.y * size.y, 0))
|
|
|
|
sf.index()
|
|
sf.generate_normals()
|
|
|
|
var _mesh = sf.commit()
|
|
|
|
sf.clear()
|
|
sf.begin(Mesh.PRIMITIVE_TRIANGLE_STRIP)
|
|
|
|
for i in range(points.size() - 1):
|
|
var point = points[i]
|
|
|
|
sf.add_vertex(Vector3(point.x * size.x, point.y * size.y, RADIUS))
|
|
sf.add_vertex(Vector3(point.x * size.x, point.y * size.y, -RADIUS))
|
|
|
|
return sf.commit(_mesh)
|
|
|