void OnSceneDraw(SceneView sceneView) { List <Vector3> vertices = curveLineRenderer.vertices; if (vertices.Count == 0) { return; } Handles.color = Color.white; Vector3 prev = ShowVertex(0); for (int i = 1; i < vertices.Count; ++i) { Vector3 cur = ShowVertex(i); Handles.DrawLine(prev, cur); prev = cur; } #if (CURVE_LINE_RENDERER_DEBUG_SHOW_NORMALS) Mesh mesh = handleMeshFilter.sharedMesh; Handles.color = Color.green; for (int i = 0; i < mesh.normals.Length; i += 1 ) { Vector3 startPoint = handleTransform.TransformPoint(mesh.vertices[i]); Vector3 normal = mesh.normals[i]; Handles.DrawLine(startPoint, startPoint + normal); } #endif if (GUI.changed) { if (target != null) { EditorUtility.SetDirty(target); } RebuildMesh(); } if (curveLineRenderer.transform.hasChanged) { curveLineRenderer.isCurveConnetionProcessed = false; UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); curveLineRenderer.Invalidate(); } }
/** * Build curve line mesh with defined parameters */ public Mesh Rebuild(Mesh mesh, MeshCollider meshCollider) { if (mesh == null) { return(mesh); } mesh.Clear(); if (vertices == null || vertices.Count < 2 || width <= 0f || normal == Vector3.zero || (type == LineType.Rounded && (roundedAngle <= 0f || radius <= 0f))) { return(mesh); } float length; Vector3 ver1, ver2; Vector3 nextVer1, nextVer2; // Normalize the normal vector Vector3 n = normal.normalized; // Define the list of vertices depending on the type List <Vector3> vertexList; switch (type) { case LineType.Rounded: vertexList = getRoundedVertices(); break; case LineType.Default: vertexList = getDefaultVertices(); break; default: vertexList = getSplittedVertices(); break; } List <Vector3> meshVertices = new List <Vector3>(); List <Vector2> meshUvs = new List <Vector2>(); // First vertex Vector3 direction = vertexList[1] - vertexList[0]; direction.Normalize(); Vector3 qdir = Vector3.Cross(direction, n).normalized; ver1 = vertexList[0] - qdir * width * 0.5f; meshVertices.Add(ver1); ver2 = vertexList[0] + qdir * width * 0.5f; meshVertices.Add(ver2); float len = 0f; if (prevCurve != null && !isCurveConnetionProcessed) { len = prevCurve.previousLen; } meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); // Inner vertices for (int i = 1; i < vertexList.Count - 1; ++i) { Vector3 nextDirection = vertexList[i + 1] - vertexList[i]; nextDirection.Normalize(); Vector3 nextQdir = calculateQdir(direction, nextDirection, n, qdir); if (type == LineType.Splitted) { // Splitted type len += (vertexList[i] - vertexList[i - 1]).magnitude; // Add both vertices meshVertices.Add(vertexList[i] - qdir * width * 0.5f); meshVertices.Add(vertexList[i] + qdir * width * 0.5f); meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); meshVertices.Add(vertexList[i] - nextQdir * width * 0.5f); meshVertices.Add(vertexList[i] + nextQdir * width * 0.5f); meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); } else if (type == LineType.Rounded) { // Rounded type Vector3 pdir = (qdir + nextQdir).normalized; float w = width / Mathf.Sin(Vector3.Angle(direction, pdir) * Mathf.PI / 180.0f); nextVer1 = vertexList[i] - pdir * w * 0.5f; nextVer2 = vertexList[i] + pdir * w * 0.5f; len += ((nextVer1 - ver1).magnitude + (nextVer2 - ver2).magnitude) * 0.5f; meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); meshVertices.Add(nextVer1); meshVertices.Add(nextVer2); meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); ver1 = nextVer1; ver2 = nextVer2; } else { // Default type Vector3 pdir = (qdir + nextQdir).normalized; float w = width / Mathf.Sin(Vector3.Angle(direction, pdir) * Mathf.PI / 180.0f); nextVer1 = vertexList[i] - pdir * w * 0.5f; nextVer2 = vertexList[i] + pdir * w * 0.5f; float length1 = (nextVer1 - ver1).magnitude; float length2 = (nextVer2 - ver2).magnitude; if (Mathf.Abs(length1 - length2) < epsilon) { len += (length1 + length2) * 0.5f; meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); meshVertices.Add(nextVer1); meshVertices.Add(nextVer2); meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); } else { int segmentCount = Mathf.CeilToInt(Mathf.Max(Mathf.Atan(Mathf.Abs(length1 - length2) / width) * 180f / Mathf.PI / Mathf.Max(1f, roundedAngle), 1f)); length = (length1 + length2) * 0.5f; float segmentDelta = length / segmentCount; for (int j = 0; j < segmentCount; ++j) { len += segmentDelta; meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); meshVertices.Add(ver1 + direction * length1 * (j + 1) / segmentCount); meshVertices.Add(ver2 + direction * length2 * (j + 1) / segmentCount); meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); } } ver1 = nextVer1; ver2 = nextVer2; } direction = nextDirection; qdir = nextQdir; } // Last vertex if (type == LineType.Splitted) { meshVertices.Add(vertexList[vertexList.Count - 1] - qdir * width * 0.5f); meshVertices.Add(vertexList[vertexList.Count - 1] + qdir * width * 0.5f); meshUvs.Add(new Vector2(1, len + (vertexList[vertexList.Count - 1] - vertexList[vertexList.Count - 2]).magnitude)); meshUvs.Add(new Vector2(0, len + (vertexList[vertexList.Count - 1] - vertexList[vertexList.Count - 2]).magnitude)); } else { len += (vertexList[vertexList.Count - 1] - vertexList[vertexList.Count - 2]).magnitude; meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); meshVertices.Add(vertexList[vertexList.Count - 1] - qdir * width * 0.5f); meshVertices.Add(vertexList[vertexList.Count - 1] + qdir * width * 0.5f); meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); } if (nextCurve != null) { nextCurve.prevCurve = GetComponent <CurveLineRenderer>(); Vector3 lastVertex = vertices[vertices.Count - 1]; Vector3 nextCurveNormal = nextCurve.normal.normalized; float nextCurveWidth = nextCurve.width; Transform nextCurveTransform = nextCurve.transform; Vector3 nextCurveBegin = nextCurve.vertices[0]; Vector3 nextCurveDirection = (nextCurve.vertices[1] - nextCurve.vertices[0]).normalized; Vector3 nextCurveQDir = Vector3.Cross(nextCurveDirection, nextCurveNormal).normalized; //Vector3 position = gameObject.transform.position; Vector3 position = Vector3.zero; Transform transform = gameObject.transform; nextVer1 = nextCurveBegin - nextCurveQDir * nextCurveWidth * 0.5f; nextVer2 = nextCurveBegin + nextCurveQDir * nextCurveWidth * 0.5f; nextVer1 = transform.InverseTransformPoint(nextCurveTransform.TransformPoint(nextVer1)) + position; nextVer2 = transform.InverseTransformPoint(nextCurveTransform.TransformPoint(nextVer2)) + position; len += (nextCurveBegin - lastVertex + nextCurve.transform.position - transform.position).magnitude; meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); meshVertices.Add(nextVer1); meshVertices.Add(nextVer2); meshUvs.Add(new Vector2(1, len)); meshUvs.Add(new Vector2(0, len)); ver1 = nextVer1; ver2 = nextVer2; previousLen = len; } // Build mesh BuildMesh(mesh, meshCollider, meshVertices, meshUvs, meshUvs.Count / 4); if (prevCurve != null && !isCurveConnetionProcessed) { isCurveConnetionProcessed = true; prevCurve.Invalidate(); } return(mesh); }