private void RefreshInternal(DirtyFlags dirtyFlags) { if (!m_spline || m_spline.Count < 2) { return; } if (!m_updatePosition && m_updateRotation == RotationMode.No) { return; } BezierSpline.Segment segment = m_spline.GetSegmentAt(m_normalizedT); switch (m_updateRotation) { case RotationMode.UseSplineNormals: if (m_rotationOffset == Vector3.zero) { transform.rotation = Quaternion.LookRotation(segment.GetTangent(), segment.GetNormal()); } else { transform.rotation = Quaternion.LookRotation(segment.GetTangent(), segment.GetNormal()) * Quaternion.Euler(m_rotationOffset); } break; case RotationMode.UseEndPointRotations: if (m_rotationOffset == Vector3.zero) { transform.rotation = Quaternion.LerpUnclamped(segment.point1.rotation, segment.point2.rotation, segment.localT); } else { transform.rotation = Quaternion.LerpUnclamped(segment.point1.rotation, segment.point2.rotation, segment.localT) * Quaternion.Euler(m_rotationOffset); } break; } if (m_updatePosition && (dirtyFlags & DirtyFlags.SplineShapeChanged) == DirtyFlags.SplineShapeChanged) { if (m_positionOffset == Vector3.zero) { transform.position = segment.GetPoint(); } else { transform.position = segment.GetPoint() + transform.rotation * m_positionOffset; } } #if UNITY_EDITOR transform.hasChanged = false; #endif }
public void Refresh() { if (!m_spline) { return; } if (!meshFilter || (meshFilter.sharedMesh && meshFilter.sharedMesh != mesh && meshFilter.sharedMesh != originalMesh)) { Initialize(); } if (!originalMesh) { return; } if (vertices == null || vertices.Length != originalVertices.Length) { vertices = new Vector3[originalVertices.Length]; } if (m_normalsMode == VectorMode.ModifyOriginals) { if (originalNormals == null) { originalNormals = originalMesh.normals; } if (originalNormals == null || originalNormals.Length < originalVertices.Length) // If somehow above statement returned null { normals = null; } else if (normals == null || normals.Length != originalNormals.Length) { normals = new Vector3[originalNormals.Length]; } } else { normals = null; } if (m_tangentsMode == VectorMode.ModifyOriginals) { if (originalTangents == null) { originalTangents = originalMesh.tangents; } if (originalTangents == null || originalTangents.Length < originalVertices.Length) // If somehow above statement returned null { tangents = null; } else if (tangents == null || tangents.Length != originalTangents.Length) { tangents = new Vector4[originalTangents.Length]; } } else { tangents = null; } Vector2 _splineSampleRange = m_splineSampleRange; if (m_invertDirection) { float temp = _splineSampleRange.x; _splineSampleRange.x = _splineSampleRange.y; _splineSampleRange.y = temp; } bool isSampleRangeForwards = _splineSampleRange.x <= _splineSampleRange.y; float splineSampleLength = _splineSampleRange.y - _splineSampleRange.x; bool dontInvertModifiedVertexAttributes = (m_thicknessMultiplier.x > 0f && m_thicknessMultiplier.y > 0f); BezierSpline.EvenlySpacedPointsHolder evenlySpacedPoints = m_highQuality ? m_spline.evenlySpacedPoints : null; Vector3 initialPoint = m_spline.GetPoint(0f); for (int i = 0; i < originalVertices.Length; i++) { Vector3 vertex = originalVertices[i]; float vertexPosition; Vector3 vertexOffset; switch (m_bendAxis) { case Axis.X: vertexPosition = vertex.x; vertexOffset = new Vector3(vertex.z * m_thicknessMultiplier.x, 0f, vertex.y * m_thicknessMultiplier.y); break; case Axis.Y: default: vertexPosition = vertex.y; vertexOffset = new Vector3(vertex.x * m_thicknessMultiplier.x, 0f, vertex.z * m_thicknessMultiplier.y); break; case Axis.Z: vertexPosition = vertex.z; vertexOffset = new Vector3(vertex.y * m_thicknessMultiplier.x, 0f, vertex.x * m_thicknessMultiplier.y); break; } float normalizedT = _splineSampleRange.x + (vertexPosition - minVertex) * _1OverVertexRange * splineSampleLength; // Remap from [minVertex,maxVertex] to _splineSampleRange if (m_highQuality) { normalizedT = evenlySpacedPoints.GetNormalizedTAtPercentage(normalizedT); } BezierSpline.Segment segment = m_spline.GetSegmentAt(normalizedT); Vector3 point = segment.GetPoint() - initialPoint; Vector3 tangent = isSampleRangeForwards ? segment.GetTangent() : -segment.GetTangent(); Quaternion rotation = Quaternion.AngleAxis(m_extraRotation, tangent) * Quaternion.LookRotation(segment.GetNormal(), tangent); Vector3 direction = rotation * vertexOffset; vertices[i] = point + direction; if (normals != null) // The only case this happens is when Normals Mode is ModifyOriginals and the original mesh has normals { normals[i] = rotation * (dontInvertModifiedVertexAttributes ? originalNormals[i] : -originalNormals[i]); } if (tangents != null) // The only case this happens is when Tangents Mode is ModifyOriginals and the original mesh has tangents { float tangentW = originalTangents[i].w; tangents[i] = rotation * (dontInvertModifiedVertexAttributes ? originalTangents[i] : -originalTangents[i]); tangents[i].w = tangentW; } } mesh.vertices = vertices; if (m_normalsMode == VectorMode.ModifyOriginals) { mesh.normals = normals; } if (m_tangentsMode == VectorMode.ModifyOriginals) { mesh.tangents = tangents; } if (m_normalsMode == VectorMode.RecalculateFromScratch) { mesh.RecalculateNormals(); #if UNITY_EDITOR // Cache original normals so that we can reset normals in OnValidate when normals are reset back to DontModify if (originalNormals == null) { originalNormals = originalMesh.normals; } #endif } if (m_tangentsMode == VectorMode.RecalculateFromScratch) { mesh.RecalculateTangents(); #if UNITY_EDITOR // Cache original tangents so that we can reset tangents in OnValidate when tangents are reset back to DontModify if (originalTangents == null) { originalTangents = originalMesh.tangents; } #endif } mesh.RecalculateBounds(); }
public void Refresh(int smoothness) { if (!m_spline || m_spline.Count < 2) { return; } if (!lineRenderer) { lineRenderer = GetComponent <LineRenderer>(); } smoothness = Mathf.Clamp(smoothness, 1, 30); int numberOfPoints = (m_spline.Count - 1) * smoothness; if (!m_spline.loop) { numberOfPoints++; // spline.GetPoint( 1f ) } else { numberOfPoints += smoothness; // Final point is connected to the first point via lineRenderer.loop, so no "numberOfPoints++" here } if (lineRendererPoints == null || lineRendererPoints.Length != numberOfPoints) { lineRendererPoints = new Vector3[numberOfPoints]; } if (m_splineSampleRange.x <= 0f && m_splineSampleRange.y >= 1f) { int pointIndex = 0; float smoothnessStep = 1f / smoothness; for (int i = 0; i < m_spline.Count - 1; i++) { BezierSpline.Segment segment = new BezierSpline.Segment(m_spline[i], m_spline[i + 1], 0f); for (int j = 0; j < smoothness; j++, pointIndex++) { lineRendererPoints[pointIndex] = segment.GetPoint(j * smoothnessStep); } } if (!m_spline.loop) { lineRendererPoints[numberOfPoints - 1] = m_spline.GetPoint(1f); } else { BezierSpline.Segment segment = new BezierSpline.Segment(m_spline[m_spline.Count - 1], m_spline[0], 0f); for (int j = 0; j < smoothness; j++, pointIndex++) { lineRendererPoints[pointIndex] = segment.GetPoint(j * smoothnessStep); } } } else { float smoothnessStep = (m_splineSampleRange.y - m_splineSampleRange.x) / (numberOfPoints - 1); for (int i = 0; i < numberOfPoints; i++) { lineRendererPoints[i] = spline.GetPoint(m_splineSampleRange.x + i * smoothnessStep); } } #if UNITY_EDITOR lineRendererUseWorldSpace = lineRenderer.useWorldSpace; #endif if (!lineRenderer.useWorldSpace) { Vector3 initialPoint = m_spline.GetPoint(0f); for (int i = 0; i < numberOfPoints; i++) { lineRendererPoints[i] -= initialPoint; } } lineRenderer.positionCount = lineRendererPoints.Length; lineRenderer.SetPositions(lineRendererPoints); lineRenderer.loop = m_spline.loop && m_splineSampleRange.x <= 0f && m_splineSampleRange.y >= 1f; }