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(); } }
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(); } }