示例#1
0
        private void ProcessRaycastData(RaycastJobHolder holder, List <Pair <byte, Point2D> > visibleNodes, Dictionary <Point2D, IFOWNode> nodes)
        {
            holder.Complete();

            NativeArray <RaycastHit>     results     = holder.GetResults();
            List <Pair <byte, Point2D> > localPoints = holder.GetPoints();

            for (int j = 0; j < localPoints.Count; j++)
            {
                int index = j * 2;
                if (results[index].collider == null || results[index + 1].collider == null)
                {
                    visibleNodes.Add(localPoints[j]);
                }
            }

            nodes.Add(holder.OriginPoint, new FOWNode(visibleNodes));
            holder.Dispose();
            visibleNodes.Clear();
        }
示例#2
0
        private bool ConnectTiles(RaycastHit[] hits, Point2D[] points, Dictionary <Point2D, IFOWNode> nodes, Dictionary <Point2D, Pair <float, Collider> > tempCamoNodes, float tileHalf, int layerMask)
        {
            const int  MaxBatches = 5;
            NavMeshHit navHit     = default(NavMeshHit);
            List <Pair <byte, Point2D> > visibleNodes = new List <Pair <byte, Point2D> >();

            List <RaycastCommand>    rayCommands = new List <RaycastCommand>();
            Queue <RaycastJobHolder> rayJobs     = new Queue <RaycastJobHolder>(5);

            for (int i = 0; i < hits.Length; i++)
            {
                Vector3 current = hits[i].point;

                float progress = Mathf.Clamp(0.01f + ((float)i / hits.Length) * 0.98f, 0, 1);
                bool  cancel   = EditorUtility.DisplayCancelableProgressBar("FOW", "Baking fog of war. Please wait...", progress);

                if (cancel)
                {
                    while (rayJobs.Count > 0)
                    {
                        RaycastJobHolder tempHolder = rayJobs.Dequeue();
                        tempHolder.Complete();
                        tempHolder.Dispose();
                    }

                    return(true);
                }

                if (!NavMesh.SamplePosition(current, out navHit, tileHalf, NavMesh.AllAreas))
                {
                    tempCamoNodes.Remove(points[i]);
                    continue;
                }

                current.y += info.eyeHeight;

                while (rayJobs.Count == MaxBatches)
                {
                    while (rayJobs.Count > 0 && rayJobs.Peek().IsCompleted)
                    {
                        RaycastJobHolder currentHolder = rayJobs.Dequeue();
                        ProcessRaycastData(currentHolder, visibleNodes, nodes);
                    }

                    Thread.Sleep(1);
                }

                List <Pair <byte, Point2D> > nodePoints = new List <Pair <byte, Point2D> >();

                for (int j = 0; j < hits.Length; j++)
                {
                    Vector3 next = hits[j].point;
                    next.y += info.eyeHeight;

                    float   dist = Vector3.Distance(current, next);
                    Vector3 dir  = (next - current).normalized;

                    float camoDist = 0;
                    if (tempCamoNodes.ContainsKey(points[j]))
                    {
                        if (tempCamoNodes.ContainsKey(points[i]))
                        {
                            Pair <float, Collider> currentPair = tempCamoNodes[points[i]];
                            Pair <float, Collider> nextPair    = tempCamoNodes[points[j]];

                            if (currentPair.right != nextPair.right)
                            {
                                camoDist = nextPair.left;
                            }
                        }
                        else
                        {
                            camoDist = tempCamoNodes[points[j]].left;
                        }
                    }

                    int roundDist = Mathf.RoundToInt(dist + camoDist);
                    if (roundDist > info.maxVisionRange)
                    {
                        continue;
                    }

                    rayCommands.Add(new RaycastCommand(current, dir, dist, layerMask));
                    rayCommands.Add(new RaycastCommand(next, -dir, dist, layerMask));
                    nodePoints.Add(new Pair <byte, Point2D>((byte)roundDist, points[j]));
                }

                RaycastJobHolder holder = new RaycastJobHolder(rayCommands, nodePoints, points[i]);
                holder.Schedule(rayCommands.Count / 5);
                rayJobs.Enqueue(holder);
                rayCommands.Clear();
            }

            while (rayJobs.Count > 0)
            {
                RaycastJobHolder holder = rayJobs.Dequeue();
                ProcessRaycastData(holder, visibleNodes, nodes);
            }

            return(false);
        }