public void Rotate(SearchableLocations <Position> list, int avgRange, float twistAmount) { Curvature = 0; for (int i = Index - avgRange, j = Index + avgRange; i < j; i++) { Curvature += Vector3.SignedAngle( list[i + 1].TangentXZ, list[i].TangentXZ, Vector3.up); } Curvature /= (float)(avgRange * 2); Quaternion glbYRot = Quaternion.FromToRotation(Vector3.forward, TangentXZ); Quaternion locXRot = Quaternion.FromToRotation(TangentXZ, Tangent); Quaternion locZRot = Quaternion.AngleAxis(Curvature * twistAmount, Vector3.forward); Rotation = glbYRot * locXRot * locZRot; Orthogonal = Rotation * Vector3.right; Normal = Rotation * Vector3.up; }
private void Refresh() { spline = spline ?? FindObjectOfType <BezierSpline>(); spline.Refresh(); int n = chunkCount * ringsPerChunk; Positions = new SearchableLocations <Position>(n); for (int i = 0; i < n; i++) { Positions.Add(new Position(1f / n * i, spline)); } int avgRange = Mathf.Max(1, Mathf.RoundToInt(Positions.Count / 2 * smoothing)); float twistAmount = twist * (chunkCount * ringsPerChunk / 8); // TBD for (int i = 0; i < n; i++) { Positions[i].Rotate(Positions, avgRange, twistAmount); } n /= segmentLength; Segments = new SearchableLocations <Segment>(n); for (int i = 0; i < n; i++) { Segments.Add(new Segment( Positions[i * segmentLength], Positions[(i + 1) * segmentLength], laneCount)); } NormLanes = new Lanes(laneCount, laneExtent, laneGap); gizmoLanes = NormLanes.Scale(radiusX); // Same for all locations, constant track width. TrackLocation.OrthoLength = radiusX; }