private void SpawnQueueWorker(NaniteOreDetector detectorComponent)
        {
            int scanningSpeed = NaniteConstructionManager.Settings != null ? NaniteConstructionManager.Settings.OreDetectorScanningSpeed : 10;

            scanningSpeed += (int)detectorComponent.ScanningUpgradesNum * 2;

            // Logging.Instance.WriteLine($"scanningSpeed sphere moved {scanningSpeed}");

            // Logging.Instance.WriteLine($"SpawnQueueWorker {Math.Min(m_taskQueue.Count, scanningSpeed)}", 1);
            for (int i = 0; i < Math.Min(m_taskQueue.Count, scanningSpeed); i++)
            {
                Vector3I vector;
                if (!m_taskQueue.TryDequeue(out vector))
                {
                    return;
                }

                OreDepositWork.Start(vector, vector + 1, m_voxelMap, Materials, QueueWorkerDone, HasFilterUpgrade, OreListSelected);

                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                          { m_tasksRunning++; });

                MyAPIGateway.Parallel.Sleep(100);
            }
        }
        public void UpdateDeposits(ref BoundingSphereD sphere, long detectorId, NaniteOreDetector detectorComponent)
        { // Invoked from parallel task
            Logging.Instance.WriteLine($"UpdateDeposits Tasks: Running:{m_tasksRunning} Initial tasks:{m_initialTasks} Processed tasks:{m_processedTasks} Timeout:{m_tasksTimeout}", 1);

            if (m_tasksRunning > 0)
            {
                if (m_OldprocessedTasks == m_processedTasks && m_processedTasks != m_initialTasks)
                {
                    if (m_tasksTimeout > 100)
                    {
                        Logging.Instance.WriteLine($"Mining scan task timeout. Clearing ore deposits and restarting.");
                        MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                        {
                            detectorComponent.DepositGroup.Clear();
                            m_tasksTimeout = 0;
                        });
                    }
                    else
                    {
                        MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                                  { m_tasksTimeout++; });
                    }
                }
                else
                {
                    MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                    {
                        m_OldprocessedTasks = m_processedTasks;
                        m_tasksTimeout      = 0;
                    });
                }
                return;
            }

            MyAPIGateway.Utilities.InvokeOnGameThread(() =>
            {
                m_tasksTimeout   = 0;
                HasFilterUpgrade = detectorComponent.HasFilterUpgrade;
                OreListSelected  = detectorComponent.OreListSelected;
            });

            Vector3I minCorner, maxCorner;

            {
                var sphereMin = sphere.Center - sphere.Radius;
                var sphereMax = sphere.Center + sphere.Radius;
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(m_voxelMap.PositionLeftBottomCorner, ref sphereMin, out minCorner);
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(m_voxelMap.PositionLeftBottomCorner, ref sphereMax, out maxCorner);
                minCorner += m_voxelMap.StorageMin;
                maxCorner += m_voxelMap.StorageMin;

                // LOD changes
                minCorner >>= 5;
                maxCorner >>= 5;
            }

            if (m_lastDetectionMin == null || m_lastDetectionMax == null)
            { // First scan
                Logging.Instance.WriteLine($"UpdateDeposits First scan", 1);

                detectorComponent.ClearMinedPositions();

                m_lastDetectionMax = minCorner;
                m_lastDetectionMin = maxCorner;
            }
            else if (m_lastDetectionMin == minCorner && m_lastDetectionMax == maxCorner)
            { // sphere still at some position
                Logging.Instance.WriteLine($"UpdateDeposits sphere still at some position", 1);

                if (m_tasksRunning < 1)
                {
                    SpawnQueueWorker();
                }

                return;
            }
            else if (m_lastDetectionMin != minCorner || m_lastDetectionMax != maxCorner)
            { // sphere moved, RESET QUEUES
                Logging.Instance.WriteLine($"UpdateDeposits sphere moved", 1);
                m_lastDetectionMin = minCorner;
                m_lastDetectionMax = maxCorner;
                Materials.Clear();
                m_taskQueue.Clear();
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                {
                    m_initialTasks   = 0;
                    m_processedTasks = 0;
                });
            }

            Vector3I cell = default(Vector3I);

            cell.Z = minCorner.Z;
            while (cell.Z <= maxCorner.Z)
            {
                cell.Y = minCorner.Y;
                while (cell.Y <= maxCorner.Y)
                {
                    cell.X = minCorner.X;
                    while (cell.X <= maxCorner.X)
                    {
                        m_taskQueue.Enqueue(cell);
                        cell.X++;
                    }
                    cell.Y++;
                }
                cell.Z++;
            }

            Logging.Instance.WriteLine($"UpdateDeposits setup queue {m_taskQueue.Count}", 1);
            MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                      { m_initialTasks = m_taskQueue.Count; });
        }