Esempio n. 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] = RoadMath.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;
                if (!RoadMath.InterceptPoint(
                        v[i + 0].ToXZVector2(), v[i + 2].ToXZVector2(),
                        v[p4].ToXZVector2(), v[p6].ToXZVector2(), out leftIntercept))
                {
                    Debug.LogWarning("Parallel Lines!");
                }

                Vector2 rightIntercept;
                if (!RoadMath.InterceptPoint(
                        v[i + 1].ToXZVector2(), v[i + 3].ToXZVector2(),
                        v[p5].ToXZVector2(), v[p7].ToXZVector2(), out rightIntercept))
                {
                    Debug.LogWarning("Parallel lines!");
                }

                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]  = RoadUtils.GroundHeight(v[i]) + new Vector3(0f, groundOffset, 0f);
            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
    }
Esempio n. 2
0
    public void OnSceneGUI()
    {
        if (road.acceptInput == false)
        {
            return;
        }

        Event e = Event.current;

        if (e.type == EventType.ValidateCommand)
        {
            road.Refresh();
            SceneView.RepaintAll();
        }

        if (e.isKey && (e.keyCode == KeyCode.Escape || e.keyCode == KeyCode.Return))
        {
            road.acceptInput = false;
            SceneView.RepaintAll();
        }

        // Existing point handles
        DrawHandleGUI(road.points);

        // TODO -- figure out why Handles.PositionHandle is sooo slow when panning

        if (!e.alt)
        {
            for (int i = 0; i < road.points.Count; i++)
            {
                tp             = road.points[i];
                road.points[i] = Handles.PositionHandle(road.points[i], Quaternion.identity);

                if (tp != road.points[i])
                {
                    Vector3 p = RoadUtils.GroundHeight(road.points[i]);
                    road.points[i] = p;
                    road.Refresh();
                }
            }
        }

        if (earlyOut)
        {
            return;
        }

        // New point placement from here down

        int controlID = GUIUtility.GetControlID(FocusType.Passive);

        HandleUtility.AddDefaultControl(controlID);

        if (e.modifiers != 0 || Tools.current != Tool.Move)
        {
            if (e.type == EventType.MouseUp && e.button == 0 && Tools.current != Tool.Move && e.modifiers == 0)
            {
                FindSceneView().ShowNotification(new GUIContent("Tool must be set to 'Move' to place points!", ""));
                SceneView.RepaintAll();
            }
            return;
        }

        if ((e.type == EventType.MouseDown || e.type == EventType.MouseDrag) && e.button == 0)
        {
            Ray        ray    = HandleUtility.GUIPointToWorldRay(e.mousePosition);
            RaycastHit ground = new RaycastHit();

            if (Physics.Raycast(ray.origin, ray.direction, out ground))
            {
                groundPoint = ground.point;
            }
        }

        // Listen for mouse input
        if (e.type == EventType.MouseUp && e.button == 0)
        {
            Ray        ray    = HandleUtility.GUIPointToWorldRay(e.mousePosition);
            RaycastHit ground = new RaycastHit();

            if (Physics.Raycast(ray.origin, ray.direction, out ground))
            {
                groundPoint = ground.point;
                AddPoint(groundPoint);
            }
        }
    }