示例#1
0
        private void ComputeDirectionFlags(GeoSpace geoSpace)
        {
            // run in 2 passes to avoid "collection was modified".
            for (int interleave = 0; interleave < 2; interleave++)
            {
                Parallel.For(0, m_blockHeight, new ParallelOptions {
                    MaxDegreeOfParallelism = OPTION_PARALLEL_THREADS
                }, (y) =>
                {
                    if (y % 2 == interleave)
                    {
                        return;
                    }

                    int i = y * m_blockWidth; // index to floor cell
                    for (int x = 0; x < m_blockWidth; x++, i++)
                    {
                        List <NavMeshBuilderFloorDesc> heights = m_floorData[i];
                        if (heights == null)
                        {
                            continue;
                        }

                        for (int f = 0; f < heights.Count; f++)
                        {
                            int z100      = heights[f].Z100i;
                            byte newFlags = GetBlockedDirections(geoSpace, x, y, z100);
                            heights[f]    = new NavMeshBuilderFloorDesc(z100, newFlags);
                        }
                    }
                });
            }
        }
示例#2
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!");
                        }
                    }
                }
            }
        }