156 lines
4.1 KiB
GDScript
156 lines
4.1 KiB
GDScript
extends ImmediateGeometry
|
|
|
|
export var points = [Vector3(0,0,0),Vector3(0,5,0)]
|
|
export var startThickness = 0.1
|
|
export var endThickness = 0.1
|
|
export var cornerSmooth = 5
|
|
export var capSmooth = 5
|
|
export var drawCaps = true
|
|
export var drawCorners = true
|
|
export var globalCoords = true
|
|
export var scaleTexture = true
|
|
|
|
var camera
|
|
var cameraOrigin
|
|
|
|
func _ready():
|
|
pass
|
|
|
|
func _process(delta):
|
|
if points.size() < 2:
|
|
return
|
|
|
|
camera = get_viewport().get_camera()
|
|
if camera == null:
|
|
return
|
|
cameraOrigin = to_local(camera.get_global_transform().origin)
|
|
|
|
var progressStep = 1.0 / points.size();
|
|
var progress = 0;
|
|
var thickness = lerp(startThickness, endThickness, progress);
|
|
var nextThickness = lerp(startThickness, endThickness, progress + progressStep);
|
|
|
|
clear()
|
|
begin(Mesh.PRIMITIVE_TRIANGLES)
|
|
|
|
for i in range(points.size() - 1):
|
|
var A = points[i]
|
|
var B = points[i+1]
|
|
|
|
if globalCoords:
|
|
A = to_local(A)
|
|
B = to_local(B)
|
|
|
|
var AB = B - A;
|
|
var orthogonalABStart = (cameraOrigin - ((A + B) / 2)).cross(AB).normalized() * thickness;
|
|
var orthogonalABEnd = (cameraOrigin - ((A + B) / 2)).cross(AB).normalized() * nextThickness;
|
|
|
|
var AtoABStart = A + orthogonalABStart
|
|
var AfromABStart = A - orthogonalABStart
|
|
var BtoABEnd = B + orthogonalABEnd
|
|
var BfromABEnd = B - orthogonalABEnd
|
|
|
|
if i == 0:
|
|
if drawCaps:
|
|
cap(A, B, thickness, capSmooth)
|
|
|
|
if scaleTexture:
|
|
var ABLen = AB.length()
|
|
var ABFloor = floor(ABLen)
|
|
var ABFrac = ABLen - ABFloor
|
|
|
|
set_uv(Vector2(ABFloor, 0))
|
|
add_vertex(AtoABStart)
|
|
set_uv(Vector2(-ABFrac, 0))
|
|
add_vertex(BtoABEnd)
|
|
set_uv(Vector2(ABFloor, 1))
|
|
add_vertex(AfromABStart)
|
|
set_uv(Vector2(-ABFrac, 0))
|
|
add_vertex(BtoABEnd)
|
|
set_uv(Vector2(-ABFrac, 1))
|
|
add_vertex(BfromABEnd)
|
|
set_uv(Vector2(ABFloor, 1))
|
|
add_vertex(AfromABStart)
|
|
else:
|
|
set_uv(Vector2(1, 0))
|
|
add_vertex(AtoABStart)
|
|
set_uv(Vector2(0, 0))
|
|
add_vertex(BtoABEnd)
|
|
set_uv(Vector2(1, 1))
|
|
add_vertex(AfromABStart)
|
|
set_uv(Vector2(0, 0))
|
|
add_vertex(BtoABEnd)
|
|
set_uv(Vector2(0, 1))
|
|
add_vertex(BfromABEnd)
|
|
set_uv(Vector2(1, 1))
|
|
add_vertex(AfromABStart)
|
|
|
|
if i == points.size() - 2:
|
|
if drawCaps:
|
|
cap(B, A, nextThickness, capSmooth)
|
|
else:
|
|
if drawCorners:
|
|
var C = points[i+2]
|
|
if globalCoords:
|
|
C = to_local(C)
|
|
|
|
var BC = C - B;
|
|
var orthogonalBCStart = (cameraOrigin - ((B + C) / 2)).cross(BC).normalized() * nextThickness;
|
|
|
|
var angleDot = AB.dot(orthogonalBCStart)
|
|
|
|
if angleDot > 0:
|
|
corner(B, BtoABEnd, B + orthogonalBCStart, cornerSmooth)
|
|
else:
|
|
corner(B, B - orthogonalBCStart, BfromABEnd, cornerSmooth)
|
|
|
|
progress += progressStep;
|
|
thickness = lerp(startThickness, endThickness, progress);
|
|
nextThickness = lerp(startThickness, endThickness, progress + progressStep);
|
|
|
|
end()
|
|
|
|
func cap(center, pivot, thickness, smoothing):
|
|
var orthogonal = (cameraOrigin - center).cross(center - pivot).normalized() * thickness;
|
|
var axis = (center - cameraOrigin).normalized();
|
|
|
|
var array = []
|
|
for i in range(smoothing + 1):
|
|
array.append(Vector3(0,0,0))
|
|
array[0] = center + orthogonal;
|
|
array[smoothing] = center - orthogonal;
|
|
|
|
for i in range(1, smoothing):
|
|
array[i] = center + (orthogonal.rotated(axis, lerp(0, PI, float(i) / smoothing)));
|
|
|
|
for i in range(1, smoothing + 1):
|
|
set_uv(Vector2(0, (i - 1) / smoothing))
|
|
add_vertex(array[i - 1]);
|
|
set_uv(Vector2(0, (i - 1) / smoothing))
|
|
add_vertex(array[i]);
|
|
set_uv(Vector2(0.5, 0.5))
|
|
add_vertex(center);
|
|
|
|
func corner(center, start, end, smoothing):
|
|
var array = []
|
|
for i in range(smoothing + 1):
|
|
array.append(Vector3(0,0,0))
|
|
array[0] = start;
|
|
array[smoothing] = end;
|
|
|
|
var axis = start.cross(end).normalized()
|
|
var offset = start - center
|
|
var angle = offset.angle_to(end - center)
|
|
|
|
for i in range(1, smoothing):
|
|
array[i] = center + offset.rotated(axis, lerp(0, angle, float(i) / smoothing));
|
|
|
|
for i in range(1, smoothing + 1):
|
|
set_uv(Vector2(0, (i - 1) / smoothing))
|
|
add_vertex(array[i - 1]);
|
|
set_uv(Vector2(0, (i - 1) / smoothing))
|
|
add_vertex(array[i]);
|
|
set_uv(Vector2(0.5, 0.5))
|
|
add_vertex(center);
|
|
|