Exemple #1
0
    public void Refresh()
    {
        if (points.Count < 2)
        {
            return;
        }

        transform.localScale = Vector3.one;

        if (!gameObject.GetComponent <MeshFilter>())
        {
            gameObject.AddComponent <MeshFilter>();
        }
        else
        {
            if (gameObject.GetComponent <MeshFilter>().sharedMesh != null)
            {
                DestroyImmediate(gameObject.GetComponent <MeshFilter>().sharedMesh);
            }
        }

        if (!gameObject.GetComponent <MeshRenderer>())
        {
            gameObject.AddComponent <MeshRenderer>();
        }

        List <Vector3> v = new List <Vector3>();
        List <int>     t = new List <int>();

        // calculate angles for each line segment, then build out a plane for it
        int tri_index = 0;
        int segments  = connectEnds ? points.Count : points.Count - 1;

        theta = new float[segments];

        for (int i = 0; i < segments; i++)
        {
            Vector2 a = points[i + 0].ToXZVector2();
            Vector2 b = (connectEnds && i == segments - 1) ? points[0].ToXZVector2() : points[i + 1].ToXZVector2();

            bool flip = (a.x > b.x);            // ? theta[i] : -theta[i];

            Vector3 rght = flip ? new Vector3(0, 0, -1) : new Vector3(0, 0, 1);
            Vector3 lft  = flip ? new Vector3(0, 0, 1) : new Vector3(0, 0, -1);

            theta[i] = MathExtensions.AngleRadian(a, b);

            // seg a
            v.Add(points[i] + rght * roadWidth);
            v.Add(points[i] + lft * roadWidth);
            // seg b
            int u = (connectEnds && i == segments - 1) ? 0 : i + 1;
            v.Add(points[u] + rght * roadWidth);
            v.Add(points[u] + lft * roadWidth);

            // apply angular rotation to points
            int l = v.Count - 4;

            v[l + 0] = v[l + 0].RotateAroundPoint(points[i + 0], -theta[i]);
            v[l + 1] = v[l + 1].RotateAroundPoint(points[i + 0], -theta[i]);

            v[l + 2] = v[l + 2].RotateAroundPoint(points[u], -theta[i]);
            v[l + 3] = v[l + 3].RotateAroundPoint(points[u], -theta[i]);

            t.AddRange(new int[6] {
                tri_index + 2,
                tri_index + 1,
                tri_index + 0,

                tri_index + 2,
                tri_index + 3,
                tri_index + 1
            });

            tri_index += 4;
        }

        // join edge vertices
        if (points.Count > 2)
        {
            segments = connectEnds ? v.Count : v.Count - 4;
            for (int i = 0; i < segments; i += 4)
            {
                int p4 = (connectEnds && i == segments - 4) ? 0 : i + 4;
                int p5 = (connectEnds && i == segments - 4) ? 1 : i + 5;
                int p6 = (connectEnds && i == segments - 4) ? 2 : i + 6;
                int p7 = (connectEnds && i == segments - 4) ? 3 : i + 7;

                Vector2 leftIntercept = MathExtensions.InterceptPoint(
                    v[i + 0].ToXZVector2(), v[i + 2].ToXZVector2(),
                    v[p4].ToXZVector2(), v[p6].ToXZVector2());

                Vector2 rightIntercept = MathExtensions.InterceptPoint(
                    v[i + 1].ToXZVector2(), v[i + 3].ToXZVector2(),
                    v[p5].ToXZVector2(), v[p7].ToXZVector2());

                v[i + 2] = leftIntercept.ToVector3();
                v[p4]    = leftIntercept.ToVector3();

                v[i + 3] = rightIntercept.ToVector3();
                v[p5]    = rightIntercept.ToVector3();
            }
        }

        transform.position = Vector3.zero;

        // // center pivot point and set height offset
        Vector3 cen  = v.Average();
        Vector3 diff = cen - transform.position;

        transform.position = cen;

        for (int i = 0; i < v.Count; i++)
        {
            v[i]  = new Vector3(v[i].x, GroundHeight(v[i]) + groundOffset, v[i].z);
            v[i] -= diff;
        }

        Mesh m = new Mesh();

        m.vertices  = v.ToArray();
        m.triangles = t.ToArray();
        m.uv        = CalculateUV(m.vertices);
        m.RecalculateNormals();
        gameObject.GetComponent <MeshFilter>().sharedMesh       = m;
        gameObject.GetComponent <MeshRenderer>().sharedMaterial = mat;
#if UNITY_EDITOR
        Unwrapping.GenerateSecondaryUVSet(gameObject.GetComponent <MeshFilter>().sharedMesh);
#endif
    }