private void CalculateSpline(List <Transform> points, int subdiv) { Vector3 p0; Vector3 p1; Vector3 m0; Vector3 m1; subdiv++; float pointStep = 1f / subdiv; for (int i = 0; i < points.Count - 1; i++) { p0 = points[i].transform.position; p1 = points[i + 1].transform.position; // m0 if (i == 0) { m0 = p1 - p0; } else { m0 = 0.5f * (p1 - points[i - 1].transform.position); } // m1 if (i < points.Count - 2) { m1 = 0.5f * (points[(i + 2) % points.Count].transform.position - p0); } else { m1 = p1 - p0; } Vector3 position; float t; if (i == points.Count - 2) { pointStep = 1f / (subdiv - 1); } for (int j = 0; j < subdiv; j++) { t = j * pointStep; Vector3 tangent; position = Interpolate(p0, p1, m0, m1, t, out tangent); TubePoint tpmain = new TubePoint() { direction = tangent, position = position, right = Vector3.Cross(Vector3.up, tangent).normalized }; Samples.Add(tpmain); } } }
private void CalculateLine(List <Transform> points, int subdiv) { List <TubePoint> mainSamples = new List <TubePoint>(); for (int i = 0; i < points.Count; i++) { var p = points[i]; var pf = p.forward; if (i == 0) { pf = (points[i + 1].position - p.position).normalized; } else if (i == points.Count - 1) { pf = (p.position - points[i - 1].position).normalized; } else { var dir0 = (p.position - points[i - 1].position).normalized; var dir1 = (points[i + 1].position - p.position).normalized; var res = dir0 + dir1; pf = res.normalized; } TubePoint tpmain = new TubePoint() { IsPoint = true, direction = pf, position = p.position, right = Vector3.Cross(p.up, pf).normalized, }; mainSamples.Add(tpmain); } for (int i = 0; i < mainSamples.Count; i++) { if (i == mainSamples.Count - 1) { TubePoint tpmain = mainSamples[i]; Samples.Add(tpmain); } else { Samples.Add(mainSamples[i]); Vector3 dir = mainSamples[i + 1].position - mainSamples[i].position; dir /= subdiv; for (int j = 0; j < subdiv - 1; j++) { TubePoint tp = new TubePoint() { IsPoint = false, direction = dir.normalized, position = mainSamples[i].position + dir * (j + 1), right = Vector3.Cross(Vector3.up, dir.normalized).normalized }; Samples.Add(tp); } } } }
public static void generateTubes(Mesh mesh, List <TubePoint> points, int numSides = 24) { mesh.Clear(); int numVertices = numSides * points.Count; Vector3[] vertices = new Vector3[numVertices]; Vector3[] normals = new Vector3[numVertices]; Vector2[] uvs = new Vector2[numVertices]; int numFace = numSides * (points.Count - 1); int numTriangles = numFace * 2; int numIndexes = numTriangles * 3; int[] triangles = new int[numIndexes]; int vert = 0; int i; int j; int n; for (i = 0, n = points.Count; i < n; i++) { // make a ring of vertices around each point oriented perpendicular to the derivative TubePoint point = points[i]; float u = ((float)i) / (n - 1); // sweep a vector around the derivative vector Vector3 firstRadiusVector = Vector3.Cross(point.derivative, Vector3.up).normalized; if (firstRadiusVector.magnitude < 0.00001f) { // what to do if tube is straight up? firstRadiusVector = Vector3.Cross(point.derivative, Vector3.right).normalized; } //Debug.Log("New Ring"); for (j = 0; j < numSides; j++) { float angle = 360f * j / numSides; Vector3 radVector = Quaternion.AngleAxis(angle, point.derivative) * firstRadiusVector * point.radius; vertices[vert] = radVector + point.position; normals[vert] = -radVector; //Debug.Log("radVector=" + radVector + " vert=" + vertices[vert]); uvs[vert] = new Vector2(u, ((float)j) / numSides); vert++; } } //Debug.Log("Created " + vert + " vertices of " + numVertices); int tri = 0; for (i = 0, n = points.Count - 1; i < n; i++) { for (j = 0; j < numSides; j++) { int curr = i * numSides + j; int next = i * numSides + ((j + 1) % numSides); triangles[tri++] = curr; triangles[tri++] = curr + numSides; triangles[tri++] = next + numSides; triangles[tri++] = curr; triangles[tri++] = next + numSides; triangles[tri++] = next; } } //Debug.Log("Created " + (tri/3.0f) + " triangles of expected " + numTriangles); mesh.vertices = vertices; mesh.normals = normals; mesh.uv = uvs; mesh.triangles = triangles; mesh.RecalculateBounds(); mesh.Optimize(); }