예제 #1
0
        private void CollectEdgesBetweenFloorLists(int bx, int by,
                                                   List <NavMeshBuilderFloorDesc> center, int nx, int ny,
                                                   Dictionary <EdgeVertex, List <EdgeVertex> > edgesOut)
        {
            List <NavMeshBuilderFloorDesc> neighbor = GetFloorDescListNoCheck(nx, ny);

            if (neighbor == null)
            {
                return;
            }

            var directionToNeighbor   = NavMeshUtil.DetermineDirection(bx, by, nx, ny);
            var directionFromNeighbor = NavMeshUtil.GetInverseDirection(directionToNeighbor);


            foreach (var floor in center)
            {
                // check if direction to neighbor is blocked.
                if ((floor.DirectionFlags & directionToNeighbor) != 0)
                {
                    continue;
                }

                List <EdgeVertex> list = null;
                foreach (var neighborFloor in neighbor)
                {
                    // check if direction from neighbor is blocked.
                    if ((neighborFloor.DirectionFlags & directionFromNeighbor) != 0)
                    {
                        continue;
                    }

                    if (Math.Abs(floor.Z100i - neighborFloor.Z100i) / 100.0f > m_maxZStep)
                    {
                        continue;
                    }

                    if (list == null)
                    {
                        var p0 = new EdgeVertex {
                            BX = (ushort)bx, BY = (ushort)by, Z100i = floor.Z100i
                        };
                        if (!edgesOut.TryGetValue(p0, out list))
                        {
                            list = new List <EdgeVertex>();
                            edgesOut.Add(p0, list);
                        }
                    }

                    list.Add(new EdgeVertex {
                        BX = (ushort)nx, BY = (ushort)ny, Z100i = neighborFloor.Z100i
                    });

                    break; // each floor connects to 0 or 1 neighbor in 1 direction.
                }
            }
        }
예제 #2
0
 public NodeId GetNeighbor(NodeId start, int offX, int offY)
 {
     return(GetNeighbor(start, NavMeshUtil.DetermineDirection(0, 0, offX, offY)));
 }
예제 #3
0
        // WARNING! on failure, m_floorData will be left in a bad state.
        private void FixDirectionFlagsToMatchSubgraphs(Dictionary <EdgeVertex, List <EdgeVertex> > edges,
                                                       List <HashSet <EdgeVertex> > subgraphs)
        {
            // mark all directions as blocked, then for each subgraph
            // visit edges/vertices and unblock directions.

            // clear all to 'blocked'
            foreach (var fl in m_floorData)
            {
                if (fl != null)
                {
                    for (int i = 0; i < fl.Count; i++)
                    {
                        fl[i] = new NavMeshBuilderFloorDesc(fl[i].Z100i, 0xFF);
                    }
                }
            }


            foreach (var sg in subgraphs)
            {
                foreach (var v in sg)
                {
                    var neighborEdges = edges[v];

                    foreach (var n in neighborEdges)
                    {
                        var dirToNeighbor   = NavMeshUtil.DetermineDirection(v.BX, v.BY, n.BX, n.BY);
                        var dirFromNeighbor = NavMeshUtil.GetInverseDirection(dirToNeighbor);

                        // update 'to' neighbor
                        // need to find which floor data entry is mine
                        var meContainedInList = m_floorData[v.BY * m_blockWidth + v.BX];
                        // next, find me
                        bool foundMe = false;
                        for (int j = 0; j < meContainedInList.Count; j++)
                        {
                            if (meContainedInList[j].Z100i == v.Z100i)
                            {
                                // unblock me to neighbor
                                meContainedInList[j] = new NavMeshBuilderFloorDesc(v.Z100i,
                                                                                   (byte)(meContainedInList[j].DirectionFlags & ~dirToNeighbor));
                                foundMe = true;
                                break;
                            }
                        }
                        if (!foundMe)
                        {
                            throw new InvalidOperationException("vertex should exist in floor data!");
                        }

                        // update 'from' neighbor
                        var  neighborContainedInList = m_floorData[n.BY * m_blockWidth + n.BX];
                        bool foundNeighbor           = false;
                        for (int j = 0; j < neighborContainedInList.Count; j++)
                        {
                            if (neighborContainedInList[j].Z100i == n.Z100i)
                            {
                                // unblock neighbor to me
                                neighborContainedInList[j] = new NavMeshBuilderFloorDesc(n.Z100i,
                                                                                         (byte)(neighborContainedInList[j].DirectionFlags & ~dirFromNeighbor));
                                foundNeighbor = true;
                                break;
                            }
                        }
                        if (!foundNeighbor)
                        {
                            throw new InvalidOperationException("neighbor vertex should exist in floor data!");
                        }
                    }
                }
            }
        }