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 }
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); } } }