private void FillRepeat() { float intervalLength = useSpline ? (intervalEnd == 0 ? spline.Length : intervalEnd) - intervalStart : curve.Length; int repetitionCount = Mathf.FloorToInt(intervalLength / source.Length); // building triangles and UVs for the repeated mesh var triangles = new List <int>(); var uv = new List <Vector2>(); var uv2 = new List <Vector2>(); var uv3 = new List <Vector2>(); var uv4 = new List <Vector2>(); var uv5 = new List <Vector2>(); var uv6 = new List <Vector2>(); var uv7 = new List <Vector2>(); var uv8 = new List <Vector2>(); for (int i = 0; i < repetitionCount; i++) { foreach (var index in source.Triangles) { triangles.Add(index + source.Vertices.Count * i); } uv.AddRange(source.Mesh.uv); uv2.AddRange(source.Mesh.uv2); uv3.AddRange(source.Mesh.uv3); uv4.AddRange(source.Mesh.uv4); #if UNITY_2018_2_OR_NEWER uv5.AddRange(source.Mesh.uv5); uv6.AddRange(source.Mesh.uv6); uv7.AddRange(source.Mesh.uv7); uv8.AddRange(source.Mesh.uv8); #endif } // computing vertices and normals var bentVertices = new List <MeshVertex>(source.Vertices.Count); float offset = 0; for (int i = 0; i < repetitionCount; i++) { sampleCache.Clear(); // for each mesh vertex, we found its projection on the curve foreach (var vert in source.Vertices) { float distance = vert.position.x - source.MinX + offset; CurveSample sample; if (!sampleCache.TryGetValue(distance, out sample)) { if (!useSpline) { if (distance > curve.Length) { continue; } sample = curve.GetSampleAtDistance(distance); } else { float distOnSpline = intervalStart + distance; //if (true) { //spline.isLoop) { while (distOnSpline > spline.Length) { distOnSpline -= spline.Length; } //} else if (distOnSpline > spline.Length) { // continue; //} sample = spline.GetSampleAtDistance(distOnSpline); } sampleCache[distance] = sample; } bentVertices.Add(sample.GetBent(vert)); } offset += source.Length; MeshUtility.Update(result, source.Mesh, triangles, bentVertices.Select(b => b.position), bentVertices.Select(b => b.normal), uv, uv2, uv3, uv4, uv5, uv6, uv7, uv8); } }
/// <summary> /// Build data that are consistent between computations if no property has been changed. /// This method allows the computation due to curve changes to be faster. /// </summary> private void BuildData() { if (source == null) { throw new Exception(GetType().Name + " can't compute because there is no source mesh."); } // find the bounds along x minX = float.MaxValue; float maxX = float.MinValue; foreach (Vertex vert in vertices) { Vector3 p = vert.v; if (rotation != Quaternion.identity) { p = rotation * p; } if (translation != Vector3.zero) { p += translation; } maxX = Math.Max(maxX, p.x); minX = Math.Min(minX, p.x); } length = Math.Abs(maxX - minX); // if the mesh is reversed by scale, we must change the culling of the faces by inversing all triangles. // the mesh is reverse only if the number of resersing axes is impair. bool reversed = scale.x < 0; if (scale.y < 0) { reversed = !reversed; } if (scale.z < 0) { reversed = !reversed; } result.triangles = reversed ? MeshUtility.GetReversedTriangles(source) : source.triangles; // we transform the source mesh vertices according to rotation/translation/scale transformedVertices.Clear(); foreach (Vertex vert in vertices) { Vertex transformed = new Vertex() { v = vert.v, n = vert.n }; // application of rotation if (rotation != Quaternion.identity) { transformed.v = rotation * transformed.v; transformed.n = rotation * transformed.n; } if (scale != Vector3.one) { transformed.v = Vector3.Scale(transformed.v, scale); transformed.n = Vector3.Scale(transformed.n, scale); } if (translation != Vector3.zero) { transformed.v += translation; } transformedVertices.Add(transformed); } }