private void GetChunk(ref Vector3I coord, out VoxelChunk chunk, MyStorageDataTypeFlags required)
        {
            using (m_cacheLock.AcquireExclusiveUsing())
            {
                if (!m_cachedChunks.TryGetValue(coord, out chunk))
                {
                    chunk = new VoxelChunk(coord);

                    var rangeStart = coord << VoxelChunk.SizeBits;
                    var rangeEnd   = ((coord + 1) << VoxelChunk.SizeBits) - 1;

                    if (required != 0)
                    {
                        using (m_storageLock.AcquireSharedUsing())
                            ReadDatForChunk(chunk, required);
                    }

                    m_chunksbyAge.Enqueue(coord);
                    m_cachedChunks.Add(coord, chunk);

                    var bb = new BoundingBox(rangeStart, rangeEnd);

                    chunk.TreeProxy = m_cacheMap.AddProxy(ref bb, chunk, 0);
                }
                else if ((chunk.Cached & required) != required)
                {
                    using (m_storageLock.AcquireSharedUsing())
                        ReadDatForChunk(chunk, required & ~chunk.Cached);
                }
            }
        }
        void ModAPI.Interfaces.IMyStorage.ReadRange(MyStorageDataCache target, MyStorageDataTypeFlags dataToRead, int lodIndex,  Vector3I lodVoxelRangeMin,  Vector3I lodVoxelRangeMax)
        {
            if ((uint)lodIndex >= (uint)MyCellCoord.MAX_LOD_COUNT)
                return;

            ReadRange(target, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
        }
        void VRage.ModAPI.IMyStorage.ReadRange(MyStorageData target, MyStorageDataTypeFlags dataToRead, int lodIndex, Vector3I lodVoxelRangeMin, Vector3I lodVoxelRangeMax, ref MyVoxelRequestFlags requestFlags)
        {
            if ((uint)lodIndex >= (uint)MyCellCoord.MAX_LOD_COUNT)
                return;

            ReadRange(target, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref requestFlags);
        }
            public void ReadLod(MyStorageData target, MyStorageDataTypeFlags dataTypes, ref Vector3I targetOffset, int lodIndex, ref Vector3I min, ref Vector3I max)
            {
                Debug.Assert(min.IsInsideInclusive(Vector3I.Zero, MaxVector >> lodIndex) &&
                             max.IsInsideInclusive(Vector3I.Zero, MaxVector >> lodIndex));

                //using (Lock.AcquireSharedUsing())
                {
                    if (lodIndex > m_maxLod)
                    {
                        UpdateLodData(lodIndex);
                    }

                    if (dataTypes.Requests(MyStorageDataTypeEnum.Content))
                    {
                        ReadLod(target, MyStorageDataTypeEnum.Content, Content, targetOffset, lodIndex, min, max);
                    }

                    if (dataTypes.Requests(MyStorageDataTypeEnum.Material))
                    {
                        ReadLod(target, MyStorageDataTypeEnum.Material, Material, targetOffset, lodIndex, min, max);
                    }
                }

                HitCount++;
            }
示例#5
0
        protected override void WriteRangeInternal(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax)
        {
            ProfilerShort.Begin("MyOctreeStorage.WriteRange");

            Debug.Assert(dataToWrite != MyStorageDataTypeFlags.None);
            if ((dataToWrite & MyStorageDataTypeFlags.Content) != 0)
            {
                var args = new WriteRangeArgs()
                {
                    DataFilter = MyOctreeNode.ContentFilter,
                    DataType   = MyStorageDataTypeEnum.Content,
                    Leaves     = m_contentLeaves,
                    Nodes      = m_contentNodes,
                    Provider   = m_dataProvider,
                    Source     = source,
                };
                WriteRange(ref args, 0, m_treeHeight + LeafLodCount, Vector3I.Zero, ref voxelRangeMin, ref voxelRangeMax);
            }

            if ((dataToWrite & MyStorageDataTypeFlags.Material) != 0)
            {
                var args = new WriteRangeArgs()
                {
                    DataFilter = MyOctreeNode.MaterialFilter,
                    DataType   = MyStorageDataTypeEnum.Material,
                    Leaves     = m_materialLeaves,
                    Nodes      = m_materialNodes,
                    Provider   = m_dataProvider,
                    Source     = source,
                };
                WriteRange(ref args, 0, m_treeHeight + LeafLodCount, Vector3I.Zero, ref voxelRangeMin, ref voxelRangeMax);
            }

            ProfilerShort.End();
        }
示例#6
0
 public VoxelWriteOp(string voxelName, string data, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin, Vector3I voxelRangeMax)
 {
     m_voxelName = voxelName;
     m_data      = data;
     m_dataType  = dataToWrite;
     m_voxelMin  = voxelRangeMin;
     m_voxelMax  = voxelRangeMax;
 }
 public VoxelWriteOp(string voxelName, string data, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin, Vector3I voxelRangeMax)
 {
     m_voxelName = voxelName;
     m_data = data;
     m_dataType = dataToWrite;
     m_voxelMin = voxelRangeMin;
     m_voxelMax = voxelRangeMax;
 }
示例#8
0
        void ModAPI.Interfaces.IMyStorage.ReadRange(MyStorageDataCache target, MyStorageDataTypeFlags dataToRead, int lodIndex, Vector3I lodVoxelRangeMin, Vector3I lodVoxelRangeMax)
        {
            if ((uint)lodIndex >= (uint)MyCellCoord.MAX_LOD_COUNT)
            {
                return;
            }

            ReadRange(target, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
        }
示例#9
0
        void VRage.ModAPI.IMyStorage.ReadRange(MyStorageData target, MyStorageDataTypeFlags dataToRead, int lodIndex, Vector3I lodVoxelRangeMin, Vector3I lodVoxelRangeMax, ref MyVoxelRequestFlags requestFlags)
        {
            if ((uint)lodIndex >= (uint)MyCellCoord.MAX_LOD_COUNT)
            {
                return;
            }

            ReadRange(target, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref requestFlags);
        }
示例#10
0
        public void ReadRange(MyStorageData target, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax, ref MyVoxelRequestFlags requestFlags)
        {
            ProfilerShort.Begin(GetType().Name + ".ReadRange");
            try
            {
                const int SUBRANGE_SIZE_SHIFT = 3;
                const int SUBRANGE_SIZE       = 1 << SUBRANGE_SIZE_SHIFT;
                var       threshold           = new Vector3I(SUBRANGE_SIZE);
                var       rangeSize           = lodVoxelRangeMax - lodVoxelRangeMin + 1;
                if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
                {
                    target.ClearContent(0);
                }

                if ((rangeSize.X <= threshold.X &&
                     rangeSize.Y <= threshold.Y &&
                     rangeSize.Z <= threshold.Z) || !MyFakes.ENABLE_SPLIT_VOXEL_READ_QUERIES)
                {
                    using (m_lock.AcquireSharedUsing())
                    {
                        ReadRangeInternal(target, ref Vector3I.Zero, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref requestFlags);
                    }
                }
                else
                {
                    // These optimizations don't work when splitting the range.
                    requestFlags &= ~(MyVoxelRequestFlags.OneMaterial | MyVoxelRequestFlags.ContentChecked);
                    MyVoxelRequestFlags flags = requestFlags;

                    // splitting to smaller ranges to make sure the lock is not held for too long, preventing write on update thread
                    // subranges could be aligned to multiple of their size for possibly better performance
                    var steps = (rangeSize - 1) >> SUBRANGE_SIZE_SHIFT;
                    for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref steps); it.IsValid(); it.MoveNext())
                    {
                        flags = requestFlags;
                        var offset = it.Current << SUBRANGE_SIZE_SHIFT;
                        var min    = lodVoxelRangeMin + offset;
                        var max    = min + SUBRANGE_SIZE - 1;
                        Vector3I.Min(ref max, ref lodVoxelRangeMax, out max);
                        Debug.Assert(min.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax));
                        Debug.Assert(max.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax));
                        using (m_lock.AcquireSharedUsing())
                        {
                            ReadRangeInternal(target, ref offset, dataToRead, lodIndex, ref min, ref max, ref flags);
                        }
                    }

                    // If the storage is consistent this should be fine.
                    requestFlags = flags;
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
示例#11
0
 protected internal void OnRangeChanged(Vector3I voxelRangeMin, Vector3I voxelRangeMax, MyStorageDataTypeFlags changedData)
 {
     if (RangeChanged != null)
     {
         m_compressedData = null;
         this.ClampVoxelCoord(ref voxelRangeMin);
         this.ClampVoxelCoord(ref voxelRangeMax);
         RangeChanged(voxelRangeMin, voxelRangeMax, changedData);
     }
 }
示例#12
0
        /// <summary>
        /// Resets the data specified by flags to values from data provider, or default if no provider is assigned.
        /// </summary>
        /// <param name="dataToReset"></param>
        public void Reset(MyStorageDataTypeFlags dataToReset)
        {
            MyPrecalcComponent.AssertUpdateThread();

            using (m_storageLock.AcquireExclusiveUsing())
            {
                m_compressedData = null;
                ResetInternal(dataToReset);
            }
            OnRangeChanged(Vector3I.Zero, Size - 1, dataToReset);
        }
 void IMyStorageDataProvider.ReadRange(MyStorageData target, MyStorageDataTypeFlags dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
 {
     if (dataType.Requests(MyStorageDataTypeEnum.Content))
     {
         ReadContentRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
     }
     else
     {
         ReadMaterialRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
     }
 }
示例#14
0
        public void ReadRange(MyStorageDataCache target, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax)
        {
            ProfilerShort.Begin(GetType().Name + ".ReadRange");
            try
            {
                const int SUBRANGE_SIZE_SHIFT = 3;
                const int SUBRANGE_SIZE       = 1 << SUBRANGE_SIZE_SHIFT;
                var       threshold           = new Vector3I(SUBRANGE_SIZE);
                var       rangeSize           = lodVoxelRangeMax - lodVoxelRangeMin + 1;
                if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
                {
                    target.ClearContent(0);
                }
                if ((dataToRead & MyStorageDataTypeFlags.Material) != 0)
                {
                    target.ClearMaterials(m_defaultMaterial);
                }

                if (rangeSize.X <= threshold.X &&
                    rangeSize.Y <= threshold.Y &&
                    rangeSize.Z <= threshold.Z)
                {
                    using (m_lock.AcquireSharedUsing())
                    {
                        ReadRangeInternal(target, ref Vector3I.Zero, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
                    }
                }
                else
                {
                    // splitting to smaller ranges to make sure the lock is not held for too long, preventing write on update thread
                    // subranges could be aligned to multiple of their size for possibly better performance
                    var steps = (rangeSize - 1) >> SUBRANGE_SIZE_SHIFT;
                    for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref steps); it.IsValid(); it.MoveNext())
                    {
                        var offset = it.Current << SUBRANGE_SIZE_SHIFT;
                        var min    = lodVoxelRangeMin + offset;
                        var max    = min + SUBRANGE_SIZE - 1;
                        Vector3I.Min(ref max, ref lodVoxelRangeMax, out max);
                        Debug.Assert(min.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax));
                        Debug.Assert(max.IsInsideInclusive(ref lodVoxelRangeMin, ref lodVoxelRangeMax));
                        using (m_lock.AcquireSharedUsing())
                        {
                            ReadRangeInternal(target, ref offset, dataToRead, lodIndex, ref min, ref max);
                        }
                    }
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
        private void ReadDatForChunk(VoxelChunk chunk, MyStorageDataTypeFlags data)
        {
            var rangeStart = chunk.Coords << VoxelChunk.SizeBits;
            var rangeEnd   = ((chunk.Coords + 1) << VoxelChunk.SizeBits) - 1;

            MyStorageData storage = chunk.MakeData();

            MyVoxelRequestFlags flags = 0;

            ReadRangeInternal(storage, ref Vector3I.Zero, data, 0, ref rangeStart, ref rangeEnd, ref flags);

            chunk.Cached |= data;
        }
示例#16
0
 public void ReadRange(MyStorageData target, MyStorageDataTypeFlags dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
 {
     if (!this.Closed)
     {
         MyVoxelDataRequest req = new MyVoxelDataRequest {
             Target        = target,
             Offset        = writeOffset,
             RequestedData = dataType,
             Lod           = lodIndex,
             MinInLod      = minInLod,
             MaxInLod      = maxInLod
         };
         this.ReadRange(ref req, false);
     }
 }
示例#17
0
        protected override void ResetInternal(MyStorageDataTypeFlags dataToReset)
        {
            bool resetContent   = (dataToReset & MyStorageDataTypeFlags.Content) != 0;
            bool resetMaterials = (dataToReset & MyStorageDataTypeFlags.Material) != 0;

            if (resetContent)
            {
                m_contentLeaves.Clear();
                m_contentNodes.Clear();
            }

            if (resetMaterials)
            {
                m_materialLeaves.Clear();
                m_materialNodes.Clear();
            }

            if (m_dataProvider != null)
            {
                var cellCoord = new MyCellCoord(m_treeHeight, ref Vector3I.Zero);
                var leafId    = cellCoord.PackId64();
                cellCoord.Lod += LeafLodCount;
                var end = Size - 1;
                if (resetContent)
                {
                    m_contentLeaves.Add(leafId,
                                        new MyProviderLeaf(m_dataProvider, MyStorageDataTypeEnum.Content, ref cellCoord));
                }
                if (resetMaterials)
                {
                    m_materialLeaves.Add(leafId,
                                         new MyProviderLeaf(m_dataProvider, MyStorageDataTypeEnum.Material, ref cellCoord));
                }
            }
            else
            {
                var nodeId = new MyCellCoord(m_treeHeight - 1, ref Vector3I.Zero).PackId64();
                if (resetContent)
                {
                    m_contentNodes.Add(nodeId, new MyOctreeNode());
                }
                if (resetMaterials)
                {
                    m_materialNodes.Add(nodeId, new MyOctreeNode());
                }
            }
        }
示例#18
0
        void IMyOctreeLeafNode.ReadRange(MyStorageData target, MyStorageDataTypeFlags types, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, ref MyVoxelRequestFlags flags)
        {
            int                num     = this.m_cell.Lod - lodIndex;
            Vector3I           vectori = this.m_cell.CoordInLod << num;
            MyVoxelDataRequest request = new MyVoxelDataRequest {
                Target        = target,
                Offset        = writeOffset,
                Lod           = lodIndex,
                MinInLod      = (Vector3I)(minInLod + vectori),
                MaxInLod      = (Vector3I)(maxInLod + vectori),
                RequestFlags  = flags,
                RequestedData = types
            };

            this.m_provider.ReadRange(ref request, false);
            flags = request.Flags;
        }
示例#19
0
        private void ReadRangeAdviseCache(MyStorageData target, MyStorageDataTypeFlags dataToRead, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax)
        {
            // Skip if too many cached cells
            if (m_pendingChunksToWrite.Count > WriteCacheCap)
            {
                ReadRange(target, dataToRead, 0, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
                return;
            }

            if (CachedWrites)
            {
                var lodDiff = VoxelChunk.SizeBits;

                var chunkMin = lodVoxelRangeMin >> lodDiff;
                var chunkMax = lodVoxelRangeMax >> lodDiff;

                var pos = Vector3I.Zero;
                for (pos.Z = chunkMin.Z; pos.Z <= chunkMax.Z; ++pos.Z)
                {
                    for (pos.Y = chunkMin.Y; pos.Y <= chunkMax.Y; ++pos.Y)
                    {
                        for (pos.X = chunkMin.X; pos.X <= chunkMax.X; ++pos.X)
                        {
                            var celPos = pos << lodDiff;

                            var lodCkStart = pos << lodDiff;
                            lodCkStart = Vector3I.Max(lodCkStart, lodVoxelRangeMin);

                            var targetOffset = lodCkStart - lodVoxelRangeMin;

                            var lodCkEnd = ((pos + 1) << lodDiff) - 1;
                            lodCkEnd = Vector3I.Min(lodCkEnd, lodVoxelRangeMax);

                            VoxelChunk chunk;
                            GetChunk(ref pos, out chunk, dataToRead);

                            lodCkStart -= celPos;
                            lodCkEnd   -= celPos;

                            using (chunk.Lock.AcquireSharedUsing())
                                chunk.ReadLod(target, dataToRead, ref targetOffset, 0, ref lodCkStart, ref lodCkEnd);
                        }
                    }
                }
            }
        }
示例#20
0
        public void OnStorageChanged(Vector3I minChanged, Vector3I maxChanged, MyStorageDataTypeFlags dataChanged)
        {
            ProfilerShort.Begin("MyVoxelMap::storage_RangeChanged");

            minChanged = Vector3I.Clamp(minChanged, m_storageMin, m_storageMax);
            maxChanged = Vector3I.Clamp(maxChanged, m_storageMin, m_storageMax);
            Debug.Assert(minChanged.IsInsideInclusive(ref m_storageMin, ref m_storageMax) &&
                maxChanged.IsInsideInclusive(ref m_storageMin, ref m_storageMax));

            // Physics doesn't care about materials, just shape of things.
            if ((dataChanged & MyStorageDataTypeFlags.Content) != 0 &&
                Physics != null)
            {
                Physics.InvalidateRange(minChanged, maxChanged);
            }

            ProfilerShort.End();
        }
示例#21
0
        public void OnStorageChanged(Vector3I minChanged, Vector3I maxChanged, MyStorageDataTypeFlags dataChanged)
        {
            ProfilerShort.Begin("MyVoxelMap::storage_RangeChanged");

            minChanged = Vector3I.Clamp(minChanged, m_storageMin, m_storageMax);
            maxChanged = Vector3I.Clamp(maxChanged, m_storageMin, m_storageMax);
            Debug.Assert(minChanged.IsInsideInclusive(ref m_storageMin, ref m_storageMax) &&
                         maxChanged.IsInsideInclusive(ref m_storageMin, ref m_storageMax));

            // Physics doesn't care about materials, just shape of things.
            if ((dataChanged & MyStorageDataTypeFlags.Content) != 0 &&
                Physics != null)
            {
                Physics.InvalidateRange(minChanged, maxChanged);
            }

            ProfilerShort.End();
        }
示例#22
0
 public unsafe void PostProcess(VrVoxelMesh mesh, MyStorageDataTypeFlags dataTypes)
 {
     if (dataTypes.Requests(MyStorageDataTypeEnum.Material))
     {
         VrVoxelVertex *vertices    = mesh.Vertices;
         int            vertexCount = mesh.VertexCount;
         Vector3        start       = (Vector3)mesh.Start;
         float          scale       = mesh.Scale;
         for (int i = 0; i < vertexCount; i++)
         {
             Vector3 position = (start + vertices[i].Position) * scale;
             Vector3 vector3  = this.Material.GetColorShift(position, vertices[i].Material, 1024f);
             if (vector3 != Vector3.Zero)
             {
                 vertices[i].Color.PackedValue = PackColorShift(vector3 * new Vector3(360f, 100f, 100f));
             }
         }
     }
 }
示例#23
0
            private static Color GetColorForDirty(MyStorageDataTypeFlags dirty)
            {
                switch (dirty)
                {
                case MyStorageDataTypeFlags.Content:
                    return(Color.Blue);

                case MyStorageDataTypeFlags.Material:
                    return(Color.Red);

                case MyStorageDataTypeFlags.ContentAndMaterial:
                    return(Color.Magenta);

                case MyStorageDataTypeFlags.None:
                    return(Color.Green);

                default:
                    return(Color.White);
                }
            }
            public void Write(MyStorageData source, MyStorageDataTypeFlags dataTypes, ref Vector3I targetOffset, ref Vector3I min, ref Vector3I max)
            {
                //using (Lock.AcquireExclusiveUsing())
                {
                    //if (false) // disabled for testing :D
                    if (dataTypes.Requests(MyStorageDataTypeEnum.Content))
                    {
                        Write(source, MyStorageDataTypeEnum.Content, Content, targetOffset, min, max);
                    }

                    if (dataTypes.Requests(MyStorageDataTypeEnum.Material))
                    {
                        Write(source, MyStorageDataTypeEnum.Material, Material, targetOffset, min, max);
                    }

                    Cached |= dataTypes;

                    Dirty   |= dataTypes;
                    m_maxLod = 0;
                }
            }
示例#25
0
        /// <summary>
        /// Invalidates voxel cache
        /// </summary>
        /// <param name="minChanged">Inclusive min</param>
        /// <param name="maxChanged">Inclusive max</param>
        private void storage_RangeChanged(Vector3I minChanged, Vector3I maxChanged, MyStorageDataTypeFlags dataChanged)
        {
            ProfilerShort.Begin("MyVoxelMap::storage_RangeChanged");

            Debug.Assert(minChanged.IsInsideInclusive(ref m_storageMin, ref m_storageMax) &&
                         maxChanged.IsInsideInclusive(ref m_storageMin, ref m_storageMax));

            // Physics doesn't care about materials, just shape of things.
            if ((dataChanged & MyStorageDataTypeFlags.Content) != 0 &&
                Physics != null)
            {
                Physics.InvalidateRange(minChanged, maxChanged);
            }

            if (Render is MyRenderComponentVoxelMap)
            {
                (Render as MyRenderComponentVoxelMap).InvalidateRange(minChanged, maxChanged);
            }

            ProfilerShort.End();
        }
示例#26
0
        public void WriteRange(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax)
        {
            MyPrecalcComponent.AssertUpdateThread();

            ProfilerShort.Begin(GetType().Name + ".WriteRange");
            try
            {
                using (m_lock.AcquireExclusiveUsing())
                {
                    m_compressedData = null;
                    WriteRangeInternal(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
                }

                ProfilerShort.BeginNextBlock(GetType().Name + ".OnRangeChanged");

                OnRangeChanged(voxelRangeMin, voxelRangeMax, dataToWrite);
            }
            finally
            {
                ProfilerShort.End();
            }
        }
示例#27
0
        protected override void ReadRangeInternal(MyStorageDataCache target, ref Vector3I targetWriteOffset,
                                                  MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelCoordStart, ref Vector3I lodVoxelCoordEnd)
        {
            bool hasLod = lodIndex <= (m_treeHeight + LeafLodCount);

            Debug.Assert(dataToRead != MyStorageDataTypeFlags.None);
            if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
            {
                if (hasLod)
                {
                    ReadRange(target, ref targetWriteOffset, MyStorageDataTypeEnum.Content, m_treeHeight, m_contentNodes, m_contentLeaves, lodIndex, ref lodVoxelCoordStart, ref lodVoxelCoordEnd);
                }
            }

            if ((dataToRead & MyStorageDataTypeFlags.Material) != 0)
            {
                if (hasLod)
                {
                    ReadRange(target, ref targetWriteOffset, MyStorageDataTypeEnum.Material, m_treeHeight, m_materialNodes, m_materialLeaves, lodIndex, ref lodVoxelCoordStart, ref lodVoxelCoordEnd);
                }
            }
        }
示例#28
0
        /// <summary>
        /// For debugging/testing only! This can be very slow for large storage.
        /// </summary>
        public void Voxelize(MyStorageDataTypeFlags data)
        {
            var cache = new MyStorageDataCache();

            cache.Resize(new Vector3I(LeafSizeInVoxels));
            var      leafCount = (Size / LeafSizeInVoxels);
            Vector3I leaf      = Vector3I.Zero;
            var      end       = leafCount - 1;

            for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref end);
                 it.IsValid();
                 it.GetNext(out leaf))
            {
                Debug.WriteLine("Processing {0} / {1}", leaf, end);
                var min = leaf * LeafSizeInVoxels;
                var max = min + (LeafSizeInVoxels - 1);
                ReadRangeInternal(cache, ref Vector3I.Zero, data, 0, ref min, ref max);
                WriteRangeInternal(cache, data, ref min, ref max);
            }

            OnRangeChanged(Vector3I.Zero, Size - 1, data);
        }
示例#29
0
        void IMyOctreeLeafNode.ReadRange(MyStorageData target, MyStorageDataTypeFlags types, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, ref MyVoxelRequestFlags flags)
        {
            var lodShift = m_cell.Lod - lodIndex;
            var leafMinInLod = m_cell.CoordInLod << lodShift;
            var min = minInLod + leafMinInLod;
            var max = maxInLod + leafMinInLod;
            AssertRangeIsInside(lodIndex, ref min, ref max);
            ProfilerShort.Begin("MyProviderLeaf.ReadRange");
            MyVoxelDataRequest req = new MyVoxelDataRequest() {
                Target = target,
                Offset = writeOffset,
                Lod = lodIndex,
                minInLod = min,
                maxInLod = max,
                RequestFlags = flags,
                RequestedData = types
            };

            m_provider.ReadRange(ref req);
            flags = req.Flags;
            ProfilerShort.End();
        }
示例#30
0
        /// <param name="minVoxelChanged">Inclusive min.</param>
        /// <param name="maxVoxelChanged">Inclusive max.</param>
        private void storage_RangeChanged(Vector3I minChanged, Vector3I maxChanged, MyStorageDataTypeFlags changedData)
        {
            MyPrecalcComponent.AssertUpdateThread();

            ProfilerShort.Begin("MyVoxelGeometry.storage_RangeChanged");

            minChanged -= MyPrecalcComponent.InvalidatedRangeInflate;
            maxChanged += MyPrecalcComponent.InvalidatedRangeInflate;
            m_storage.ClampVoxelCoord(ref minChanged);
            m_storage.ClampVoxelCoord(ref maxChanged);
            var minCellChanged = minChanged >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;
            var maxCellChanged = maxChanged >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;

            using (m_lock.AcquireExclusiveUsing())
            {
                if (minCellChanged == Vector3I.Zero && maxCellChanged == m_cellsCount - 1)
                {
                    m_cellsByCoordinate.Clear();
                    m_coordinateToMesh.Clear();
                    m_isEmptyCache.Reset();
                }
                else
                {
                    MyCellCoord cell = new MyCellCoord();
                    cell.CoordInLod = minCellChanged;
                    for (var it = new Vector3I.RangeIterator(ref minCellChanged, ref maxCellChanged); it.IsValid(); it.GetNext(out cell.CoordInLod))
                    {
                        var key = cell.PackId64();
                        m_cellsByCoordinate.Remove(key);
                        m_coordinateToMesh.Remove(key);
                        SetEmpty(ref cell, false);
                    }
                }
            }

            ProfilerShort.End();
        }
示例#31
0
        void IMyOctreeLeafNode.ReadRange(MyStorageData target, MyStorageDataTypeFlags types, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, ref MyVoxelRequestFlags flags)
        {
            var lodShift     = m_cell.Lod - lodIndex;
            var leafMinInLod = m_cell.CoordInLod << lodShift;
            var min          = minInLod + leafMinInLod;
            var max          = maxInLod + leafMinInLod;

            AssertRangeIsInside(lodIndex, ref min, ref max);
            ProfilerShort.Begin("MyProviderLeaf.ReadRange");
            MyVoxelDataRequest req = new MyVoxelDataRequest()
            {
                Target        = target,
                Offset        = writeOffset,
                Lod           = lodIndex,
                minInLod      = min,
                maxInLod      = max,
                RequestFlags  = flags,
                RequestedData = types
            };

            m_provider.ReadRange(ref req);
            flags = req.Flags;
            ProfilerShort.End();
        }
示例#32
0
        public MyStorageData(Vector3I size, byte[] content = null, byte[] material = null, byte[] occlusion = null)
        {
            m_dataByType = new byte[(int)MyStorageDataTypeEnum.NUM_STORAGE_DATA_TYPES][];

            Resize(size);

            if (content != null)
            {
                m_storedTypes |= MyStorageDataTypeFlags.Content;
                this[MyStorageDataTypeEnum.Content] = content;
            }

            if (material != null)
            {
                m_storedTypes |= MyStorageDataTypeFlags.Material;
                this[MyStorageDataTypeEnum.Material] = material;
            }

            if (occlusion != null)
            {
                m_storedTypes |= MyStorageDataTypeFlags.Occlusion;
                this[MyStorageDataTypeEnum.Occlusion] = occlusion;
            }
        }
示例#33
0
        /// <summary>
        /// Invalidates voxel cache
        /// </summary>
        /// <param name="minChanged">Inclusive min</param>
        /// <param name="maxChanged">Inclusive max</param>
        private void storage_RangeChanged(Vector3I minChanged, Vector3I maxChanged, MyStorageDataTypeFlags dataChanged)
        {
            ProfilerShort.Begin("MyVoxelMap::storage_RangeChanged");

            Debug.Assert(minChanged.IsInsideInclusive(ref m_storageMin, ref m_storageMax) &&
                maxChanged.IsInsideInclusive(ref m_storageMin, ref m_storageMax));

            // Physics doesn't care about materials, just shape of things.
            if ((dataChanged & MyStorageDataTypeFlags.Content) != 0 &&
                Physics != null)
            {
                Physics.InvalidateRange(minChanged, maxChanged);
            }

            if (Render is MyRenderComponentVoxelMap)
            {
                (Render as MyRenderComponentVoxelMap).InvalidateRange(minChanged, maxChanged);
            }

            ContentChanged = true;
            ProfilerShort.End();

        }
示例#34
0
        public MyStorageData(MyStorageDataTypeFlags typesToStore = MyStorageDataTypeFlags.ContentAndMaterial)
        {
            m_storedTypes = typesToStore;

            m_dataByType = new byte[(int)MyStorageDataTypeEnum.NUM_STORAGE_DATA_TYPES][];
        }
示例#35
0
        protected override void ReadRangeInternal(MyStorageDataCache target, ref Vector3I targetWriteOffset,
            MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelCoordStart, ref Vector3I lodVoxelCoordEnd)
        {
            bool hasLod = lodIndex <= (m_treeHeight + LeafLodCount);
            Debug.Assert(dataToRead != MyStorageDataTypeFlags.None);
            if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
            {
                if (hasLod)
                {
                    ReadRange(target, ref targetWriteOffset, MyStorageDataTypeEnum.Content, m_treeHeight, m_contentNodes, m_contentLeaves, lodIndex, ref lodVoxelCoordStart, ref lodVoxelCoordEnd);
                }
            }

            if ((dataToRead & MyStorageDataTypeFlags.Material) != 0)
            {
                if (hasLod)
                {
                    ReadRange(target, ref targetWriteOffset, MyStorageDataTypeEnum.Material, m_treeHeight, m_materialNodes, m_materialLeaves, lodIndex, ref lodVoxelCoordStart, ref lodVoxelCoordEnd);
                }
            }
        }
            public void ReadLod(MyStorageData target, MyStorageDataTypeFlags dataTypes, ref Vector3I targetOffset, int lodIndex, ref Vector3I min, ref Vector3I max)
            {
                Debug.Assert(min.IsInsideInclusive(Vector3I.Zero, MaxVector >> lodIndex)
                    && max.IsInsideInclusive(Vector3I.Zero, MaxVector >> lodIndex));

                //using (Lock.AcquireSharedUsing())
                {
                    if (lodIndex > MaxLod)
                        UpdateLodData(lodIndex);

                    if (dataTypes.Requests(MyStorageDataTypeEnum.Content))
                    {
                        ReadLod(target, MyStorageDataTypeEnum.Content, Content, targetOffset, lodIndex, min, max);
                    }

                    if (dataTypes.Requests(MyStorageDataTypeEnum.Material))
                    {
                        ReadLod(target, MyStorageDataTypeEnum.Material, Material, targetOffset, lodIndex, min, max);
                    }
                }

                HitCount++;
            }
        private void GetChunk(ref Vector3I coord, out VoxelChunk chunk, MyStorageDataTypeFlags required)
        {
            using (m_cacheLock.AcquireExclusiveUsing())
            {
                if (!m_cachedChunks.TryGetValue(coord, out chunk))
                {
                    chunk = new VoxelChunk(coord);

                    var rangeStart = coord << VoxelChunk.SizeBits;
                    var rangeEnd = ((coord + 1) << VoxelChunk.SizeBits) - 1;

                    if (required != 0)
                    {
                        using (m_storageLock.AcquireSharedUsing())
                            ReadDatForChunk(chunk, required);
                    }

                    m_chunksbyAge.Enqueue(coord);
                    m_cachedChunks.Add(coord, chunk);

                    var bb = new BoundingBox(rangeStart, rangeEnd);

                    chunk.TreeProxy = m_cacheMap.AddProxy(ref bb, chunk, 0);
                }
                else if ((chunk.Cached & required) != required)
                {
                    using (m_storageLock.AcquireSharedUsing())
                        ReadDatForChunk(chunk, required & ~chunk.Cached);
                }

            }
        }
示例#38
0
        private void storage_RangeChangedPlanet(Vector3I minChanged, Vector3I maxChanged, MyStorageDataTypeFlags dataChanged)
        {
            ProfilerShort.Begin("MyVoxelMap::storage_RangeChanged");
            Vector3I minSector = minChanged / PHYSICS_SECTOR_SIZE_METERS;
            Vector3I maxSector = maxChanged / PHYSICS_SECTOR_SIZE_METERS;

            MyVoxelPhysics voxelMap;

            if (m_physicsShapes != null)
            {
                for (var it = new Vector3I_RangeIterator(ref minSector, ref maxSector);
                     it.IsValid(); it.MoveNext())
                {
                    if (m_physicsShapes.TryGetValue(it.Current, out voxelMap))
                    {
                        if (voxelMap != null)
                        {
                            voxelMap.OnStorageChanged(minChanged, maxChanged, dataChanged);
                        }
                    }
                }
            }

            if (Render is MyRenderComponentVoxelMap)
            {
                (Render as MyRenderComponentVoxelMap).InvalidateRange(minChanged, maxChanged);
            }

            OnRangeChanged(minChanged, maxChanged, dataChanged);
            ProfilerShort.End();
        }
示例#39
0
 void ModAPI.Interfaces.IMyStorage.WriteRange(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin, Vector3I voxelRangeMax)
 {
     WriteRange(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
 }
示例#40
0
 protected abstract void ResetInternal(MyStorageDataTypeFlags dataToReset);
示例#41
0
 protected abstract void WriteRangeInternal(MyStorageData source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax);
示例#42
0
        private void ReadRangeAdviseCache(MyStorageData target, MyStorageDataTypeFlags dataToRead, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax)
        {
            // Skip if too many cached cells
            if (m_pendingChunksToWrite.Count > WriteCacheCap)
            {
                ReadRange(target, dataToRead, 0, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
                return;
            }

            if (CachedWrites)
            {
                var lodDiff = VoxelChunk.SizeBits;

                var chunkMin = lodVoxelRangeMin >> lodDiff;
                var chunkMax = lodVoxelRangeMax >> lodDiff;

                var pos = Vector3I.Zero;
                for (pos.Z = chunkMin.Z; pos.Z <= chunkMax.Z; ++pos.Z)
                    for (pos.Y = chunkMin.Y; pos.Y <= chunkMax.Y; ++pos.Y)
                        for (pos.X = chunkMin.X; pos.X <= chunkMax.X; ++pos.X)
                        {
                            var celPos = pos << lodDiff;

                            var lodCkStart = pos << lodDiff;
                            lodCkStart = Vector3I.Max(lodCkStart, lodVoxelRangeMin);

                            var targetOffset = lodCkStart - lodVoxelRangeMin;

                            var lodCkEnd = ((pos + 1) << lodDiff) - 1;
                            lodCkEnd = Vector3I.Min(lodCkEnd, lodVoxelRangeMax);

                            VoxelChunk chunk;
                            GetChunk(ref pos, out chunk, dataToRead);

                            lodCkStart -= celPos;
                            lodCkEnd -= celPos;

                            using (chunk.Lock.AcquireSharedUsing())
                                chunk.ReadLod(target, dataToRead, ref targetOffset, 0, ref lodCkStart, ref lodCkEnd);
                        }
            }
        }
示例#43
0
        public void ReadRange(MyStorageData target, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax, ref MyVoxelRequestFlags requestFlags)
        {
            ProfilerShort.Begin(GetType().Name + ".ReadRange");

            if ((dataToRead & MyStorageDataTypeFlags.Content) != 0)
            {
                target.ClearContent(0);
            }

            if (requestFlags.HasFlags(MyVoxelRequestFlags.AdviseCache) && lodIndex == 0 && CachedWrites)
            {
                ReadRangeAdviseCache(target, dataToRead, ref lodVoxelRangeMin, ref lodVoxelRangeMax);
                ProfilerShort.End();
                return;
            }

            if (CachedWrites && lodIndex <= VoxelChunk.SizeBits && m_cachedChunks.Count > 0)
            {
                // read occlusion separate
                if (dataToRead.Requests(MyStorageDataTypeEnum.Occlusion))
                {
                    using (m_storageLock.AcquireSharedUsing())
                        ReadRangeInternal(target, ref Vector3I.Zero, MyStorageDataTypeFlags.Occlusion, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref requestFlags);

                    dataToRead ^= MyStorageDataTypeFlags.Occlusion;
                }

                if (m_tmpChunks == null) m_tmpChunks = new List<VoxelChunk>();

                var lodDiff = VoxelChunk.SizeBits - lodIndex;

                // We fetch which chunks overlap our current range from the chunk tree, then we read all data from storage and apply those changes
                var querybb = new BoundingBox(lodVoxelRangeMin << lodIndex, lodVoxelRangeMax << lodIndex);

                using (m_cacheLock.AcquireSharedUsing())
                    m_cacheMap.OverlapAllBoundingBox(ref querybb, m_tmpChunks, 0, false);

                if (m_tmpChunks.Count > 0)
                {
                    var chunkMin = lodVoxelRangeMin >> lodDiff;
                    var chunkMax = lodVoxelRangeMax >> lodDiff;

                    bool readFromStorage = false;

                    if ((chunkMax - chunkMin + 1).Size > m_tmpChunks.Count)
                    {
                        using (m_storageLock.AcquireSharedUsing())
                            ReadRangeInternal(target, ref Vector3I.Zero, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref requestFlags);
                        readFromStorage = true;
                    }

                    for (int i = 0; i < m_tmpChunks.Count; ++i)
                    {
                        var chunk = m_tmpChunks[i];
                        var pos = chunk.Coords;

                        var celPos = pos << lodDiff;

                        var lodCkStart = pos << lodDiff;
                        lodCkStart = Vector3I.Max(lodCkStart, lodVoxelRangeMin);

                        var targetOffset = lodCkStart - lodVoxelRangeMin;

                        var lodCkEnd = ((pos + 1) << lodDiff) - 1;
                        lodCkEnd = Vector3I.Min(lodCkEnd, lodVoxelRangeMax);

                        lodCkStart -= celPos;
                        lodCkEnd -= celPos;

                        if ((chunk.Cached & dataToRead) != dataToRead && !readFromStorage)
                        {
                            using (m_storageLock.AcquireSharedUsing())
                                if ((chunk.Cached & dataToRead) != dataToRead)
                                    ReadDatForChunk(chunk, dataToRead);
                        }

                        using (chunk.Lock.AcquireSharedUsing())
                            chunk.ReadLod(target, !readFromStorage ? dataToRead : dataToRead & chunk.Cached, ref targetOffset, lodIndex, ref lodCkStart, ref lodCkEnd);
                    }

                    m_tmpChunks.Clear();
                    ProfilerShort.End();
                    return;
                }
            }

            // all else
            using (m_storageLock.AcquireSharedUsing())
                ReadRangeInternal(target, ref Vector3I.Zero, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref requestFlags);

            ProfilerShort.End();
        }
示例#44
0
 public void ReadRange(MyStorageData target, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax)
 {
     MyVoxelRequestFlags flags = 0;
     ReadRange(target, dataToRead, lodIndex, ref lodVoxelRangeMin, ref lodVoxelRangeMax, ref flags);
 }
示例#45
0
        public void WriteRange(MyStorageData source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax)
        {
            MyPrecalcComponent.AssertUpdateThread();

            ProfilerShort.Begin(GetType().Name + ".WriteRange");
            try
            {
                m_compressedData = null;

                if (CachedWrites && (m_pendingChunksToWrite.Count < WriteCacheCap || OverlapsAnyCachedCell(voxelRangeMin, voxelRangeMax)))
                {
                    var lodDiff = VoxelChunk.SizeBits;

                    var chunkMin = voxelRangeMin >> lodDiff;
                    var chunkMax = voxelRangeMax >> lodDiff;

                    var pos = Vector3I.Zero;
                    for (pos.Z = chunkMin.Z; pos.Z <= chunkMax.Z; ++pos.Z)
                        for (pos.Y = chunkMin.Y; pos.Y <= chunkMax.Y; ++pos.Y)
                            for (pos.X = chunkMin.X; pos.X <= chunkMax.X; ++pos.X)
                            {
                                var celPos = pos << lodDiff;

                                var lodCkStart = pos << lodDiff;
                                lodCkStart = Vector3I.Max(lodCkStart, voxelRangeMin);

                                var lodCkEnd = ((pos + 1) << lodDiff) - 1;
                                lodCkEnd = Vector3I.Min(lodCkEnd, voxelRangeMax);

                                var targetOffset = lodCkStart - voxelRangeMin;

                                VoxelChunk chunk;
                                // Do not read the chunk if the range overlaps the whole chunk
                                var toRead = (lodCkEnd - lodCkStart + 1).Size != VoxelChunk.Volume ? dataToWrite : 0;
                                GetChunk(ref pos, out chunk, toRead);

                                lodCkStart -= celPos;
                                lodCkEnd -= celPos;

                                using (chunk.Lock.AcquireExclusiveUsing())
                                {
                                    bool dirty = chunk.Dirty != 0;
                                    chunk.Write(source, dataToWrite, ref targetOffset, ref lodCkStart, ref lodCkEnd);
                                    if (!dirty) m_pendingChunksToWrite.Enqueue(pos);
                                }
                            }
                }
                else
                {
                    using (m_storageLock.AcquireExclusiveUsing())
                        WriteRangeInternal(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
                }

                ProfilerShort.BeginNextBlock(GetType().Name + ".OnRangeChanged");

                OnRangeChanged(voxelRangeMin, voxelRangeMax, dataToWrite);

            }
            finally
            {
                ProfilerShort.End();
            }
        }
示例#46
0
        /// <summary>
        /// Resets the data specified by flags to values from data provider, or default if no provider is assigned.
        /// </summary>
        /// <param name="dataToReset"></param>
        public void Reset(MyStorageDataTypeFlags dataToReset)
        {
            MyPrecalcComponent.AssertUpdateThread();

            using (m_storageLock.AcquireExclusiveUsing())
            {
                m_compressedData = null;
                ResetInternal(dataToReset);
            }
            OnRangeChanged(Vector3I.Zero, Size - 1, dataToReset);
        }
        /// <param name="minVoxelChanged">Inclusive min.</param>
        /// <param name="maxVoxelChanged">Inclusive max.</param>
        private void storage_RangeChanged(Vector3I minChanged, Vector3I maxChanged, MyStorageDataTypeFlags changedData)
        {
            MyPrecalcComponent.AssertUpdateThread();

            ProfilerShort.Begin("MyVoxelGeometry.storage_RangeChanged");

            minChanged -= MyPrecalcComponent.InvalidatedRangeInflate;
            maxChanged += MyPrecalcComponent.InvalidatedRangeInflate;
            m_storage.ClampVoxelCoord(ref minChanged);
            m_storage.ClampVoxelCoord(ref maxChanged);
            var minCellChanged = minChanged >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;
            var maxCellChanged = maxChanged >> MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS_BITS;
            using (m_lock.AcquireExclusiveUsing())
            {
                if (minCellChanged == Vector3I.Zero && maxCellChanged == m_cellsCount - 1)
                {
                    m_cellsByCoordinate.Clear();
                    m_coordinateToMesh.Clear();
                    m_isEmptyCache.Reset();
                }
                else
                {
                    MyCellCoord cell = new MyCellCoord();
                    cell.CoordInLod = minCellChanged;
                    for (var it = new Vector3I_RangeIterator(ref minCellChanged, ref maxCellChanged); it.IsValid(); it.GetNext(out cell.CoordInLod))
                    {
                        var key = cell.PackId64();
                        m_cellsByCoordinate.Remove(key);
                        m_coordinateToMesh.Remove(key);
                        SetEmpty(ref cell, false);
                    }
                }
            }

            ProfilerShort.End();
        }
示例#48
0
 protected abstract void ReadRangeInternal(MyStorageData target, ref Vector3I targetWriteRange, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax, ref MyVoxelRequestFlags requestFlags);
        private void OnStorageChanged(Vector3I minVoxelChanged, Vector3I maxVoxelChanged, MyStorageDataTypeFlags changedData)
        {
            if (!changedData.HasFlag(MyStorageDataTypeFlags.Content))
            {
                return;
            }

            InvalidateRange(minVoxelChanged, maxVoxelChanged);
        }
示例#50
0
        protected override void ResetInternal(MyStorageDataTypeFlags dataToReset)
        {
            bool resetContent = (dataToReset & MyStorageDataTypeFlags.Content) != 0;
            bool resetMaterials = (dataToReset & MyStorageDataTypeFlags.Material) != 0;

            if (resetContent)
            {
                m_contentLeaves.Clear();
                m_contentNodes.Clear();
            }

            if (resetMaterials)
            {
                m_materialLeaves.Clear();
                m_materialNodes.Clear();
            }

            if (m_dataProvider != null)
            {
                var cellCoord = new MyCellCoord(m_treeHeight, ref Vector3I.Zero);
                var leafId = cellCoord.PackId64();
                cellCoord.Lod += LeafLodCount;
                var end = Size - 1;
                if (resetContent)
                {
                    m_contentLeaves.Add(leafId,
                        new MyProviderLeaf(m_dataProvider, MyStorageDataTypeEnum.Content, ref cellCoord));
                }
                if (resetMaterials)
                {
                    m_materialLeaves.Add(leafId,
                        new MyProviderLeaf(m_dataProvider, MyStorageDataTypeEnum.Material, ref cellCoord));
                }
            }
            else
            {
                var nodeId = new MyCellCoord(m_treeHeight - 1, ref Vector3I.Zero).PackId64();
                if (resetContent)
                {
                    m_contentNodes.Add(nodeId, new MyOctreeNode());
                }
                if (resetMaterials)
                {
                    m_materialNodes.Add(nodeId, new MyOctreeNode());
                }
            }
        }
 void VRage.ModAPI.IMyStorage.WriteRange(MyStorageData source, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin, Vector3I voxelRangeMax)
 {
     WriteRange(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
 }
示例#52
0
 protected internal void OnRangeChanged(Vector3I voxelRangeMin, Vector3I voxelRangeMax, MyStorageDataTypeFlags changedData)
 {
     if (RangeChanged != null)
     {
         RangeChanged(this, voxelRangeMin, voxelRangeMax, changedData);
     }
 }
 void IMyOctreeLeafNode.ReadRange(MyStorageData target, MyStorageDataTypeFlags types, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod, ref MyVoxelRequestFlags flags)
 {
     m_octree.ReadRange(target, m_dataType, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
 }
 void ModAPI.Interfaces.IMyStorage.WriteRange(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin,  Vector3I voxelRangeMax)
 {
     WriteRange(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
 }
            public void Write(MyStorageData source, MyStorageDataTypeFlags dataTypes, ref Vector3I targetOffset, ref Vector3I min, ref Vector3I max)
            {
                //using (Lock.AcquireExclusiveUsing())
                {
                    //if (false) // disabled for testing :D
                    if (dataTypes.Requests(MyStorageDataTypeEnum.Content))
                    {
                        Write(source, MyStorageDataTypeEnum.Content, Content, targetOffset, min, max);
                    }

                    if (dataTypes.Requests(MyStorageDataTypeEnum.Material))
                    {
                        Write(source, MyStorageDataTypeEnum.Material, Material, targetOffset, min, max);
                    }

                    Cached |= dataTypes;

                    Dirty |= dataTypes;
                    MaxLod = 0;
                }
            }
示例#56
0
        private void storage_RangeChangedPlanet(Vector3I minChanged, Vector3I maxChanged, MyStorageDataTypeFlags dataChanged)
        {
            ProfilerShort.Begin("MyVoxelMap::storage_RangeChanged");
            Vector3I minSector = minChanged / PHYSICS_SECTOR_SIZE_METERS;
            Vector3I maxSector = maxChanged/PHYSICS_SECTOR_SIZE_METERS;

            Vector3I increment = m_storage.Size / (m_numCells+1);
            for (var it = new Vector3I.RangeIterator(ref minSector, ref maxSector);
                it.IsValid(); it.MoveNext())
            {
                MyVoxelPhysics voxelMap = CreatePhysicsShape(ref increment, ref it);

                voxelMap.OnStorageChanged(minChanged, maxChanged, dataChanged);
            }

            if (Render is MyRenderComponentVoxelMap)
            {
                (Render as MyRenderComponentVoxelMap).InvalidateRange(minChanged, maxChanged);
            }

            ProfilerShort.End();
        }
        private void ReadDatForChunk(VoxelChunk chunk, MyStorageDataTypeFlags data)
        {
            var rangeStart = chunk.Coords << VoxelChunk.SizeBits;
            var rangeEnd = ((chunk.Coords + 1) << VoxelChunk.SizeBits) - 1;

            MyStorageData storage = chunk.MakeData();

            MyVoxelRequestFlags flags = 0;

            ReadRangeInternal(storage, ref Vector3I.Zero, data, 0, ref rangeStart, ref rangeEnd, ref flags);

            chunk.Cached |= data;
            chunk.MaxLod = 0;
        }
 void IMyStorageDataProvider.ReadRange(MyStorageData target, MyStorageDataTypeFlags dataType, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
 {
     if (dataType.Requests(MyStorageDataTypeEnum.Content))
         ReadContentRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
     else
         ReadMaterialRange(target, ref writeOffset, lodIndex, ref minInLod, ref maxInLod);
 }
示例#59
0
        protected override void WriteRangeInternal(MyStorageDataCache source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax)
        {
            ProfilerShort.Begin("MyOctreeStorage.WriteRange");

            Debug.Assert(dataToWrite != MyStorageDataTypeFlags.None);
            if ((dataToWrite & MyStorageDataTypeFlags.Content) != 0)
            {
                var args = new WriteRangeArgs()
                {
                    DataFilter = MyOctreeNode.ContentFilter,
                    DataType = MyStorageDataTypeEnum.Content,
                    Leaves = m_contentLeaves,
                    Nodes = m_contentNodes,
                    Provider = m_dataProvider,
                    Source = source,
                };
                WriteRange(ref args, 0, m_treeHeight + LeafLodCount, Vector3I.Zero, ref voxelRangeMin, ref voxelRangeMax);
            }

            if ((dataToWrite & MyStorageDataTypeFlags.Material) != 0)
            {
                var args = new WriteRangeArgs()
                {
                    DataFilter = MyOctreeNode.MaterialFilter,
                    DataType = MyStorageDataTypeEnum.Material,
                    Leaves = m_materialLeaves,
                    Nodes = m_materialNodes,
                    Provider = m_dataProvider,
                    Source = source,
                };
                WriteRange(ref args, 0, m_treeHeight + LeafLodCount, Vector3I.Zero, ref voxelRangeMin, ref voxelRangeMax);
            }

            ProfilerShort.End();
        }
示例#60
0
        /// <summary>
        /// For debugging/testing only! This can be very slow for large storage.
        /// </summary>
        public void Voxelize(MyStorageDataTypeFlags data)
        {
            var cache = new MyStorageDataCache();

            cache.Resize(new Vector3I(LeafSizeInVoxels));
            var leafCount = (Size / LeafSizeInVoxels);
            Vector3I leaf = Vector3I.Zero;
            var end = leafCount - 1;
            for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref end);
                it.IsValid();
                it.GetNext(out leaf))
            {
                Debug.WriteLine("Processing {0} / {1}", leaf, end);
                var min = leaf * LeafSizeInVoxels;
                var max = min + (LeafSizeInVoxels - 1);
                ReadRangeInternal(cache, ref Vector3I.Zero, data, 0, ref min, ref max);
                WriteRangeInternal(cache, data, ref min, ref max);
            }

            OnRangeChanged(Vector3I.Zero, Size - 1, data);
        }