////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override void LoadData()
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyVoxelCacheRender.LoadData");

            MySandboxGame.Log.WriteLine("MyVoxelCacheRender.LoadData() - START");
            MySandboxGame.Log.IncreaseIndent();

            m_capacity                = MyVoxelConstants.RENDER_CELL_CACHE_SIZE;
            m_cellsByCoordinate       = new Dictionary <Int64, LinkedListNode <MyVoxelCacheCellRender> >(m_capacity);
            m_priority                = new LinkedList <MyVoxelCacheCellRender>();
            m_priorityArray           = new LinkedListNode <MyVoxelCacheCellRender> [m_capacity];
            m_cellsPreallocated       = new MyVoxelCacheCellRender[m_capacity];
            m_helperLodCachedDataCell = new MyVoxelGeometry.CellData();
            m_dataCellsQueue          = new List <MyVoxelGeometry.CellData>(MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS_TOTAL);
            for (int i = 0; i < m_capacity; i++)
            {
                m_cellsPreallocated[i] = new MyVoxelCacheCellRender();
                m_priorityArray[i]     = new LinkedListNode <MyVoxelCacheCellRender>(m_cellsPreallocated[i]);
                m_priority.AddLast(m_priorityArray[i]);
            }
            MySandboxGame.Log.DecreaseIndent();
            MySandboxGame.Log.WriteLine("MyVoxelCacheRender.LoadData() - END");
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            LoadCache();
        }
        public static MyVoxelCacheCellRender GetCell(MyVoxelMap voxelMap, ref Vector3I renderCellCoord, MyLodTypeEnum cellHashType)
        {
            MyVoxelCacheCellRender ret = GetCellFromCache(voxelMap.VoxelMapId, ref renderCellCoord, cellHashType);

            if (ret == null)
            {
                ret = LoadCell(voxelMap, ref renderCellCoord, cellHashType);
            }

            if (ret != null)
            {
                UpdateCell(voxelMap.VoxelMapId, ref renderCellCoord, cellHashType);
            }

            return(ret);
        }
        public static MyMultiMaterialHelper GetForMultimaterial(int material0, int material1, int material2)
        {
            int id = MyVoxelCacheCellRender.GetMultimaterialId(material0, material1, material2);
            MyMultiMaterialHelper helper = null;

            m_preallocatedMultiMaterialHelpers.TryGetValue(id, out helper);
            if (helper == null)
            {
                helper = new MyMultiMaterialHelper();
                helper.LoadData();
                helper.SetMaterials(MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)material0),
                                    MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)material1),
                                    MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)material2));
                m_preallocatedMultiMaterialHelpers.Add(id, helper);
            }
            return(helper);

            //m_multiMaterialHelper.SetMaterials(material0, material1, material2);
            //return m_multiMaterialHelper;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override void LoadData()
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyVoxelCacheRender.LoadData");

            MySandboxGame.Log.WriteLine("MyVoxelCacheRender.LoadData() - START");
            MySandboxGame.Log.IncreaseIndent();

            m_capacity = MyVoxelConstants.RENDER_CELL_CACHE_SIZE;
            m_cellsByCoordinate = new Dictionary<Int64, LinkedListNode<MyVoxelCacheCellRender>>(m_capacity);
            m_priority = new LinkedList<MyVoxelCacheCellRender>();
            m_priorityArray = new LinkedListNode<MyVoxelCacheCellRender>[m_capacity];
            m_cellsPreallocated = new MyVoxelCacheCellRender[m_capacity];
            m_helperLodCachedDataCell = new MyVoxelGeometry.CellData();
            m_dataCellsQueue = new List<MyVoxelGeometry.CellData>(MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS_TOTAL);
            for (int i = 0; i < m_capacity; i++)
            {
                m_cellsPreallocated[i] = new MyVoxelCacheCellRender();
                m_priorityArray[i] = new LinkedListNode<MyVoxelCacheCellRender>(m_cellsPreallocated[i]);
                m_priority.AddLast(m_priorityArray[i]);
            }
            MySandboxGame.Log.DecreaseIndent();
            MySandboxGame.Log.WriteLine("MyVoxelCacheRender.LoadData() - END");
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            LoadCache();
        }
        private static MyVoxelCacheCellRender LoadCell(MyVoxelMap voxelMap, ref Vector3I renderCellCoord, MyLodTypeEnum cellHashType)
        {
            Profiler.Begin("AddCell");

            MyVoxelCacheCellRender ret = AddCell(voxelMap.VoxelMapId, ref renderCellCoord, cellHashType);

            ret.Begin(voxelMap, ref renderCellCoord);
            ret.CellHashType = cellHashType;

            Profiler.End();

            if (cellHashType == MyLodTypeEnum.LOD0)
            {
                Profiler.Begin("LOD0 - queue cells");
                m_dataCellsQueue.Clear();

                //  Create normal (LOD0) version
                for (int dataX = 0; dataX < MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS; dataX++)
                {
                    for (int dataY = 0; dataY < MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS; dataY++)
                    {
                        for (int dataZ = 0; dataZ < MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS; dataZ++)
                        {
                            //  Don't precalculate this cells now. Store it in queue and calculate all cells at once by MyVoxelPrecalc.PrecalcQueue()
                            Vector3I dataCellCoord =
                                new Vector3I(
                                    renderCellCoord.X * MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS + dataX,
                                    renderCellCoord.Y * MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS + dataY,
                                    renderCellCoord.Z * MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS + dataZ);
                            MyVoxelGeometry.CellData cachedDataCell = voxelMap.Geometry.GetCellLater(MyLodTypeEnum.LOD0, ref dataCellCoord);
                            if (cachedDataCell != null)
                            {
                                m_dataCellsQueue.Add(cachedDataCell);
                            }
                        }
                    }
                }

                Profiler.BeginNextBlock("LOD0 - PrecalcQueue");

                //  Precalculate all queued data cells in parallel threads - using multiple cores if possible.
                MyVoxelPrecalc.PrecalcQueue();

                Profiler.BeginNextBlock("LOD0 - AddTriangles");
                ret.AddTriangles(m_dataCellsQueue);
                Profiler.End();
            }
            else if (cellHashType == MyLodTypeEnum.LOD1)
            {
                Profiler.Begin("LOD1 - PrecalcImmediatelly");

                m_helperLodCachedDataCell.Reset();

                //  Create LOD1 render cell
                MyVoxelPrecalc.PrecalcImmediatelly(
                    new MyVoxelPrecalcTaskItem(
                        MyLodTypeEnum.LOD1,
                        voxelMap,
                        m_helperLodCachedDataCell,
                        new Vector3I(
                            renderCellCoord.X * MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS,
                            renderCellCoord.Y * MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS,
                            renderCellCoord.Z * MyVoxelConstants.RENDER_CELL_SIZE_IN_GEOMETRY_CELLS)));


                Profiler.BeginNextBlock("LOD1 - AddTriangles");
                m_dataCellsQueue.Clear();
                m_dataCellsQueue.Add(m_helperLodCachedDataCell);
                ret.AddTriangles(m_dataCellsQueue);
                Profiler.End();
            }
            else
            {
                throw new InvalidBranchException();
            }

            ret.End();

            return(ret);
        }