- Edited
I am trying to create a rope-like thing, but have to generate the mesh part by part. Although the mesh is cut in parts, I want it to look smoothly. I have already kept the crosssection of each part well-joined, but failed to figure out how to smooth the seams in shader between every two parts. Could anyone please to help? Thank you.
Here are the codes to generate the 3d rope-like thing
`
extends Node3D
var radius := .12
var resolution := 7
var points = null
var fake_up_vectors = null
var tangents := []
func apply_curve(curve):
$Path3D.set_curve(curve)
# pre-set the curve bake interval, by default it is .2
curve.set_bake_interval(.1)
# init points, fake_up_vectors and tangents
points = curve.get_baked_points()
fake_up_vectors = curve.get_baked_up_vectors()
tangents = []
for i in points.size():
if i > 0 and i < points.size() - 1:
# not endpoint
tangents.push_back((points[i + 1] - points[i - 1]).normalized())
else:
# manipulate the up vector for the first and last point
if i <= 0:
if curve.get_point_out(0):
tangents.push_back(curve.get_point_out(0).normalized())
else:
tangents.push_back((points[i + 1] - points[i]).normalized())
else:
if curve.get_point_in(curve.get_point_count() - 1):
tangents.push_back((Vector3(0,0,0) - curve.get_point_in(curve.get_point_count() - 1)).normalized())
else:
tangents.push_back((points[i] - points[i - 1]).normalized())
var plane = Plane(tangents[i])
fake_up_vectors[i] = plane.project(Vector3(0,0,1)).normalized()
extrude()
func extrude():
var vertices := PackedVector3Array()
var indices := PackedInt32Array()
for point_index in points.size():
var center = points[point_index]
var tangent = tangents[point_index]
var cross = Vector3(0,0,1).cross(tangent).normalized()
var angle = Vector3(0,0,1).signed_angle_to(tangent, cross)
var angle2 = .0
vertices.push_back(center) # center of the circle
var vertice_ind_ori = point_index * (resolution + 1) # index for the center
for section in resolution:
var degree = PI * 2 * section / resolution
var x = radius * sin(degree)
var y = radius * cos(degree)
var coords = Vector3(x, y, 0).rotated(cross, angle)
if section == 0: angle2 = coords.signed_angle_to(fake_up_vectors[point_index], tangent)
coords = coords.rotated(tangent, angle2)
vertices.push_back(coords + center)
if point_index >= 1:
# draw triangles
# 1 3
# 0 2
var vertice_ind_0 = vertice_ind_ori + section + 1
var vertice_ind_1 = vertice_ind_0 - (resolution + 1)
var vertice_ind_2 = (vertice_ind_0 + 1) if (section < resolution - 1) else (vertice_ind_0 + 1 - resolution)
var vertice_ind_3 = vertice_ind_2 - (resolution + 1)
indices.append_array(PackedInt32Array([
vertice_ind_0, vertice_ind_1, vertice_ind_3,
vertice_ind_0, vertice_ind_3, vertice_ind_2
]))
var arrays = []
arrays.resize(Mesh.ARRAY_MAX)
arrays[Mesh.ARRAY_VERTEX] = vertices
arrays[Mesh.ARRAY_INDEX] = indices
var arr_mesh = ArrayMesh.new()
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
var surface_tool = SurfaceTool.new()
surface_tool.begin(Mesh.PRIMITIVE_TRIANGLES)
for v in vertices:
surface_tool.add_vertex(v)
for i in indices:
surface_tool.add_index(i)
surface_tool.generate_normals()
arr_mesh = surface_tool.commit()
$MeshInstance3D.mesh = arr_mesh
`