Hey guys,
I’m new to procedural mesh generation and was hoping to create a rope that I can generate along a curve. My implementation seems to work, but I’m missing faces down the length of the rope. Any ideas on what could be causing this? I’ve looked at this all weekend and still haven’t figured it out so any help would be greatly appreciated!
Here is an example:
[198783-mesh-problem.png*_|198783]
I’ve also linked the function I’ve been using to generate below:
public static void GenerateRope(int sides, float thickness, Vector3[] vertices, Mesh mesh)
{
mesh.Clear();
List<Vector3> newVertices = new List<Vector3>();
List<int> triangles = new List<int>();
for (int i = 0; i < vertices.Length-1; i++)
{
Vector3 start = vertices*;*
Vector3 end = vertices[i+1];
float angle = 360f / sides;
Vector3 forward = (end - start).normalized;
Vector3 outward = thickness * Vector3.Cross(Vector3.up, forward).normalized;
// Build Sides
for (int j = 0; j <= sides; j++)
{
Vector3[] points = new Vector3[4];
Quaternion rotation = Quaternion.AngleAxis(angle * j, forward);
Vector3 offset = rotation * outward;
// Top Left, Top Right
points[0] = start + offset;
points[1] = end + offset;
rotation = Quaternion.AngleAxis(angle * (j + 1), forward);
offset = rotation * outward;
// Bottom Left, Bottom Right
points[2] = start + offset;
points[3] = end + offset;
// Build Quads
newVertices.Add(points[0]);
newVertices.Add(points[1]);
newVertices.Add(points[2]);
newVertices.Add(points[3]);
// Build Triangles
int v = (i * j * 4);
triangles.Add(v);
triangles.Add(v + 1);
triangles.Add(v + 2);
triangles.Add(v + 2);
triangles.Add(v + 1);
triangles.Add(v + 3);
}
}
mesh.vertices = newVertices.ToArray();
mesh.triangles = triangles.ToArray().Reverse().ToArray();
mesh.RecalculateNormals();
}
----------
EDIT: Solution
Thanks to @Eno-Khaon I was able to get the rope generating properly! My final script is attached below for anyone to use as a reference, or to generate a rope on their own! Happy coding
----------
[198800-rope-final.png_|198800]*
----------
static Vector3 GetDirectionVector(Vector3 to, Vector3 from)
{
return (to - from).normalized;
}
public static void GenerateRope(int sides, float thickness, Vector3[] vertices, Mesh mesh)
{
mesh.Clear();
List newVertices = new List();
List triangles = new List();
int ringSize = sides * 4;
float angle = 360f / sides;
for (int i = 0; i < vertices.Length-1; i++)
{
// Grab Vertices
Vector3 start = vertices*;*
Vector3 end = vertices[i + 1];
// Calculate Direction Vectors
Vector3 direction = GetDirectionVector(end, start);
Vector3 forward = i > 0 ?
GetDirectionVector(start, vertices[i - 1]) + direction // midpoint between current and last point
: direction;
Vector3 endForward = i < vertices.Length - 2?
direction + GetDirectionVector(vertices[i+2], end) // midpoint between current and next point
: direction;
Vector3 outward = thickness * Vector3.Cross(Vector3.up, forward).normalized; // outward thickness
for (int j = 0; j < sides; j++)
{
// Build Quad
Quaternion startRotation = Quaternion.AngleAxis(angle * j, forward);
Quaternion endRotation = Quaternion.AngleAxis(angle * j, endForward);
Vector3 startOffset = startRotation * outward;
Vector3 endOffset = endRotation * outward;
// Top Left, Top Right
newVertices.Add(start + startOffset);
newVertices.Add(end + endOffset);
// Flip to Next Edge
startRotation = Quaternion.AngleAxis(angle * (j+1), forward);
endRotation = Quaternion.AngleAxis(angle * (j+1), endForward);
startOffset = startRotation * outward;
endOffset = endRotation * outward;
// Bottom Left, Bottom Right
newVertices.Add(start + startOffset);
newVertices.Add(end + endOffset);
// Build Triangles
int v = (i * ringSize) + (j * 4);
triangles.Add(v);
triangles.Add(v + 2);
triangles.Add(v + 1);
triangles.Add(v + 2);
triangles.Add(v + 3);
triangles.Add(v + 1);
}
}
mesh.SetVertices(newVertices);
mesh.SetTriangles(triangles, 0);
mesh.RecalculateNormals();
}
_*
_*