public Vector3 RoadCenterAt(float distanceFromStart, out bool done, out Vector3 direction) { var segments = Math.Round(CachedNodes.Length * 100 * SegmentRate); var nodePositions = CachedNodes.Select(x => x.transform.localPosition).ToArray(); float lengthSeen = 0; for (int i = 0; i <= segments; i++) { var s = i / (float)segments; var center = MathfPlus.BSpline(nodePositions, s); Vector3 nextCenter = MathfPlus.BSpline(nodePositions, (i + 1) / (float)segments); direction = nextCenter - center; var segmentLength = Vector3.Distance(nextCenter, center); lengthSeen += segmentLength; if (lengthSeen > distanceFromStart) { float distanceAtLastSegment = lengthSeen - segmentLength; done = false; return(transform.localToWorldMatrix * MathfPlus.PadVector3(Vector3.Lerp(center, nextCenter, (distanceFromStart - distanceAtLastSegment) / (lengthSeen - distanceAtLastSegment)))); } } // fallback : at distance = 0 done = true; direction = Vector3.zero; return(Vector3.zero); }
void Rebuild() { var vertices = new List <Vector3>(); var triangles = new List <int>(); var uv = new List <Vector2>(); var nodePositions = CachedNodes.Select(x => x.transform.localPosition).ToArray(); SplineMesh.Clear(); SplineMesh.subMeshCount = 1; RoadTotalLength = 0; var segments = Math.Round(CachedNodes.Length * 100 * SegmentRate); float accumulatedTexCoord = 0; for (int i = 0; i <= segments; i++) { var s = i / (float)segments; var center = MathfPlus.BSpline(nodePositions, s); Vector3 nextCenter = MathfPlus.BSpline(nodePositions, (i + 1) / (float)segments); var diff = Vector3.Normalize(nextCenter - center); var tangent = Vector3.Cross(diff, Vector3.up); var c = vertices.Count; var segmentLength = Vector3.Distance(nextCenter, center); RoadTotalLength += segmentLength; accumulatedTexCoord += segmentLength * 0.1f; vertices.Add(center - tangent * Width); uv.Add(new Vector2(0, accumulatedTexCoord)); vertices.Add(center + tangent * Width); uv.Add(new Vector2(1, accumulatedTexCoord)); if (i != segments) { triangles.Add(c); triangles.Add(c + 1); triangles.Add(c + 2); triangles.Add(c + 2); triangles.Add(c + 1); triangles.Add(c + 3); triangles.Add(c); triangles.Add(c + 2); triangles.Add(c + 1); triangles.Add(c + 2); triangles.Add(c + 3); triangles.Add(c + 1); } } if (vertices.Count > 0) { try { SplineMesh.vertices = vertices.ToArray(); SplineMesh.uv = uv.ToArray(); SplineMesh.SetTriangles(triangles.ToArray(), 0); SplineMesh.RecalculateNormals(); SplineMesh.RecalculateBounds(); SplineMesh.Optimize(); } catch (Exception exception) { Debug.Log(exception.Message); } } }