• Godot Help
  • Making a Mesh with SurfaceTool around a Path. Keeps looping back to Path origin

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 🙁

    tobias Lil' update: I was indexing beyond the verteces I actually made, so all I needed to do was loop over the amount of points -1 and now everything is fine!