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();
        }
    }
Exemple #2
0
    /**
     * 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);
    }