Hey Godot forum,
I'm trying to use SurfaceTool to generate a Mesh around a Path.
I'm tesselating the Path, and going through those points, creating verteces in a circle around it.
Afterwards I loop through the tesselated points again and assign the verteces an index so they make a neat mesh.
Or so I thought. The mesh looks good and UV's are working properly, only there is this final point that the SurfaceTool makes up at the Path's origin, I can't for the life of me figure out what's causing this.
This is the Path code:
extends Path
export(float) var stemThickness = 1 #factor used to multiply up and right vectors to increase stem width
export(float) var lerpStep = .5 #step made to interpolate between old up and right vectors, smooths over sudden changes in the path
export(int) var tesselate_tolerance = 6
export(int) var tesselate_max = 3
export var smooth = true #bool if the stem is shaded smooth
export var smoothness = .5
export var uvScale = Vector2(1.0, 1.0) #vec2 to multiply the uv vec2 by, increase this if the stem is longer, to make the pixels on the stem smaller
export(int) var sides = 3
func _ready():
var baseFactorArray = []
for k in sides:
baseFactorArray.append(Vector3.UP.rotated(Vector3(0,0,1), TAU/sides*k)) #create an array of vec3, that are used to find a x and y factor to multiplicate the up and right vecs of the points by. making a neat shape
var bpoints = curve.tessellate(tesselate_max, tesselate_tolerance) #tesselate the curve, making more points in bends
var curlen = curve.get_baked_length()
var st = SurfaceTool.new()
st.clear()
st.begin(Mesh.PRIMITIVE_TRIANGLES)
st.add_smooth_group(smooth)
var upvec_old = Vector3.ZERO #make room for the old upvec
var rightvec_old = Vector3.ZERO #same for right
for i in range (bpoints.size()): #loop over points
var pos = bpoints[i] #get the current position
var stageoncurve = curve.get_closest_offset(pos)/curlen #stage on curve is needed to calculate the uv, because the points arent evenly distributed because of tesselation
var forward = curve.interpolate_baked(stageoncurve + smoothness) #look forward a bit
var backward = curve.interpolate_baked(stageoncurve - smoothness) #look backward a bit
var forwardvec = forward - backward #get the direction from back to front
var rightvec_new = forwardvec.cross(Vector3.UP).normalized() * stemThickness #cross product from forward direction with upvec gives rightvec
var upvec_new = rightvec_new.cross(forwardvec).normalized() * stemThickness #cross the rightvec with the forwardvec for real upvec.
var rightvec = lerp(rightvec_old, rightvec_new, lerpStep) #now lerp between the old right and new yiou jsut calced
var upvec = lerp(upvec_old, upvec_new, lerpStep) #same for up
var fakebase = [upvec, rightvec] #make a "fakebase" which is just an array and just x and y :P
for k in range(sides): #iterations for every corner of "cylinder"
var add = fakebase[0] * baseFactorArray[k].x + fakebase[1] * baseFactorArray[k].y #"add" is the vec3 ur gonna add to your current position. you multiply the x and y components of the fake base with preset multiplications
st.add_uv(Vector2(stageoncurve, float(k)/float(sides)/float(bpoints.size())) * uvScale) #add the uv, using the stageoncurve for the u and stage on the k loop divided by the total length for the v. multiply it by uv scale to scale
st.add_vertex(pos + add) #add the vertex by adding add to pos :)
upvec_old = upvec
rightvec_old = rightvec
for i in bpoints.size(): #loop through all points you made verteces around again to assign indeces
var _i = i * sides #multiply i by amount of sides your cylinder has
for k in sides: # for every side except the last, which has to wrap back
#make quads from 2 triangles
if k < sides - 1:
st.add_index(k + _i)
st.add_index(k + _i + sides)
st.add_index(k + _i + sides + 1)
st.add_index(k + _i)
st.add_index(k + _i + sides + 1)
st.add_index(k + _i + 1)
pass
else: #the last quad is different, looping back on the first quad
st.add_index(k + _i)
st.add_index(k + _i + sides)
st.add_index(k + _i + 1)
st.add_index(k + _i)
st.add_index(_i + sides)
st.add_index(_i)
pass
var _mesh = st.commit()
var meshinst = MeshInstance.new()
meshinst.mesh = _mesh
add_child(meshinst)
I circled the unexpected loop back to origin:

PS: Sorry I also can't get all of the code to be recognised as such 🙁