private void FillOnce() { sampleCache.Clear(); var bentVertices = new List <MeshVertex>(source.Vertices.Count); // for each mesh vertex, we found its projection on the curve foreach (var vert in source.Vertices) { float distance = vert.position.x - source.MinX; CurveSample sample; if (!sampleCache.TryGetValue(distance, out sample)) { if (!useSpline) { if (distance > curve.Length) { distance = curve.Length; } sample = curve.GetSampleAtDistance(distance); } else { float distOnSpline = intervalStart + distance; if (distOnSpline > spline.Length) { if (spline.IsLoop) { while (distOnSpline > spline.Length) { distOnSpline -= spline.Length; } } else { distOnSpline = spline.Length; } } sample = spline.GetSampleAtDistance(distOnSpline); } sampleCache[distance] = sample; } bentVertices.Add(sample.GetBent(vert)); } MeshUtility.Update(result, source.Mesh, source.Triangles, bentVertices.Select(b => b.position), bentVertices.Select(b => b.normal)); }
/// <summary> /// Bend the mesh. This method may take time and should not be called more than necessary. /// Consider using <see cref="ComputeIfNeeded"/> for faster result. /// </summary> public void Compute() { if (isDirty) { BuildData(); } isDirty = false; // we manage a cache because in most situations, the mesh will contain several vertices located at the same curve distance. Dictionary <float, CurveSample> sampleCache = new Dictionary <float, CurveSample>(); List <Vertex> bentVertices = new List <Vertex>(vertices.Count); // for each mesh vertex, we found its projection on the curve foreach (Vertex vert in transformedVertices) { Vertex bent = new Vertex() { v = vert.v, n = vert.n }; float distanceRate = Math.Abs(bent.v.x - minX) / length; CurveSample sample; if (!sampleCache.TryGetValue(distanceRate, out sample)) { sample = curve.GetSampleAtDistance(curve.Length * distanceRate); sampleCache[distanceRate] = sample; } // application of scale bent.v = Vector3.Scale(bent.v, new Vector3(0, sample.scale.y, sample.scale.x)); // application of roll bent.v = Quaternion.AngleAxis(sample.roll, Vector3.right) * bent.v; bent.n = Quaternion.AngleAxis(sample.roll, Vector3.right) * bent.n; // reset X value bent.v.x = 0; // application of the rotation + location Quaternion q = sample.Rotation * Quaternion.Euler(0, -90, 0); bent.v = q * bent.v + sample.location; bent.n = q * bent.n; bentVertices.Add(bent); } result.vertices = bentVertices.Select(b => b.v).ToArray(); result.normals = bentVertices.Select(b => b.n).ToArray(); result.RecalculateBounds(); }