예제 #1
0
    void AStarPath()
    {
        AAPrism s = null, f = null;

        foreach (var item in a)
        {
            item.H      = (item.Centre - finish.transform.position).sqrMagnitude;
            item.parent = null;
            item.state  = NodeState.Untested;
            if (item.bounds.Contains(start.transform.position))
            {
                item.Display(Color.green);
                s = item;
            }
            if (item.bounds.Contains(finish.transform.position))
            {
                item.Display(Color.red);
                f = item;
            }
        }
        if (PathSearch(s, f))
        {
            ColourPath(f);
        }
        else
        {
            Debug.Log("Failed to find path!");
        }
    }
예제 #2
0
 void ColourPath(AAPrism s)
 {
     if (s.parent == null)
     {
         return;
     }
     s.parent.Display(Color.magenta);
     ColourPath(s.parent);
 }
예제 #3
0
        public void AddNeighbour(AAPrism neighbour)
        {
            NeighbourInfo n = new NeighbourInfo(neighbour);

            if (neighbours.Contains(n))
            {
                return;
            }
            neighbours.Add(n);
        }
예제 #4
0
    bool OutOfBounds(AAPrism current)
    {
        bool returnval = false;

        current.Contract(VoxelSize * .1f);
        foreach (var point in current.GetCorners())
        {
            if (!bounds.Contains(point))
            {
                returnval = true;
            }
        }
        current.Expand(VoxelSize * .1f);
        return(returnval);
    }
예제 #5
0
        public void AddNeighbour(AAPrism neighbour, List <Vector3> points)
        {
            Vector3 average = Vector3.zero;

            foreach (var item in points)
            {
                average += item;
            }
            average /= points.Count;
            float         d1 = (Centre - average).sqrMagnitude, d2 = (neighbour.Centre - average).sqrMagnitude;
            NeighbourInfo n = new NeighbourInfo(neighbour, d1 + d2, points);

            if (neighbours.Contains(n))
            {
                return;
            }
            neighbours.Add(n);
        }
예제 #6
0
    bool KnitStep(AAPrism current, Axis axis, float posneg)
    {
        current.Expand(axis, posneg * VoxelSize);
        current.Contract(VoxelSize * .1f);          //This is a little hack to prevent coplanar hits along non-expanding sides
        //we have to make sure to expand again before exiting
        foreach (var point in current.GetCorners()) //check if we hit the outside bounds //TODO only do max and min?
        {
            if (!bounds.Contains(point))
            {
                current.Expand(VoxelSize * .1f);
                current.Contract(axis, posneg * VoxelSize);
                return(false);
            }
        }
        foreach (var item in a)          //check if we hit another prism
        {
            if (item.Equals(current))
            {
                continue;
            }
            if (item.bounds.Intersects(current.bounds))
            {
                current.Expand(VoxelSize * .1f);
                current.Contract(axis, posneg * VoxelSize);
                //log the neighbour relation
                current.AddNeighbour(item);
                item.AddNeighbour(current);
                return(false);
            }
        }
        current.Expand(VoxelSize * .1f);

        if (current.Intersects)          //check if we hit an object
        {
            current.Contract(axis, posneg * VoxelSize);
            return(false);
        }
        else           //no intersections so growth continues, remove all covered seeds
        {
            Bounds b = current.bounds;
            seeds.RemoveAll(item => b.Contains(item.Centre));             //TODO change to just intersection? (can't be full sized)
            return(true);
        }
    }
예제 #7
0
        public List <Vector3> DetermineIntersectionPoints(AAPrism other)
        {
            double         maxDelta = 1e-5;
            List <Vector3> points   = new List <Vector3>();

            Vector3 min = new Vector3(Mathf.Max(bounds.min.x, other.bounds.min.x),
                                      Mathf.Max(bounds.min.y, other.bounds.min.y),
                                      Mathf.Max(bounds.min.z, other.bounds.min.z));
            Vector3 max = new Vector3(Mathf.Min(bounds.max.x, other.bounds.max.x),
                                      Mathf.Min(bounds.max.y, other.bounds.max.y),
                                      Mathf.Min(bounds.max.z, other.bounds.max.z));
            Vector3 diff = max - min;

            //merge points on the zero dist. axes
            float[] xvals = Mathf.Abs(diff.x) < maxDelta ? new[] { min.x } : new[] { min.x, max.x };
            float[] yvals = Mathf.Abs(diff.y) < maxDelta ? new[] { min.y } : new[] { min.y, max.y };
            float[] zvals = Mathf.Abs(diff.z) < maxDelta ? new[] { min.z } : new[] { min.z, max.z };

            if (!bounds.Intersects(other.bounds))              //check no intersection case
            {
                Debug.Log("No intersection");
                //return points;
            }
            foreach (var x in xvals)
            {
                foreach (var y in yvals)
                {
                    foreach (var z in zvals)
                    {
                        points.Add(new Vector3(x, y, z));
                    }
                }
            }

            if (points.Count > 4)              //something is wrong, intersection is > 2 dimensional
            {
                Debug.Log("Prism intersection is box!");
            }

            return(points);
        }
예제 #8
0
 bool PathSearch(AAPrism current, AAPrism finish)
 {
     current.state = NodeState.Closed;
     if (current.Equals(finish))
     {
         return(true);
     }
     foreach (var item in current.neighbours)
     {
         if (item.prism.state == NodeState.Closed)
         {
             continue;
         }
         if (item.prism.state == NodeState.Open)
         {
             if (item.distance < item.prism.G)                  //if the new g is smaller then the old one
             {
                 item.prism.parent = current;
                 item.prism.G      = item.distance;
             }
         }
         else
         {
             item.prism.state  = NodeState.Open;
             item.prism.parent = current;
             item.prism.G      = item.distance;
         }
     }
     current.neighbours.Sort((x, y) => x.prism.F.CompareTo(y.prism.F));
     foreach (var node in current.neighbours.Where(x => x.prism.state != NodeState.Closed))
     {
         if (PathSearch(node.prism, finish))
         {
             return(true);
         }
     }
     return(false);
 }
예제 #9
0
 public NeighbourInfo(AAPrism item)
 {
     prism = item;
 }
예제 #10
0
 public NeighbourInfo(AAPrism item, float dist, List <Vector3> points)
 {
     prism              = item;
     distance           = dist;
     intersectionPoints = points;
 }
예제 #11
0
    List <Vector3> AStarPath(Vector3 s, Vector3 f)
    {
        AAPrism        startPrism = null, endPrism = null;
        List <NavNode> list = new List <NavNode>(navNodes); //copy the list so we can modify it non-destructively

        foreach (var prism in a)                            //find the containing prism for start and finish
        {
            if (prism.bounds.Contains(s))                   //TODO optimize with sort and end loop
            {
                prism.Display(Color.green);
                startPrism = prism;
            }
            if (prism.bounds.Contains(f))
            {
                prism.Display(Color.red);
                endPrism = prism;
            }
        }
        //TODO add nullchecking on prisms to see if off grid
        if (startPrism == endPrism)          //if they are in the same prism then we can travel direct
        {
            return(new List <Vector3> {
                s, f
            });
        }
        NavNode startNode = new NavNode(s);         //add start and finish to list
        NavNode endNode   = new NavNode(f);

        list.Add(startNode);
        list.Add(endNode);
        foreach (var location in startPrism.GetAllPoints())         //update neighbours
        {
            NavNode node = getNodeAt(list, location);
            node.AddNeighbour(startNode);
            startNode.AddNeighbour(node);
        }
        foreach (var location in endPrism.GetAllPoints())
        {
            NavNode node = getNodeAt(list, location);
            node.AddNeighbour(endNode);
            endNode.AddNeighbour(node);
        }
        foreach (var item in list)                                         //prepare to pathfind
        {
            item.H      = (item.position - endNode.position).sqrMagnitude; //TODO use regular mag to stop exponent growth?
            item.parent = null;
            item.state  = NodeState.Untested;
        }
        List <Vector3> path = new List <Vector3>();

        if (PathSearch(startNode, endNode))          //pathfind
        {
            Debug.Log("Path found!");
            path = ReturnPath(endNode);
            for (int i = 0; i < path.Count - 1; i++)
            {
                DebugExtension.DebugPoint(path[i], Color.magenta, .5f);
                Debug.DrawLine(path[i], path[i + 1], Color.cyan);
            }
            SmoothPath(path);
            for (int i = 0; i < path.Count - 1; i++)
            {
                DebugExtension.DebugPoint(path[i], Color.magenta, .5f);
                Debug.DrawLine(path[i], path[i + 1], Color.yellow);
            }
        }
        else
        {
            Debug.Log("Failed to find path!");
        }
        return(path);
    }
예제 #12
0
    IEnumerator Knit()
    {
        //choose voxel and start growing; when edge hit, stop that edge
        Debug.Log("Beginning knit");
        while (seeds.Count > 0)
        {
            Debug.Log("Seeds Remaining: " + seeds.Count);
            bool[]  growing = new[] { true, true, true, true, true, true };            //+x, +y +z -x, -y -z
            AAPrism current = seeds[rand.Next(0, seeds.Count - 1)];
            seeds.Remove(current);
            a.Add(current);
            current.isSeed = false;
            if (delay != 0)
            {
                foreach (var seed in seeds)
                {
                    seed.Display(delay * 10f);
                }
            }

            while (growing[0] || growing[1] || growing[2] || growing[3] || growing[4] || growing[5])
            {
                if (growing[0])                  //step x
                {
                    growing[0] = KnitStep(current, Axis.x, 1);
                    if (delay != 0)
                    {
                        yield return(new WaitForSeconds(delay));
                    }
                }
                if (growing[1])                  //step y
                {
                    growing[1] = KnitStep(current, Axis.y, 1);
                    if (delay != 0)
                    {
                        yield return(new WaitForSeconds(delay));
                    }
                }
                if (growing[2])                  //step z
                {
                    growing[2] = KnitStep(current, Axis.z, 1);
                    if (delay != 0)
                    {
                        yield return(new WaitForSeconds(delay));
                    }
                }
                if (growing[3])                  //step -x
                {
                    growing[3] = KnitStep(current, Axis.x, -1);
                    if (delay != 0)
                    {
                        yield return(new WaitForSeconds(delay));
                    }
                }
                if (growing[4])                  //step -y
                {
                    growing[4] = KnitStep(current, Axis.y, -1);
                    if (delay != 0)
                    {
                        yield return(new WaitForSeconds(delay));
                    }
                }
                if (growing[5])                  //step -z
                {
                    growing[5] = KnitStep(current, Axis.z, -1);
                    if (delay != 0)
                    {
                        yield return(new WaitForSeconds(delay));
                    }
                }
            }
            if (delay != 0)
            {
                yield return(new WaitForSeconds(delay));
            }
        }
        foreach (var prism in a)
        {
            foreach (var neighbour in prism.neighbours)            //calculate neighbour intersection points
            {
                neighbour.AddIntersectionPoints(prism.DetermineIntersectionPoints(neighbour.prism));
            }
        }

        foreach (var prism in a)          //set up navnodes
        {
            prism.drawn = false;
            List <NavNode> nodes = new List <NavNode>();
            foreach (var point in prism.GetAllPoints())
            {
                nodes.Add(new NavNode(point));
            }
            for (int i = 0; i < nodes.Count - 1; i++)
            {
                for (int j = i + 1; j < nodes.Count; j++)
                {
                    nodes[i].AddNeighbour(nodes[j]);
                    nodes[j].AddNeighbour(nodes[i]);
                }
            }
            foreach (var item in nodes)
            {
                //if the node is already in the main list, just add neighbours
                if (navNodes.Any((x) => item.position == x.position))
                {
                    int index = navNodes.FindIndex((x) => item.position == x.position);
                    foreach (var neighbour in item.neighbours)
                    {
                        navNodes[index].AddNeighbour(neighbour);
                    }
                }
                else
                {
                    navNodes.Add(item);                     //otherwise add the node
                }
            }
        }
        knitDone = true;
    }