void Start() { // Disable the pointer graphic (until the user holds down on the touchpad) Pointer.enabled = false; // Standard plane mesh used for "fade out" graphic when you teleport // This way you don't need to supply a simple plane mesh in the inspector PlaneMesh = new Mesh(); Vector3[] verts = new Vector3[] { new Vector3(-1, -1, 0), new Vector3(-1, 1, 0), new Vector3(1, 1, 0), new Vector3(1, -1, 0) }; int[] elts = new int[] { 0, 1, 2, 0, 2, 3 }; PlaneMesh.vertices = verts; PlaneMesh.triangles = elts; PlaneMesh.RecalculateBounds(); // Set some standard variables MaterialFadeID = Shader.PropertyToID("_Fade"); EnabledAnimatorID = Animator.StringToHash("Enabled"); RoomBorder = GetComponent<BorderRenderer>(); Vector3 p0, p1, p2, p3; if (GetChaperoneBounds(out p0, out p1, out p2, out p3)) { BorderPointSet p = new BorderPointSet(new Vector3[] { p0, p1, p2, p3, p0 }); RoomBorder.Points = new BorderPointSet[] { p }; } RoomBorder.enabled = false; }
/// \brief Given some mesh m, calculates a number of polylines that border the mesh. This may return more than /// one polyline if, for example, the mesh has holes in it or if the mesh is separated in two pieces. /// /// \param m input mesh /// \returns array of cyclic polylines private static BorderPointSet[] FindBorderEdges(Mesh m) { // First, get together all the edges in the mesh and find out // how many times each edge is used. Edges that are only used // once are border edges. // Key: edges (note that because of how the hashcode / equals() is set up, two equivalent edges will effectively // be equal) // Value: How many times this edge shows up in the mesh. Any keys with a value of 1 are border edges. Dictionary<Edge, int> edges = new Dictionary<Edge, int>(); for (int x = 0; x < m.triangles.Length / 3; x++) { int p1 = m.triangles[x * 3]; int p2 = m.triangles[x * 3 + 1]; int p3 = m.triangles[x * 3 + 2]; Edge[] e = new Edge[3]; e[0] = new Edge(p1, p2); e[1] = new Edge(p2, p3); e[2] = new Edge(p3, p1); foreach (Edge d in e) { int curval; edges.TryGetValue(d, out curval); // 0 if nonexistant edges[d] = curval + 1; } } // Next, consolidate all of the border edges into one List<Edge> List<Edge> border = new List<Edge>(); foreach (KeyValuePair<Edge, int> p in edges) { if (p.Value == 1) // border edge == edge only used once. border.Add(p.Key); } // Perform the following routine: // 1. Pick any unvisited edge segment [v_start,v_next] and add these vertices to the polygon loop. // 2. Find the unvisited edge segment [v_i,v_j] that has either v_i = v_next or v_j = v_next and add the // other vertex (the one not equal to v_next) to the polygon loop. Reset v_next as this newly added vertex, // mark the edge as visited and continue from 2. // 3. Traversal is done when we get back to v_start. // Source: http://stackoverflow.com/questions/14108553/get-border-edges-of-mesh-in-winding-order bool[] visited = new bool[border.Count]; bool finished = false; int cur_index = 0; List<Vector3[]> ret = new List<Vector3[]>(); while(!finished) { int[] raw = FindPolylineFromEdges(cur_index, visited, border); Vector3[] fmt = new Vector3[raw.Length]; for (int x = 0; x < raw.Length; x++) fmt[x] = m.vertices[raw[x]]; ret.Add(fmt); finished = true; for (int x=0;x<visited.Length;x++) { if (!visited[x]) { cur_index = x; finished = false; break; } } } BorderPointSet[] ret_set = new BorderPointSet[ret.Count]; for (int x = 0; x < ret.Count; x++) { ret_set[x] = new BorderPointSet(ret[x]); } return ret_set; }