Exemplo n.º 1
0
        public void ManualCalculation(List <ObstacleListenerSystem> ConcernedObstacleListeners, bool forceCalculation)
        {
            var occlusionCalculationCounter = 0;
            var totalFrustumCounter         = 0;

            if (!forceCalculation)
            {
                //Position change detection
                foreach (var obstacleListener in ConcernedObstacleListeners)
                {
                    ObstacleListenerLastFramePositions.TryGetValue(obstacleListener, out var lastFramePosition);
                    var hasChanged = !obstacleListener.AssociatedRangeTransformProvider().IsEqualTo(lastFramePosition);

                    //The obstacle listener has changed -> all associated near square obstacles are updated
                    if (hasChanged)
                    {
                        obstacleListenersThatHasChangedThisFrame.Add(obstacleListener);

                        foreach (var obstacleInteractiveObject in obstacleListener.NearSquareObstacles)
                        {
                            occlusionCalculationCounter += 1;
                            totalFrustumCounter         += obstacleInteractiveObject.GetFaceFrustums().Count;
                            ClearAndCreateCalculatedFrustums(obstacleListener, obstacleInteractiveObject);
                        }
                    }

                    //The obstacle listener hasn't changed -> we compate near square obstacles positions for update
                    else
                    {
                        singleObstacleThatHasChangedThisFrame.TryGetValue(obstacleListener, out var obstacleInteractiveObjectsThatChanged);
                        if (obstacleInteractiveObjectsThatChanged == null)
                        {
                            singleObstacleThatHasChangedThisFrame.Add(obstacleListener, new List <ObstacleInteractiveObject>());
                            obstacleInteractiveObjectsThatChanged = singleObstacleThatHasChangedThisFrame[obstacleListener];
                        }


                        foreach (var squareObstacle in obstacleListener.NearSquareObstacles)
                        {
                            ObstacleLastFramePositions.TryGetValue(squareObstacle, out var lastFrameSquareObstacleTrasform);
                            //Static obstacles are not detecting changes
                            if (!squareObstacle.SquareObstacleSystemInitializationData.IsStatic &&
                                !squareObstacle.GetObstacleCenterTransform().IsEqualTo(lastFrameSquareObstacleTrasform))
                            {
                                //We add this single couple (listener <-> obstacle) to calculation
                                obstacleInteractiveObjectsThatChanged.Add(squareObstacle);
                                occlusionCalculationCounter += 1;
                                totalFrustumCounter         += squareObstacle.GetFaceFrustums().Count;
                                ClearAndCreateCalculatedFrustums(obstacleListener, squareObstacle);
                            }
                        }
                    }

                    //Update Obstacle Listener Positions
                    ObstacleListenerLastFramePositions[obstacleListener] = obstacleListener.AssociatedRangeTransformProvider();
                }

                //Update Square Obstacle Positions
                foreach (var obstacleInteractiveObject in obstacleInteractiveObjectManager.AllObstacleInteractiveObjects)
                {
                    ObstacleLastFramePositions[obstacleInteractiveObject] = obstacleInteractiveObject.GetObstacleCenterTransform();
                }
            }
            else
            {
                foreach (var obstacleListener in ConcernedObstacleListeners)
                {
                    foreach (var squareObstacle in obstacleListener.NearSquareObstacles)
                    {
                        occlusionCalculationCounter += 1;
                        totalFrustumCounter         += squareObstacle.GetFaceFrustums().Count;
                    }
                }
            }

            if (occlusionCalculationCounter > 0)
            {
                FrustumOcclusionCalculationDatas = new NativeArray <FrustumOcclusionCalculationData>(occlusionCalculationCounter, Allocator.TempJob);
                AssociatedFrustums = new NativeArray <FrustumV2Indexed>(totalFrustumCounter, Allocator.TempJob);
                Results            = new NativeArray <FrustumPointsWithInitializedFlag>(totalFrustumCounter, Allocator.TempJob);

                var currentOcclusionCalculationCounter = 0;
                var currentFrustumCounter = 0;

                foreach (var obstacleListenerThatChanged in obstacleListenersThatHasChangedThisFrame)
                {
                    foreach (var nearSquareObstacle in obstacleListenerThatChanged.NearSquareObstacles)
                    {
                        AddToArrays(ref FrustumOcclusionCalculationDatas, AssociatedFrustums, ref currentOcclusionCalculationCounter, ref currentFrustumCounter, obstacleListenerThatChanged, nearSquareObstacle);
                    }
                }

                foreach (var singleObstacleSystemThatChanged in singleObstacleThatHasChangedThisFrame)
                {
                    if (singleObstacleSystemThatChanged.Value.Count > 0)
                    {
                        foreach (var nearSquareObstacle in singleObstacleSystemThatChanged.Value)
                        {
                            AddToArrays(ref FrustumOcclusionCalculationDatas, AssociatedFrustums, ref currentOcclusionCalculationCounter, ref currentFrustumCounter, singleObstacleSystemThatChanged.Key, nearSquareObstacle);
                        }
                    }
                }

                var jobHandle = new FrustumOcclusionCalculationJob()
                {
                    AssociatedFrustums = AssociatedFrustums,
                    FrustumOcclusionCalculationDatas = FrustumOcclusionCalculationDatas,
                    Results = Results
                }.Schedule(totalFrustumCounter, 36);

                if (!forceCalculation)
                {
                    JobEnded  = false;
                    JobHandle = jobHandle;
                }
                else
                {
                    jobHandle.Complete();
                    while (!jobHandle.IsCompleted)
                    {
                    }

                    OnJobEnded();
                }
            }
            else
            {
                ClearFrameDependantData();
            }
        }
Exemplo n.º 2
0
        public void ManualCalculation(List <ObstacleListenerSystem> ConcernedObstacleListeners, bool forceCalculation)
        {
            var occlusionCalculationCounter = 0;
            var totalFrustumCounter         = 0;

            // counting and clearing frustums that are going to be updated

            if (!forceCalculation)
            {
                //Position change detection
                foreach (var obstacleListener in ConcernedObstacleListeners)
                {
                    ObstacleListenerLastFramePositions.TryGetValue(obstacleListener, out var lastFramePosition);
                    var hasChanged = !obstacleListener.AssociatedRangeTransformProvider().IsEqualTo(lastFramePosition);

                    // The obstacle listener has moved -> all associated near obstacles occlusion frustums are updated
                    if (hasChanged)
                    {
                        obstacleListenersThatHasChangedThisFrame.Add(obstacleListener);

                        foreach (var obstacleInteractiveObject in obstacleListener.NearSquareObstacles)
                        {
                            occlusionCalculationCounter += 1;
                            totalFrustumCounter         += obstacleInteractiveObject.GetFaceFrustums().Count;
                            ClearAndCreateCalculatedFrustums(obstacleListener, obstacleInteractiveObject);
                        }
                    }

                    //The obstacle listener hasn't changed -> we compare near square obstacles positions for update
                    else
                    {
                        singleObstacleThatHasChangedThisFrame.TryGetValue(obstacleListener, out var obstacleInteractiveObjectsThatChanged);
                        if (obstacleInteractiveObjectsThatChanged == null)
                        {
                            singleObstacleThatHasChangedThisFrame.Add(obstacleListener, new List <ObstacleInteractiveObject>());
                            obstacleInteractiveObjectsThatChanged = singleObstacleThatHasChangedThisFrame[obstacleListener];
                        }


                        foreach (var squareObstacle in obstacleListener.NearSquareObstacles)
                        {
                            ObstacleLastFramePositions.TryGetValue(squareObstacle, out var lastFrameSquareObstacleTrasform);

                            if (
                                /// Static obstacles are not detecting transform changes
                                (!squareObstacle.SquareObstacleSystemInitializationData.IsStatic && !squareObstacle.InteractiveGameObject.GetTransform().IsEqualTo(lastFrameSquareObstacleTrasform))
                                ||
                                /// If there is no calculation data for this obstacle -> forcing calculation.
                                /// This can happen while reloading scene because NearSquareObstacles are added in fixed step and scene reload may imply to not call FixedUpdate before
                                /// Update
                                !OcclusionCalculationDataAvailable(obstacleListener, squareObstacle)
                                )
                            {
                                //We add this single couple (listener <-> obstacle) to calculation
                                obstacleInteractiveObjectsThatChanged.Add(squareObstacle);
                                occlusionCalculationCounter += 1;
                                totalFrustumCounter         += squareObstacle.GetFaceFrustums().Count;
                                ClearAndCreateCalculatedFrustums(obstacleListener, squareObstacle);
                            }

                            //Update Square Obstacle Positions
                            ObstacleLastFramePositions[squareObstacle] = squareObstacle.InteractiveGameObject.GetTransform();
                        }
                    }

                    //Update Obstacle Listener Positions
                    ObstacleListenerLastFramePositions[obstacleListener] = obstacleListener.AssociatedRangeTransformProvider();
                }
            }
            else
            {
                foreach (var obstacleListener in ConcernedObstacleListeners)
                {
                    foreach (var squareObstacle in obstacleListener.NearSquareObstacles)
                    {
                        occlusionCalculationCounter += 1;
                        totalFrustumCounter         += squareObstacle.GetFaceFrustums().Count;
                    }
                }
            }

            // If there is calculations to be done, create the unity job.

            if (occlusionCalculationCounter > 0)
            {
                FrustumOcclusionCalculationDatas = new NativeArray <FrustumOcclusionCalculationData>(occlusionCalculationCounter, Allocator.TempJob);
                AssociatedFrustums = new NativeArray <FrustumV2Indexed>(totalFrustumCounter, Allocator.TempJob);
                Results            = new NativeArray <FrustumPointsWithInitializedFlag>(totalFrustumCounter, Allocator.TempJob);

                var currentOcclusionCalculationCounter = 0;
                var currentFrustumCounter = 0;

                foreach (var obstacleListenerThatChanged in obstacleListenersThatHasChangedThisFrame)
                {
                    foreach (var nearSquareObstacle in obstacleListenerThatChanged.NearSquareObstacles)
                    {
                        AddToArrays(ref FrustumOcclusionCalculationDatas, AssociatedFrustums, ref currentOcclusionCalculationCounter, ref currentFrustumCounter, obstacleListenerThatChanged, nearSquareObstacle);
                    }
                }

                foreach (var singleObstacleSystemThatChanged in singleObstacleThatHasChangedThisFrame)
                {
                    if (singleObstacleSystemThatChanged.Value.Count > 0)
                    {
                        foreach (var nearSquareObstacle in singleObstacleSystemThatChanged.Value)
                        {
                            AddToArrays(ref FrustumOcclusionCalculationDatas, AssociatedFrustums, ref currentOcclusionCalculationCounter, ref currentFrustumCounter, singleObstacleSystemThatChanged.Key, nearSquareObstacle);
                        }
                    }
                }

                var jobHandle = new FrustumOcclusionCalculationJob()
                {
                    AssociatedFrustums = AssociatedFrustums,
                    FrustumOcclusionCalculationDatas = FrustumOcclusionCalculationDatas,
                    Results = Results
                }.Schedule(totalFrustumCounter, 36);

                if (!forceCalculation)
                {
                    JobEnded  = false;
                    JobHandle = jobHandle;
                }
                else
                {
                    jobHandle.Complete();
                    while (!jobHandle.IsCompleted)
                    {
                    }

                    OnJobEnded();
                }
            }
            else
            {
                ClearFrameDependantData();
            }
        }