private void TryProcessFriends() { var updated = false; Tuple <int, int[]> item; while (_loadedFriendsQueue.TryDequeue(out item)) { updated = true; var userId = item.Item1; var friendIds = item.Item2; var user = _users[userId]; user.AllFriends.UnionWith(friendIds); foreach (var friendId in friendIds) { _users[friendId].AllFriends.Add(userId); if (!_users[friendId].Friends.Contains(userId)) { user.Friends.Add(friendId); } } } if (!updated) { return; } var nodes = _nodesBuffer.GetData(); var edgesIndices = new int[_users.Sum(i => i.AllFriends.Count)]; var edges = new EdgeVertex[_users.Sum(i => i.Friends.Count)]; for (int i = 0, j = 0, k = 0; i < _users.Length; i++) { nodes[i].EdgesStart = j; nodes[i].EdgesEnd = j + _users[i].AllFriends.Count; foreach (var friendId in _users[i].AllFriends) { edgesIndices[j++] = friendId; } foreach (var friendId in _users[i].Friends) { edges[k++] = new EdgeVertex(i, friendId); } } _nodesBuffer.SetData(nodes); _newNodesBuffer.SetData(nodes); _edgeIndicesBuffer?.Dispose(); _edgesBuffer?.Dispose(); _edgeIndicesBuffer = edgesIndices.Length == 0 ? null : Buffer.Structured.New(GraphicsDevice, edgesIndices); _edgesBuffer = edges.Length == 0 ? null : Buffer.Structured.New(GraphicsDevice, edges.ToArray()); _shader.Parameters["EdgeIndices"].SetResource(_edgeIndicesBuffer); }
private List <int> FindEdgeSubVertices(EdgeVertex p1, EdgeVertex p2, float scaleAmount) { List <int> subEdgeVertices = new List <int>(); subEdgeVertices.Add(p1.listLoc); Vector3 pt1 = p1.transform.position; Vector3 pt2 = p2.transform.position; Vector3 distance = (pt2 - pt1).normalized; for (int i = 1; i < scaleAmount; i++) { Vector3 overlapPos = new Vector3(pt1.x + (1 * distance.x * i), pt1.y + (1 * distance.y * i), pt1.z + (1 * distance.z * i)); Collider[] hitCollider = Physics.OverlapSphere(overlapPos, .25f); foreach (Collider collider in hitCollider) { EdgeVertex tp = collider.gameObject.GetComponent <EdgeVertex>(); if (tp) { subEdgeVertices.Add(tp.listLoc); break; } } } subEdgeVertices.Add(p2.listLoc); return(subEdgeVertices); }
private void GenerateSelectableVertex(Vector3 pos) { GameObject edgePoint = GameObject.CreatePrimitive(PrimitiveType.Sphere); Destroy(edgePoint.GetComponent <SphereCollider>()); EdgeVertex tp = edgePoint.AddComponent <EdgeVertex>(); tp.ptID = "Pt" + _nextPtID; edgePoint.name = tp.ptID; tp.listLoc = _nextPtID; edgePoint.layer = LayerMask.NameToLayer("Player"); // if (Array.Exists(_initTPLocs, i => _nextPtID == i )) // _initTPs.Add(_nextPtID, tp); _nextPtID++; Renderer rend = edgePoint.GetComponent <Renderer>(); rend.material.shader = Shader.Find("Unlit/ColorZAlways"); rend.material.renderQueue = 2350; rend.enabled = false; SphereCollider sphereCollider = edgePoint.AddComponent <SphereCollider>(); sphereCollider.radius = .75f; edgePoint.transform.position = pos; edgePoint.transform.localScale = new Vector3(0.25f, 0.25f, 0.25f); edgePoint.transform.parent = verticesHolder.transform; _points.Add(pos); }
internal bool HasEdgeWith(Vertex vb, out EdgeVertex newEdge) { foreach (var edge in Edges) { if (edge.A == this && edge.B == vb || edge.B == this && edge.A == vb) { newEdge = edge; return(true); } } newEdge = null; return(false); }
private void EdgeUtil(Graph graph, EdgeVertex tp1, EdgeVertex tp2, float scaleAmount) { var edgeSubVerts = FindEdgeSubVertices(tp1, tp2, scaleAmount); //FormEdgesFromSubVerts for (int i = 0; i < edgeSubVerts.Count - 1; i++) { graph.addEdge(edgeSubVerts[i], edgeSubVerts[i + 1]); } //TODO: figure out early exit for no edge being drawn }
/// <summary> /// Computes edge adjacency for the whole mesh and stores it in the appropriate dictionaries. /// </summary> public void ComputeEdgeAdjacency() { foreach (MeshEdge edge in mesh.Edges) { foreach (MeshVertex adjacent in edge.AdjacentVertices()) { if (!EdgeVertex.ContainsKey(edge.Index)) { EdgeVertex.Add(edge.Index, new List <int>() { adjacent.Index }); } else { EdgeVertex[edge.Index].Add(adjacent.Index); } } foreach (MeshFace adjacent in edge.AdjacentFaces()) { if (!EdgeFace.ContainsKey(edge.Index)) { EdgeFace.Add(edge.Index, new List <int>() { adjacent.Index }); } else { EdgeFace[edge.Index].Add(adjacent.Index); } } foreach (MeshEdge adjacent in edge.AdjacentEdges()) { if (!EdgeEdge.ContainsKey(edge.Index)) { EdgeEdge.Add(edge.Index, new List <int>() { adjacent.Index }); } else { EdgeEdge[edge.Index].Add(adjacent.Index); } } } }
private void OnMouseDown() { if (GameManager.SharedInstance.PlayMode) { return; } //Debug.Log(ptID); AudioManager audioManager = GameManager.SharedInstance.AudioManager; if (!_activePoint) { GameObject.Find("Robonaut").GetComponentInChildren <Animator>().SetBool("Painting", true); isActivePoint = true; _activePoint = this; CleanAdjacentPointLists(); ToggleSelectablePoints(false); coroutine = PreviewSelectablePoints(); StartCoroutine(coroutine); _rend.enabled = true; audioManager.PlaySoundEffect(audioManager.VertexClick); } else if (_isActiveSelectable) { GameObject.Find("Robonaut").GetComponentInChildren <Animator>().SetBool("Painting", false); GameManager.SharedInstance.levelManager.GenerateEdge(_activePoint, this); _activePoint.isActivePoint = false; _activePoint._rend.enabled = false; StopCoroutine(_activePoint.coroutine); ToggleSelectablePoints(true); _activePoint._onPoint = false; _activePoint = null; _rend.enabled = true; audioManager.PlaySoundEffect(audioManager.VertexClick); } }
private void FillAdjacentList(List <EdgeVertex> adjacentList, Vector3 axis) { Vector3 tpPos = transform.position; //Check for adjacent points in positive axis dir Vector3 overlapPos = new Vector3(tpPos.x + axis.x, tpPos.y + axis.y, tpPos.z + axis.z); Collider[] hitCollider = Physics.OverlapSphere(overlapPos, .25f); int i = 1; while (hitCollider.Length > 0) { bool foundTp = false; foreach (Collider collider in hitCollider) { EdgeVertex tp = collider.gameObject.GetComponent <EdgeVertex>(); if (tp) { adjacentList.Add(tp); foundTp = true; break; } } if (!foundTp) { break; } i++; overlapPos = new Vector3(tpPos.x + axis.x * i, tpPos.y + axis.y * i, tpPos.z + axis.z * i); hitCollider = Physics.OverlapSphere(overlapPos, .25f); } //Check for adjacent points in negative axis dir overlapPos = new Vector3(tpPos.x - axis.x, tpPos.y - axis.y, tpPos.z - axis.z); hitCollider = Physics.OverlapSphere(overlapPos, .25f); i = 1; while (hitCollider.Length > 0) { bool foundTp = false; foreach (Collider collider in hitCollider) { EdgeVertex tp = collider.gameObject.GetComponent <EdgeVertex>(); if (tp) { adjacentList.Add(tp); foundTp = true; break; } } if (!foundTp) { break; } i++; overlapPos = new Vector3(tpPos.x - axis.x * i, tpPos.y - axis.y * i, tpPos.z - axis.z * i); hitCollider = Physics.OverlapSphere(overlapPos, .25f); } }
public Edge(int id, T a, T b, EdgeVertex baseEdge) : this(id, a, b) { BaseEdge = baseEdge; }
private void UpdateMeshData() { Debug.Log("UpdateMeshData"); var watch = new System.Diagnostics.Stopwatch(); watch.Start(); var meshTriangles = UnityMesh.triangles; var meshVertices = UnityMesh.vertices; var meshNormal = UnityMesh.normals; var meshUV0 = UnityMesh.uv; var meshUV1 = UnityMesh.uv2; HasNormals = meshNormal != null && meshNormal.Length > 0; HasUV1 = meshUV0 != null && meshUV0.Length > 0; HasUV2 = meshUV1 != null && meshUV1.Length > 0; //Construct Surface int trisID; Vertex curVertex; Triangle curTriangle = null; for (int i = 0; i < meshTriangles.Length; i++) { if (watch.ElapsedMilliseconds >= 10 * 1000) { break; } int vid = meshTriangles[i]; trisID = i % 3; if (trisID == 0) { Triangles.Add(new Triangle(Triangles.Count)); curTriangle = Triangles[Triangles.Count - 1]; } int vertexID; if (!VertexPositionLookup.TryGetValue(meshVertices[vid], out curVertex)) { vertexID = Vertecies.Count; curVertex = new Vertex(Vertecies.Count, meshVertices[vid]); Vertecies.Add(curVertex); VertexPositionLookup.Add(curVertex.Position, curVertex); } int normId; int uv1Id; int uv2Id; if (HasNormals) { if (!VertexHasNormal(curVertex, meshNormal[vid], out normId)) { normId = AddNormal(curVertex, meshNormal[vid]); } curTriangle.Normals[trisID] = Normals[normId]; } if (HasUV1) { if (!VertexHasUV1(curVertex, meshUV0[vid], out uv1Id)) { uv1Id = AddUV1(curVertex, meshUV0[vid]); } curTriangle.UV1s[trisID] = UV1[uv1Id]; } if (HasUV2) { if (!VertexHasUV2(curVertex, meshUV1[vid], out uv2Id)) { uv2Id = AddUV2(curVertex, meshUV1[vid]); } curTriangle.UV2s[trisID] = UV2[uv2Id]; } curTriangle.Vertecies[trisID] = curVertex; } Debug.Log("Construct Surface: " + watch.ElapsedMilliseconds.ToString() + "ms"); var elapsed = watch.ElapsedMilliseconds; //ConstructEdges Triangle triangle; for (int i = 0; i < Triangles.Count; i++) { triangle = Triangles[i]; for (int e = 0; e < 3; e++) { //Search for Surface Edges var va = triangle.Vertecies[e]; var vb = triangle.Vertecies[(e + 1) % 3]; EdgeVertex newEdge; if (!va.HasEdgeWith(vb, out newEdge)) { newEdge = new EdgeVertex(Edges.Count, va, vb); Edges.Add(newEdge); } newEdge.Triangles.Add(triangle); triangle.Edges.Add(newEdge); va.Edges.Add(newEdge); vb.Edges.Add(newEdge); //Search for Normal Edges if (HasNormals) { var na = triangle.Normals[e]; var nb = triangle.Normals[(e + 1) % 3]; Edge <Vertex3> edgen; if (!va.HasNormalEdgeWith(na, nb, out edgen)) { edgen = new Edge <Vertex3>(Edges.Count, na, nb, newEdge); newEdge.NormalEdges.Add(edgen); NormalEdges.Add(edgen); } edgen.Triangles.Add(triangle); triangle.NormalEdges.Add(edgen); va.NormalEdges.Add(edgen); vb.NormalEdges.Add(edgen); } //Search for UV1 Edges if (HasUV1) { var uva = triangle.UV1s[e]; var uvb = triangle.UV1s[(e + 1) % 3]; Edge <Vertex2> edgeuv; if (!va.HasUV1EdgeWith(uva, uvb, out edgeuv)) { edgeuv = new Edge <Vertex2>(Edges.Count, uva, uvb, newEdge); newEdge.UV1Edges.Add(edgeuv); UV1Edges.Add(edgeuv); } edgeuv.Triangles.Add(triangle); triangle.UV1Edges.Add(edgeuv); va.UV1Edges.Add(edgeuv); vb.UV1Edges.Add(edgeuv); } //Search for UV2 Edges if (HasUV2) { var uva = triangle.UV2s[e]; var uvb = triangle.UV2s[(e + 1) % 3]; Edge <Vertex2> edgeuv; if (!va.HasUV2EdgeWith(uva, uvb, out edgeuv)) { edgeuv = new Edge <Vertex2>(Edges.Count, uva, uvb, newEdge); newEdge.UV2Edges.Add(edgeuv); UV2Edges.Add(edgeuv); } edgeuv.Triangles.Add(triangle); triangle.UV2Edges.Add(edgeuv); va.UV2Edges.Add(edgeuv); vb.UV2Edges.Add(edgeuv); } } } Debug.Log("ConstructEdges: " + (watch.ElapsedMilliseconds - elapsed).ToString() + "ms"); elapsed = watch.ElapsedMilliseconds; //Find Boundary Edges foreach (var edge in Edges) { if (edge.Triangles.Count != 1) { continue; } edge.IsBoundary = true; BoarderEdges.Add(edge); } foreach (var edge in NormalEdges) { if (edge.Triangles.Count != 1) { continue; } edge.IsBoundary = true; NormalBoarderEdges.Add(edge); NormalBoarderVertexEdges.Add(edge.BaseEdge); } foreach (var edge in UV1Edges) { if (edge.Triangles.Count != 1) { continue; } edge.IsBoundary = true; UV1BoarderEdges.Add(edge); UV1BoarderVertexEdges.Add(edge.BaseEdge); } foreach (var edge in UV2Edges) { if (edge.Triangles.Count != 1) { continue; } edge.IsBoundary = true; UV2BoarderEdges.Add(edge); UV2BoarderVertexEdges.Add(edge.BaseEdge); } Debug.Log("Find Boundary Edges: " + (watch.ElapsedMilliseconds - elapsed).ToString() + "ms"); elapsed = watch.ElapsedMilliseconds; Debug.Log("Total: " + watch.ElapsedMilliseconds.ToString() + "ms"); Debug.Log("---------------------------"); }
//TODO: properly use the addEdge function to make use of the bool and avoid creating edge game object public void GenerateEdge(EdgeVertex tp1, EdgeVertex tp2) { Vector3 p1 = tp1.transform.position; Vector3 p2 = tp2.transform.position; int pt1ID = tp1.listLoc; int pt2ID = tp2.listLoc; float xRot = 90; float yRot = 0; //use the mid point of the two points to position the prefab since the anchor is the center of the quad aka the //center of our line Vector3 midPoint = Vector3.zero; midPoint = (p1 + p2) / 2; //To make quads always visible to the (isometric) camera there are some specific rotation angles needed. When a //line is moving only along the x-axis it's y rot needs to be 90 and when a line is moving along the y-axis only //it's y-rot is 90 and it's x-rot is 180. These will be standard values since (for now) we're not rotating the //camera. Vector3 distance = p2 - p1; float scaleAmount; bool xAxisEdge = false, yAxisEdge = false, zAxisEdge = false; if (Mathf.Abs(distance.x) > 0) { yRot = 90; scaleAmount = Mathf.Abs(distance.x); xAxisEdge = true; } else if (Mathf.Abs(distance.y) > 0) { xRot = 180; yRot = 90; scaleAmount = Mathf.Abs(distance.y); yAxisEdge = true; } else { scaleAmount = Mathf.Abs(distance.z); zAxisEdge = true; } string xGraphKey = p1.x.ToString(); string yGraphKey = p1.y.ToString(); string zGraphKey = p1.z.ToString(); if (xAxisEdge) { EdgeUtil(_yGraphs[yGraphKey], tp1, tp2, scaleAmount); EdgeUtil(_zGraphs[zGraphKey], tp1, tp2, scaleAmount); FaceGenUtil(_yGraphs[yGraphKey]); FaceGenUtil(_zGraphs[zGraphKey]); } else if (yAxisEdge) { EdgeUtil(_xGraphs[xGraphKey], tp1, tp2, scaleAmount); EdgeUtil(_zGraphs[zGraphKey], tp1, tp2, scaleAmount); FaceGenUtil(_xGraphs[xGraphKey]); FaceGenUtil(_zGraphs[zGraphKey]); } else if (zAxisEdge) { EdgeUtil(_xGraphs[xGraphKey], tp1, tp2, scaleAmount); EdgeUtil(_yGraphs[yGraphKey], tp1, tp2, scaleAmount); FaceGenUtil(_xGraphs[xGraphKey]); FaceGenUtil(_yGraphs[yGraphKey]); } /*TODO: optimization idea; check overlap sphere for midpoint, if edge already present (e.g. larger overlapping edge) * or just the same edge, don't instantiate*/ GameObject line = Instantiate(linePrefab, midPoint, Quaternion.Euler(xRot, yRot, 0)); Transform lineTransform = line.transform; lineTransform.parent = gameObject.transform; var localScale = lineTransform.localScale; lineTransform.localScale = new Vector3(localScale.x, localScale.y * scaleAmount, localScale.z); }