Example #1
0
    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);
    }
Example #2
0
    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);
        }
    }
Example #3
0
    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);
        }
    }
Example #4
0
    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);
        }
    }
Example #5
0
    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 };
    }
Example #6
0
    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;
        }
    }