Exemplo n.º 1
0
        public static void Calculate(Level level)
        {
            var chunks = level.GetLoadedChunks().OrderBy(column => column.x).ThenBy(column => column.z);
            SkyLightBlockAccess blockAccess = new SkyLightBlockAccess(level.WorldProvider);

            _chunkCount = chunks.Count();

            if (_chunkCount == 0)
            {
                return;
            }

            CheckIfSpawnIsMiddle(chunks, level.SpawnPoint.GetCoordinates3D());

            Stopwatch sw = new Stopwatch();

            sw.Start();

            //Parallel.ForEach(chunks, chunk => chunk.RecalcHeight());

            //Log.Debug($"Recalc height level {level.LevelName}({level.LevelId}) for {_chunkCount} chunks, {_chunkCount*16*16*256} blocks. Time {sw.ElapsedMilliseconds}ms");

            SkyLightCalculations calculator = new SkyLightCalculations(Config.GetProperty("CalculateLights.MakeMovie", false));

            int midX = calculator.GetMidX(chunks.ToArray());

            //int width = calculator.GetWidth(chunks.ToArray());

            sw.Restart();

            HighPrecisionTimer tickerHighPrecisionTimer = null;

            if (calculator.TrackResults)
            {
                tickerHighPrecisionTimer = new HighPrecisionTimer(100, _ => calculator.SnapshotVisits());
            }

            calculator.StartTimeInMilliseconds = Environment.TickCount;

            var t0 = Task.Run(() =>
            {
                var pairs = chunks.OrderBy(pair => pair.x).ThenBy(pair => pair.z).Where(chunk => chunk.x <= midX).OrderByDescending(pair => pair.x).ThenBy(pair => pair.z).ToArray();
                calculator.CalculateSkyLights(blockAccess, pairs);
            });

            var t5 = Task.Run(() =>
            {
                var pairs = chunks.OrderByDescending(pair => pair.x).ThenBy(pair => pair.z).Where(chunk => chunk.x > midX).OrderBy(pair => pair.x).ThenByDescending(pair => pair.z).ToArray();
                calculator.CalculateSkyLights(blockAccess, pairs);
            });

            var t1 = Task.Run(() =>
            {
                var pairs = chunks.OrderBy(pair => pair.x).ThenBy(pair => pair.z).ToArray();
                calculator.CalculateSkyLights(blockAccess, pairs);
            });

            var t2 = Task.Run(() =>
            {
                var pairs = chunks.OrderByDescending(pair => pair.x).ThenByDescending(pair => pair.z).ToArray();
                calculator.CalculateSkyLights(blockAccess, pairs);
            });

            var t3 = Task.Run(() =>
            {
                var pairs = chunks.OrderByDescending(pair => pair.x).ThenBy(pair => pair.z).ToArray();
                calculator.CalculateSkyLights(blockAccess, pairs);
            });

            var t4 = Task.Run(() =>
            {
                var pairs = chunks.OrderBy(pair => pair.x).ThenByDescending(pair => pair.z).ToArray();
                calculator.CalculateSkyLights(blockAccess, pairs);
            });

            Task.WaitAll(t0, t1, t2, t3, t4, t5);

            Log.Debug($"Recalc skylight for {_chunkCount:N0} chunks, {_chunkCount*16*16*256:N0} blocks. Touches={calculator.visits:N0} Time {sw.ElapsedMilliseconds:N0}ms");

            if (calculator.TrackResults)
            {
                Task.Run(() =>
                {
                    tickerHighPrecisionTimer?.Dispose();
                    calculator.SnapshotVisits();
                    calculator.SnapshotVisits();

                    if (calculator.RenderingTasks.Count == 0)
                    {
                        return;
                    }

                    // Start with an end-frame (twitter thumbs)
                    var last = calculator.RenderingTasks.Last();
                    calculator.RenderingTasks.Remove(last);
                    calculator.RenderingTasks.Insert(0, last);

                    calculator.RenderVideo();

                    Log.Debug($"Movie rendered.");
                });
            }

            //foreach (var chunk in chunks)
            //{
            //	calculator.ShowHeights(chunk);
            //}

            //var chunkColumn = chunks.First(column => column.x == -1 && column.z == 0 );
            //if (chunkColumn != null)
            //{
            //	Log.Debug($"Heights:\n{Package.HexDump(chunkColumn.height)}");
            //	Log.Debug($"skylight.Data:\n{Package.HexDump(chunkColumn.skyLight.Data, 64)}");
            //}
        }