예제 #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);
    }
예제 #2
0
    void MakeGrid()
    {
        var colliders = _voids
                        .GetComponentsInChildren <MeshCollider>()
                        .ToArray();

        var voxelSize = float.Parse(_voxelSize);

        _grid = Grid3d.MakeGridWithVoids(colliders, voxelSize);
        Analysis();
        MakeVoxelMesh();
        ToggleVoids();
    }
예제 #3
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);
        }
    }
예제 #4
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 };
    }