void UpdateDynamicChunkCache()
        {
            var dynamicChunksOrderVersion = EntityManager.GetComponentOrderVersion <VisibleLocalToWorld>();

            if (dynamicChunksOrderVersion == m_LastDynamicChunksOrderVersion)
            {
                return;
            }

            // Dispose
            if (m_DynamicChunks.IsCreated)
            {
                m_DynamicChunks.Dispose();
            }

            var sharedComponentCount           = EntityManager.GetSharedComponentCount();
            var customMeshInstanceRendererType = GetArchetypeChunkSharedComponentType <CustomMeshInstanceRenderer>();
            var worldMeshRenderBoundsType      = GetArchetypeChunkComponentType <WorldMeshRenderBounds>(true);

            // Allocate temp data
            var chunkRendererMap = new NativeMultiHashMap <int, int>(100000, Allocator.TempJob);
            var foundArchetypes  = new NativeList <EntityArchetype>(Allocator.TempJob);

            Profiler.BeginSample("CreateArchetypeChunkArray");
            EntityManager.AddMatchingArchetypes(m_DynamicChunksQuery, foundArchetypes);
            var chunks = EntityManager.CreateArchetypeChunkArray(foundArchetypes, Allocator.TempJob);

            Profiler.EndSample();

            m_DynamicChunks = new NativeArray <ArchetypeChunk>(chunks.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);

            var mapChunkRenderersJob = new MapChunkRenderers
            {
                Chunks = chunks,
                CustomMeshInstanceRendererType = customMeshInstanceRendererType,
                ChunkRendererMap = chunkRendererMap
            };
            var mapChunkRenderersJobHandle = mapChunkRenderersJob.Schedule(chunks.Length, 64);

            var gatherSortedChunksJob = new GatherSortedChunks
            {
                ChunkRendererMap     = chunkRendererMap,
                SharedComponentCount = sharedComponentCount,
                SortedChunks         = m_DynamicChunks,
                Chunks = chunks
            };
            var gatherSortedChunksJobHandle = gatherSortedChunksJob.Schedule(mapChunkRenderersJobHandle);

            gatherSortedChunksJobHandle.Complete();

            foundArchetypes.Dispose();
            chunkRendererMap.Dispose();
            chunks.Dispose();

            m_LastDynamicChunksOrderVersion = dynamicChunksOrderVersion;
        }
        void UpdateFrozenChunkCache()
        {
            var visibleLocalToWorldOrderVersion = EntityManager.GetComponentOrderVersion <VisibleLocalToWorld>();
            var frozenOrderVersion       = EntityManager.GetComponentOrderVersion <Frozen>();
            var staticChunksOrderVersion = math.min(visibleLocalToWorldOrderVersion, frozenOrderVersion);

            if (staticChunksOrderVersion == m_LastFrozenChunksOrderVersion)
            {
                return;
            }

            // Dispose
            if (m_FrozenChunks.IsCreated)
            {
                m_FrozenChunks.Dispose();
            }
            if (m_FrozenChunkBounds.IsCreated)
            {
                m_FrozenChunkBounds.Dispose();
            }

            var sharedComponentCount      = EntityManager.GetSharedComponentCount();
            var meshInstanceRendererType  = GetArchetypeChunkSharedComponentType <MeshInstanceRenderer>();
            var worldMeshRenderBoundsType = GetArchetypeChunkComponentType <WorldMeshRenderBounds>(true);

            // Allocate temp data
            var chunkRendererMap = new NativeMultiHashMap <int, int>(100000, Allocator.TempJob);
            var foundArchetypes  = new NativeList <EntityArchetype>(Allocator.TempJob);

            Profiler.BeginSample("CreateArchetypeChunkArray");
            var chunks = m_FrozenChunksQuery.CreateArchetypeChunkArray(Allocator.TempJob);

            Profiler.EndSample();

            m_FrozenChunks      = new NativeArray <ArchetypeChunk>(chunks.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
            m_FrozenChunkBounds = new NativeArray <WorldMeshRenderBounds>(chunks.Length, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);

            var mapChunkRenderersJob = new MapChunkRenderers
            {
                Chunks = chunks,
                MeshInstanceRendererType = meshInstanceRendererType,
                ChunkRendererMap         = chunkRendererMap.ToConcurrent()
            };
            var mapChunkRenderersJobHandle = mapChunkRenderersJob.Schedule(chunks.Length, 64);

            var gatherSortedChunksJob = new GatherSortedChunks
            {
                ChunkRendererMap     = chunkRendererMap,
                SharedComponentCount = sharedComponentCount,
                SortedChunks         = m_FrozenChunks,
                Chunks = chunks
            };
            var gatherSortedChunksJobHandle = gatherSortedChunksJob.Schedule(mapChunkRenderersJobHandle);

            var updateChangedChunkBoundsJob = new UpdateChunkBounds
            {
                Chunks = m_FrozenChunks,
                WorldMeshRenderBoundsType = worldMeshRenderBoundsType,
                ChunkBounds = m_FrozenChunkBounds
            };
            var updateChangedChunkBoundsJobHandle = updateChangedChunkBoundsJob.Schedule(chunks.Length, 64, gatherSortedChunksJobHandle);

            updateChangedChunkBoundsJobHandle.Complete();

            foundArchetypes.Dispose();
            chunkRendererMap.Dispose();
            chunks.Dispose();

            m_LastFrozenChunksOrderVersion = staticChunksOrderVersion;
        }