Example #1
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 #2
0
    IEnumerator GrowGrid()
    {
        int count       = 100000;
        int lastFitness = 0;

        while (count-- > 0)
        {
            var skinVoxels = _grid.GetVoxels().Where(v => v.IsSkin).ToList();

            if (skinVoxels.Count == 0)
            {
                break;
            }

            var index     = Random.Range(0, skinVoxels.Count);
            var candidate = skinVoxels[index];

            candidate.IsActive = false;

            int componentCount = _grid.GetConnectedComponents();
            if (componentCount != 1)
            {
                Debug.Log("Tried to remove a voxel that disconnected the structure.");
                candidate.IsActive = true;
                yield return(null);
            }

            int fitness = 0;

            foreach (var voxel in _grid.GetVoxels())
            {
                if (!voxel.IsActive)
                {
                    continue;
                }
                int neighbourCount = voxel.GetFaceNeighbours().Count(n => n.IsActive);

                if (neighbourCount == 2)
                {
                    fitness += 1;
                }
            }

            if (fitness < lastFitness)
            {
                Debug.Log("Fitness decreased.");
                candidate.IsActive = true;
                continue;
            }

            lastFitness = fitness;
            UpdateCenters();
            yield return(new WaitForSeconds(0.001f));
        }
    }
Example #3
0
    void UpdateActiveVoxels()
    {
        _centers.Clear();

        foreach (var voxel in _grid.GetVoxels())
        {
            if (voxel.IsActive)
            {
                _centers.Add(voxel.Center);
            }
        }
    }
Example #4
0
    void Analysis()
    {
        // analysis model
        var model = new Model();

        var corners = _grid.GetCorners()
                      .Where(c => c.GetConnectedVoxels().Any(v => v.IsActive))
                      .Select(c => new FeaCorner(c))
                      .ToList();

        var nodes = corners.Select(c => c.Node).ToArray();

        var elements = _grid.GetVoxels()
                       .Where(b => b.IsActive)
                       .SelectMany(v => MakeTetrahedra(v))
                       .ToArray();

        model.Nodes.Add(nodes);
        model.Elements.Add(elements);

        model.Solve();

        // analysis results
        foreach (var corner in corners)
        {
            var d = corner.Node
                    .GetNodalDisplacement(LoadCase.DefaultLoadCase)
                    .Displacements;

            corner.Displacement = new Vector3((float)d.X, (float)d.Z, (float)d.Y);
            var length = corner.Displacement.magnitude;

            foreach (var voxel in corner.GetConnectedVoxels())
            {
                voxel.Value += length;
            }
        }

        var activeVoxels = _grid.GetVoxels().Where(v => v.IsActive);

        foreach (var voxel in activeVoxels)
        {
            voxel.Value /= voxel.GetCorners().Count();
        }

        var min = activeVoxels.Min(v => v.Value);
        var max = activeVoxels.Max(v => v.Value);

        foreach (var voxel in activeVoxels)
        {
            voxel.Value = Mathf.InverseLerp(min, max, voxel.Value);
        }
    }
Example #5
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 #6
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 #7
0
    void Update()
    {
        if (_grid == null)
        {
            return;
        }

        foreach (var voxel in _grid.GetVoxels())
        {
            Drawing.DrawCube(voxel.Center, _grid.VoxelSize, voxel.Tile);
        }
    }
Example #8
0
    void Start()
    {
        var bounds = new Bounds(new Vector3(0, 5, 0), new Vector3(15, 9, 9));

        _grid = new Grid3d(bounds, 0.8f);

        foreach (var voxel in _grid.GetVoxels())
        {
            voxel.IsActive = true;
        }

        StartCoroutine(GrowGrid());
    }
Example #9
0
    void Update()
    {
        if (_grid == null)
        {
            return;
        }

        foreach (var voxel in _grid.GetVoxels().Where(v => v.IsActive))
        {
            Drawing.DrawCube(voxel.Center, _grid.VoxelSize * 0.9f, 0.8f);
        }

        foreach (var voxel in _flowPath)
        {
            Drawing.DrawCube(voxel.Center, _grid.VoxelSize, 0);
        }
    }