void MakeGrid() { var colliders = _voids .GetComponentsInChildren <MeshCollider>() .ToArray(); var voxelSize = float.Parse(_voxelSize); _grid = Grid3d.MakeGridWithVoids(colliders, voxelSize, true); var faces = _grid.GetFaces().Where(f => f.IsActive); var graphEdges = faces.Select(f => new TaggedEdge <Voxel, Face>(f.Voxels[0], f.Voxels[1], f)); var graph = graphEdges.ToAdjacencyGraph <Voxel, TaggedEdge <Voxel, Face> >(); var voxels = _grid.GetVoxels().Where(v => v.IsActive); var start = voxels.First(); var end = voxels.ElementAt(100); var flow = graph.MaximumFlowEdmondsKarp(_ => 1, start, end, out var predecessors, (s, e) => new TaggedEdge <Voxel, Face>(s, e, null)); var current = end; _flowPath = new List <Voxel>(); _flowPath.Add(current); while (predecessors(current, out var next)) { current = next.GetOtherVertex(current); _flowPath.Add(current); } print(flow); }
void MakeGrid() { var bounds = _voids .GetComponentsInChildren <MeshCollider>() .Select(c => c.bounds) .ToArray(); var voxelSize = float.Parse(_voxelSize); _grid = Grid3d.MakeGridWithBounds(bounds, voxelSize); // shortest path to test if connectivity is working var faces = _grid.GetFaces().Where(f => f.IsActive).ToList(); var graphEdges = faces.Select(f => new TaggedEdge <Voxel, Face>(f.Voxels[0], f.Voxels[1], f)); var graph = graphEdges.ToUndirectedGraph <Voxel, TaggedEdge <Voxel, Face> >(); var start = _grid.GetVoxels().ElementAt(2); var end = _grid.GetVoxels().ElementAt(250); var shortest = graph.ShortestPathsDijkstra(_ => 1, start); shortest(end, out var path); var current = start; _flowPath = new List <Voxel>(); _flowPath.Add(current); foreach (var face in path) { current = face.GetOtherVertex(current); _flowPath.Add(current); } }
void MakeGrid() { // create grid with voids var colliders = _voids .GetComponentsInChildren <MeshCollider>() .ToArray(); _grid = new Grid3d(colliders, voxelSize); //sorting the Voxel var faces = _grid.GetFaces().Where(f => f.IsActive); var graphFaces = faces.Select(e => new TaggedEdge <Voxel, Face>(e.Voxels[0], e.Voxels[1], e)); var graphVoxel = graphFaces.ToUndirectedGraph <Voxel, TaggedEdge <Voxel, Face> >(); var startVoxel = _grid.GetVoxels().Where(v => Vector3.Distance(v.Center, Vector3.zero) < 1.5f).First(); var shortestGrow = QuickGraph.Algorithms.AlgorithmExtensions.ShortestPathsDijkstra(graphVoxel, e => 1.0, startVoxel); linkFaces = faces.ToList(); //foreach (var botomFaces in _grid.GetFaces().Where(f => f.Index.y == 0 && f.Direction == Axis.Y)) linkFaces.Add(botomFaces); foreach (var voxel in _grid.GetVoxels().Where(v => v.IsActive)) { IEnumerable <TaggedEdge <Voxel, Face> > path; if (shortestGrow(voxel, out path)) { voxel.Order = path.Count() + UnityEngine.Random.value * 0.9f; } activeVoxels.Add(voxel); voxel.IsActive = false; } activeVoxels = activeVoxels.OrderBy(v => v.Order).ToList(); for (int i = 0; i < _grid.GetFaces().Max(f => f.Index.z) / 2; i++) { startFaces.Add(_grid.GetFaces().Where(f => f.Index.y == 0 && f.Index.x == 0 && f.Index.z == i * 2 && f.Direction == Axis.Y).First()); startFaces.Add(_grid.GetFaces().Where(f => f.Index.y == 0 && f.Index.x == 15 && f.Index.z == i * 2 && f.Direction == Axis.Y).First()); } foreach (var sf in startFaces) { var stack = Instantiate(stackPrefab, sf.Center, Quaternion.identity); _stackList.Add(stack); } }
IEnumerator GrowVoxelsAnimation() { float size = float.Parse(_voxelSize); var voids = _voids.GetComponentsInChildren <MeshCollider>(); _grid = Grid3d.MakeGridWithVoids(voids, size); ToggleVoids(false); _sequence.Clear(); foreach (var voxel in _grid.GetFaces().Where(v => v.IsSkin)) { _sequence.Add(voxel); yield return(null); } }
void MakeGrid() { // create grid with voids var colliders = _voids .GetComponentsInChildren <MeshCollider>() .ToArray(); var voxelSize = float.Parse(_voxelSize); _grid = Grid3d.MakeGridWithVoids(colliders, voxelSize); // select edges of boundary faces var edges = _grid.GetEdges().Where(e => e.ClimbableFaces.Length == 2); // create graph from edges var graphEdges = edges.Select(e => new TaggedEdge <Face, Edge>(e.ClimbableFaces[0], e.ClimbableFaces[1], e)); var graph = graphEdges.ToUndirectedGraph <Face, TaggedEdge <Face, Edge> >(); // start face for shortest path var start = _grid.GetFaces().Where(f => f.IsSkin).Skip(10).First(); // calculate shortest path from start face to all boundary faces var shortest = graph.ShortestPathsDijkstra(e => 1.0, start); // select an end face to draw one specific path var end = _grid.GetFaces().Where(f => f.IsSkin).Skip(200).First(); shortest(end, out var endPath); // unsorted distinct faces of the path from start to end faces var endPathFaces = new HashSet <Face>(endPath.SelectMany(e => new[] { e.Source, e.Target })); // create a mesh face for every outer face colored based on the path length (except a solid yellow path to end face) var faceMeshes = new List <CombineInstance>(); foreach (var face in _grid.GetFaces().Where(f => f.IsSkin)) { float t = 1; if (shortest(face, out var path)) { t = path.Count() * 0.04f; t = Mathf.Clamp01(t); } Mesh faceMesh; // paint face yellow if its part of the start-end path, gradient color for other faces if (endPathFaces.Contains(face)) { faceMesh = Drawing.MakeFace(face.Center, face.Direction, _grid.VoxelSize, 0, 1); } else { faceMesh = Drawing.MakeFace(face.Center, face.Direction, _grid.VoxelSize, t); } faceMeshes.Add(new CombineInstance() { mesh = faceMesh }); } var mesh = new Mesh() { indexFormat = UnityEngine.Rendering.IndexFormat.UInt32 }; mesh.CombineMeshes(faceMeshes.ToArray(), true, false, false); Mesh pathMesh = new Mesh(); // draw a polyline for the start-end path { if (shortest(end, out var path)) { float offset = 0.1f; var vertices = new List <Vector3>(); var current = start; vertices.Add(current.Center + current.Normal * offset); foreach (var edge in path) { vertices.Add(edge.Tag.Center + edge.Tag.Normal * offset); current = edge.GetOtherVertex(current); vertices.Add(current.Center + current.Normal * offset); } pathMesh.SetVertices(vertices); pathMesh.subMeshCount = 2; pathMesh.SetIndices(Enumerable.Range(0, vertices.Count).ToArray(), MeshTopology.LineStrip, 1); } } _meshes = new[] { mesh, pathMesh }; }
void Update() { if (_grid == null) { return; } foreach (var face in _grid.GetFaces()) { Debug.DrawRay(face.Center, face.Normal * 0.2f, Color.white); } if (Input.GetKeyDown(KeyCode.P)) { MainController._togglePath = !MainController._togglePath; } if (MainController._togglePath) { if (allPaths != null) { foreach (var path in allPaths) { if (path != null) { for (int i = 0; i < path.Count - 1; i++) { Drawing.DrawRectangularBar(path[i], path[i + 1], 0.02f, 1); } } } } } if (Input.GetKeyDown(KeyCode.M)) { MakeMesh(); } if (Input.GetKey(KeyCode.E)) { MakeEdge(); } if (Input.GetKeyDown(KeyCode.Return)) // move to raycasted voxel { StartCoroutine(MoveToRaycastVoxel()); } if (Input.GetKeyDown(KeyCode.Space)) { Build(); } if (MainController._toggleBuildMode) { RaycastSelect(); } if (Input.GetKeyDown(KeyCode.A)) { MainController._toggleMesh = !MainController._toggleMesh; this.GetComponent <MeshRenderer>().enabled = MainController._toggleMesh; } }