private void Compute() { if (source == null) { return; } if (generatedMesh == null) { generatedMesh = new Mesh(); } int nbVert = source.vertices.Length; // find the bounds along BendAxis float minX = float.MaxValue; float maxX = float.MinValue; foreach (Vertex vert in vertices) { Vector3 p = vert.v; if (sourceRotation != Quaternion.identity) { p = sourceRotation * p; } if (sourceTranslation != Vector3.zero) { p += sourceTranslation; } switch (BendAxis) { case Axis.X: maxX = Math.Max(maxX, p.x); minX = Math.Min(minX, p.x); break; case Axis.Z: maxX = Math.Max(maxX, p.z); minX = Math.Min(minX, p.z); break; default: throw new ArgumentOutOfRangeException(); } } float length = Math.Abs(maxX - minX); List <Vector3> deformedVerts = new List <Vector3>(nbVert); List <Vector3> deformedNormals = new List <Vector3>(nbVert); // for each mesh vertex, we have to find its projection on the curve foreach (Vertex vert in vertices) { Vector3 p = vert.v; Vector3 n = vert.n; // application of rotation if (sourceRotation != Quaternion.identity) { p = sourceRotation * p; n = sourceRotation * n; } if (sourceTranslation != Vector3.zero) { p += sourceTranslation; } float distanceRate; switch (BendAxis) { case Axis.X: distanceRate = Math.Abs(p.x - minX) / length; break; case Axis.Z: distanceRate = Math.Abs(p.z - minX) / length; break; default: throw new ArgumentOutOfRangeException(); } Vector3 curvePoint = curve.GetLocationAtDistance(curve.Length * distanceRate); Vector3 curveTangent = curve.GetTangentAtDistance(curve.Length * distanceRate); Quaternion q = CubicBezierCurve.GetRotationFromTangent(curveTangent); // application of scale float scaleAtDistance = startScale + (endScale - startScale) * distanceRate; p *= scaleAtDistance; // application of roll float rollAtDistance = startRoll + (endRoll - startRoll) * distanceRate; switch (BendAxis) { case Axis.X: p = Quaternion.AngleAxis(rollAtDistance, Vector3.right) * p; n = Quaternion.AngleAxis(rollAtDistance, Vector3.right) * n; // reset X value of p p = new Vector3(0, p.y, p.z); break; case Axis.Z: p = Quaternion.AngleAxis(rollAtDistance, Vector3.forward) * p; n = Quaternion.AngleAxis(rollAtDistance, Vector3.forward) * n; // reset Z value of p p = new Vector3(p.x, p.y, 0); break; default: throw new ArgumentOutOfRangeException(); } Vector3 fvert = q * p + curvePoint; deformedVerts.Add(fvert); deformedNormals.Add(q * n); } generatedMesh.vertices = deformedVerts.ToArray(); generatedMesh.normals = deformedNormals.ToArray(); generatedMesh.uv = source.uv; generatedMesh.triangles = source.triangles; GetComponent <MeshFilter>().mesh = generatedMesh; }
public Vector3 GetLocationAtDistance(float d) { return(sourceCurve.GetLocationAtDistance(Mathf.Min(startLength + d, sourceCurve.Length))); }