コード例 #1
0
        public void DoWork(WorkData workData = null)
        {
            try
            {
                // LOD above is 5 we decrease it by 2 so our LOD now is 3
                Min <<= 2;
                Max <<= 2;

                MyStorageData cache = Cache;
                cache.Resize(new Vector3I(8));

                for (int x = Min.X; x <= Max.X; x++)
                {
                    for (int y = Min.Y; y <= Max.Y; y++)
                    {
                        for (int z = Min.Z; z <= Max.Z; z++)
                        {
                            ProcessCell(cache, VoxelMap.Storage, new Vector3I(x, y, z), 0);
                        }
                    }
                }

                Callback();
            }
            catch (Exception e)
            {
                Logging.Instance.WriteLine($"{e}");
                Callback();
            }
        }
コード例 #2
0
        void VRage.ModAPI.IMyStorage.ReadRange(MyStorageData 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);
        }
コード例 #3
0
        /// <summary>
        /// Create a new Asteroid, ready for some manipulation.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="size">Currently the size must be multiple of 64, eg. 128x64x256</param>
        /// <param name="position"></param>
        public static IMyVoxelMap CreateNewAsteroid(string storageName, Vector3I size, Vector3D position)
        {
            var cache = new MyStorageData();

            // new storage is created completely full
            // no geometry will be created because that requires full-empty transition
            var storage = MyAPIGateway.Session.VoxelMaps.CreateStorage(size);

            // midspace's Note: The following steps appear redundant, as the storage space is created empty.
            /*
            // always ensure cache is large enough for whatever you plan to load into it
            cache.Resize(size);

            // range is specified using inclusive min and max coordinates
            // Choose a reasonable size of range you plan to work with, to avoid high memory usage
            // memory size in bytes required by cache is computed as Size.X * Size.Y * Size.Z * 2, where Size is size of the range.
            // min and max coordinates are inclusive, so if you want to read 8^3 voxels starting at coordinate [8,8,8], you
            // should pass in min = [8,8,8], max = [15,15,15]
            // For LOD, you should only use LOD0 or LOD1
            // When you write data inside cache back to storage, you always write to LOD0 (the most detailed LOD), LOD1 can only be read from.
            storage.ReadRange(cache, MyStorageDataTypeFlags.All, 0, Vector3I.Zero, size - 1);

            // resets all loaded content to empty
            cache.ClearContent(0);

            // write new data back to the storage
            storage.WriteRange(cache, MyStorageDataTypeFlags.Content, Vector3I.Zero, size - 1);
            */

            return MyAPIGateway.Session.VoxelMaps.CreateVoxelMap(storageName, storage, position, 0);
        }
コード例 #4
0
        public static MyStorageData GetVoxelCacheInSphere(this IMyVoxelBase Voxel, BoundingSphereD Sphere, out Vector3I refCorner, out Vector3I refMaxCorner)
        {
            if (Voxel == null)
            {
                throw new ArgumentNullException(nameof(Voxel));
            }
            if (Voxel.Storage == null)
            {
                throw new ArgumentException("Voxel.Storage is null");
            }

            BoundingBoxD SphereBound = VoxelHelpers.GetWorldBoundariesForSphere(Sphere);
            Vector3I     minCorner, maxCorner;

            Voxel.MyVoxelGenerator_ComputeShapeBounds(ref SphereBound, out minCorner, out maxCorner);
            Vector3I minCorner1 = minCorner - 1;
            Vector3I maxCorner1 = maxCorner + 1;

            Voxel.Storage_ClampVoxelCoord(ref minCorner1, 1);
            Voxel.Storage_ClampVoxelCoord(ref maxCorner1, 1);
            MyStorageData cache = new MyStorageData(MyStorageDataTypeFlags.ContentAndMaterial);

            cache.Resize(minCorner1, maxCorner1);
            MyVoxelRequestFlags myVoxelRequestFlags = MyVoxelRequestFlags.AdviseCache | MyVoxelRequestFlags.ConsiderContent;

            Voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, minCorner1, maxCorner1, ref myVoxelRequestFlags);
            refCorner    = minCorner1;
            refMaxCorner = maxCorner1;
            return(cache);
        }
コード例 #5
0
            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++;
            }
コード例 #6
0
        internal void BuildFrom(MyStorageData source)
        {
            Debug.Assert(source.Size3D == new Vector3I(m_octree.TreeWidth));
            var enumer = new MyStorageData.MortonEnumerator(source, m_dataType);

            m_octree.Build(enumer);
        }
コード例 #7
0
        public bool TryGetUniformValue(out byte uniformValue)
        {
            MyStorageData      filteredValueBuffer = FilteredValueBuffer;
            MyVoxelDataRequest request             = new MyVoxelDataRequest {
                Target        = null,
                Offset        = Vector3I.Zero,
                Lod           = this.m_cell.Lod,
                MinInLod      = this.m_cell.CoordInLod,
                MaxInLod      = this.m_cell.CoordInLod,
                RequestedData = this.m_dataType.ToFlags()
            };

            this.m_provider.ReadRange(ref request, true);
            if ((request.Flags & MyVoxelRequestFlags.EmptyData) > 0)
            {
                uniformValue = (this.m_dataType == MyStorageDataTypeEnum.Material) ? ((byte)0xff) : ((byte)0);
                return(true);
            }
            if ((this.m_dataType != MyStorageDataTypeEnum.Content) || ((request.Flags & MyVoxelRequestFlags.FullContent) <= 0))
            {
                uniformValue = 0;
                return(false);
            }
            uniformValue = 0xff;
            return(true);
        }
コード例 #8
0
        byte IMyOctreeLeafNode.GetFilteredValue()
        {
            MyStorageData filteredValueBuffer = FilteredValueBuffer;

            this.m_provider.ReadRange(filteredValueBuffer, this.m_dataType.ToFlags(), ref Vector3I.Zero, this.m_cell.Lod, ref this.m_cell.CoordInLod, ref this.m_cell.CoordInLod);
            return((this.m_dataType == MyStorageDataTypeEnum.Material) ? filteredValueBuffer.Material(0) : filteredValueBuffer.Content(0));
        }
コード例 #9
0
ファイル: MyVoxelBase.cs プロジェクト: feiyuren233/vrage
        public void GetFilledStorageBounds(out Vector3I min, out Vector3I max)
        {
            min = Vector3I.MaxValue;
            max = Vector3I.MinValue;

            Vector3I sz = Size;

            Vector3I SMax = Size - 1;

            MyStorageData data = new MyStorageData();

            data.Resize(Size);

            Storage.ReadRange(data, MyStorageDataTypeFlags.Content, 0, Vector3I.Zero, SMax);

            for (int z = 0; z < sz.Z; ++z)
            {
                for (int y = 0; y < sz.Y; ++y)
                {
                    for (int x = 0; x < sz.X; ++x)
                    {
                        if (data.Content(x, y, z) > MyVoxelConstants.VOXEL_ISO_LEVEL)
                        {
                            Vector3I l = Vector3I.Max(new Vector3I(x - 1, y - 1, z - 1), Vector3I.Zero);
                            min = Vector3I.Min(l, min);

                            Vector3I h = Vector3I.Min(new Vector3I(x + 1, y + 1, z + 1), SMax);
                            max = Vector3I.Max(h, max);
                        }
                    }
                }
            }
        }
        private bool FindMaterial(IMyStorage storage, byte[] findMaterial)
        {
            if (findMaterial.Length == 0)
            {
                return(false);
            }

            var oldCache = new MyStorageData();

            oldCache.Resize(storage.Size);
            storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 2, Vector3I.Zero, storage.Size - 1);
            //MyAPIGateway.Utilities.ShowMessage("check", string.Format("SizeLinear {0}  {1}.", oldCache.SizeLinear, oldCache.StepLinear));

            Vector3I p;

            for (p.Z = 0; p.Z < storage.Size.Z; ++p.Z)
            {
                for (p.Y = 0; p.Y < storage.Size.Y; ++p.Y)
                {
                    for (p.X = 0; p.X < storage.Size.X; ++p.X)
                    {
                        var content  = oldCache.Content(ref p);
                        var material = oldCache.Material(ref p);

                        if (content > 0 && findMaterial.Contains(material))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
コード例 #11
0
            public override void Perform()
            {
                MyVoxelBase base2 = MySession.Static.VoxelMaps.TryGetVoxelMapByNameStart(this.m_voxelName);

                if (base2 != null)
                {
                    base2.Storage.WriteRange(MyStorageData.FromBase64(this.m_data), this.m_dataType, this.m_voxelMin, this.m_voxelMax, true, false);
                }
            }
コード例 #12
0
        public static MyVoxelMaterialDefinition GetMaterialAt(this VRage.Game.Voxels.IMyStorage self, ref Vector3D localCoords)
        {
            Vector3I      lodVoxelRangeMin = Vector3D.Floor(localCoords / 1.0);
            MyStorageData target           = new MyStorageData(MyStorageDataTypeFlags.All);

            target.Resize(Vector3I.One);
            self.ReadRange(target, MyStorageDataTypeFlags.Material, 0, lodVoxelRangeMin, lodVoxelRangeMin);
            return(MyDefinitionManager.Static.GetVoxelMaterialDefinition(target.Material(0)));
        }
コード例 #13
0
        void VRage.ModAPI.IMyStorage.ReadRange(MyStorageData 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);
        }
コード例 #14
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();
            }
        }
コード例 #15
0
        public static MyVoxelMaterialDefinition GetMaterialAt(this VRage.Game.Voxels.IMyStorage self, ref Vector3I voxelCoords)
        {
            MyStorageData target = new MyStorageData(MyStorageDataTypeFlags.All);

            target.Resize(Vector3I.One);
            self.ReadRange(target, MyStorageDataTypeFlags.All, 0, voxelCoords, voxelCoords);
            byte materialIndex = target.Material(0);

            return((materialIndex != 0xff) ? MyDefinitionManager.Static.GetVoxelMaterialDefinition(materialIndex) : null);
        }
コード例 #16
0
            void ShrinkVMap()
            {
                Vector3I min, max;

                m_selectedVoxel.GetFilledStorageBounds(out min, out max);

                MyVoxelMapStorageDefinition def = null;

                if (m_selectedVoxel.AsteroidName != null)
                {
                    MyDefinitionManager.Static.TryGetVoxelMapStorageDefinition(m_selectedVoxel.AsteroidName, out def);
                }

                var origSize = m_selectedVoxel.Size;

                var tightSize = max - min + 1;

                var storage = new MyOctreeStorage(null, tightSize);

                var offset = (storage.Size - tightSize) / 2 + 1;

                MyStorageData data = new MyStorageData();

                data.Resize(tightSize);

                m_selectedVoxel.Storage.ReadRange(data, MyStorageDataTypeFlags.ContentAndMaterial, 0, min, max);

                min = offset;
                max = offset + tightSize - 1;
                storage.WriteRange(data, MyStorageDataTypeFlags.ContentAndMaterial, ref min, ref max);

                var newMap = MyWorldGenerator.AddVoxelMap(m_selectedVoxel.StorageName, storage, m_selectedVoxel.WorldMatrix);

                m_selectedVoxel.Close();

                newMap.Save = true;

                if (def == null)
                {
                    ShowAlert("Voxel map {0} does not have a definition, the shrunk voxel map will be saved with the world instead.", m_selectedVoxel.StorageName);
                }
                else
                {
                    byte[] cVmapData;
                    newMap.Storage.Save(out cVmapData);

                    using (var ostream = MyFileSystem.OpenWrite(Path.Combine(MyFileSystem.ContentPath, def.StorageFile), FileMode.Open))
                    {
                        ostream.Write(cVmapData, 0, cVmapData.Length);
                    }
                    var notification = new MyHudNotification(MyStringId.GetOrCompute("Voxel prefab {0} updated succesfuly (size changed from {1} to {2})."), 4000);
                    notification.SetTextFormatArguments(def.Id.SubtypeName, origSize, storage.Size);
                    MyHud.Notifications.Add(notification);
                }
            }
コード例 #17
0
 public static void PaintInShape(MyVoxelBase voxelMap, MyShape shape, byte materialIdx)
 {
     using (voxelMap.Pin())
     {
         if (!voxelMap.MarkedForClose)
         {
             Vector3I vectori;
             Vector3I maxCorner;
             Vector3I minCorner;
             GetVoxelShapeDimensions(voxelMap, shape, out minCorner, out maxCorner, out vectori);
             if (m_cache == null)
             {
                 m_cache = new MyStorageData(MyStorageDataTypeFlags.All);
             }
             Vector3I_RangeIterator it = new Vector3I_RangeIterator(ref Vector3I.Zero, ref vectori);
             while (true)
             {
                 Vector3I vectori2;
                 Vector3I vectori3;
                 if (!it.IsValid())
                 {
                     MySandboxGame.Static.Invoke(delegate {
                         if (voxelMap.Storage != null)
                         {
                             voxelMap.Storage.NotifyChanged(minCorner, maxCorner, MyStorageDataTypeFlags.All);
                         }
                     }, "PaintInShape notify");
                     break;
                 }
                 GetCellCorners(ref minCorner, ref maxCorner, ref it, out vectori2, out vectori3);
                 m_cache.Resize(vectori2, vectori3);
                 MyVoxelRequestFlags considerContent = MyVoxelRequestFlags.ConsiderContent;
                 voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.All, 0, vectori2, vectori3, ref considerContent);
                 Vector3I_RangeIterator iterator2 = new Vector3I_RangeIterator(ref vectori2, ref vectori3);
                 while (true)
                 {
                     Vector3D vectord;
                     if (!iterator2.IsValid())
                     {
                         voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.Material, vectori2, vectori3, false, true);
                         it.MoveNext();
                         break;
                     }
                     Vector3I p = iterator2.Current - vectori2;
                     MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxelMap.PositionLeftBottomCorner, ref iterator2.Current, out vectord);
                     if ((shape.GetVolume(ref vectord) > 0.5f) && (m_cache.Material(ref p) != 0xff))
                     {
                         m_cache.Material(ref p, materialIdx);
                     }
                     iterator2.MoveNext();
                 }
             }
         }
     }
 }
コード例 #18
0
        private static bool HasContentAt(this MyVoxelBase voxel, ref Vector3D localPosition)
        {
            Vector3I voxelCoord;

            MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref localPosition, out voxelCoord);
            MyStorageData cache = new MyStorageData();

            cache.Resize(Vector3I.One);
            voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, ref voxelCoord, ref voxelCoord);
            return(cache.Content(0) > MyVoxelConstants.VOXEL_ISO_LEVEL);
        }
コード例 #19
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);
     }
 }
コード例 #20
0
        public static void GetMaterialContent(this VRage.Game.Voxels.IMyStorage self, ref Vector3I voxelCoords, out byte material, out byte content)
        {
            MyStorageData myStorageData = new MyStorageData(MyStorageDataTypeFlags.ContentAndMaterial);

            myStorageData.Resize(Vector3I.One);
            myStorageData.ClearMaterials(0);
            self.ReadRange(myStorageData, MyStorageDataTypeFlags.ContentAndMaterial, 0, voxelCoords, voxelCoords);

            material = myStorageData.Material(0);
            content  = myStorageData.Content(0);
        }
コード例 #21
0
 unsafe void IWork.DoWork(WorkData workData)
 {
     try
     {
         if (this.m_result == null)
         {
             this.m_result     = new List <MyEntityOreDeposit>();
             this.m_emptyCells = new List <Vector3I>();
         }
         MyStorageData cache = Cache;
         cache.Resize(new Vector3I(8));
         IMyStorage storage = this.VoxelMap.Storage;
         if (storage != null)
         {
             using (StoragePin pin = storage.Pin())
             {
                 if (pin.Valid)
                 {
                     Vector3I vectori;
                     vectori.Z = this.Min.Z;
                     while (vectori.Z <= this.Max.Z)
                     {
                         vectori.Y = this.Min.Y;
                         while (true)
                         {
                             if (vectori.Y > this.Max.Y)
                             {
                                 int *numPtr3 = (int *)ref vectori.Z;
                                 numPtr3[0]++;
                                 break;
                             }
                             vectori.X = this.Min.X;
                             while (true)
                             {
                                 if (vectori.X > this.Max.X)
                                 {
                                     int *numPtr2 = (int *)ref vectori.Y;
                                     numPtr2[0]++;
                                     break;
                                 }
                                 this.ProcessCell(cache, storage, vectori, this.DetectorId);
                                 int *numPtr1 = (int *)ref vectori.X;
                                 numPtr1[0]++;
                             }
                         }
                     }
                 }
             }
         }
     }
     finally
     {
     }
 }
コード例 #22
0
            public override void Perform()
            {
                var map = MySession.Static.VoxelMaps.TryGetVoxelMapByNameStart(m_voxelName);

                Debug.Assert(map != null);
                if (map == null)
                {
                    return;
                }

                map.Storage.WriteRange(MyStorageData.FromBase64(m_data), m_dataType, m_voxelMin, m_voxelMax);
            }
コード例 #23
0
        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;
        }
コード例 #24
0
        private static void VoxelReading()
        {
            var camera = MySector.MainCamera;

            if (camera == null)
            {
                return;
            }

            var         offset         = 0; // MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF;
            var         targetPosition = camera.Position + (Vector3D)camera.ForwardVector * 4.5f - offset;
            MyVoxelBase targetVoxelMap = null;

            foreach (var voxelMap in MySession.Static.VoxelMaps.Instances)
            {
                if (voxelMap.PositionComp.WorldAABB.Contains(targetPosition) == ContainmentType.Contains)
                {
                    targetVoxelMap = voxelMap;
                    break;
                }
            }
            if (targetVoxelMap == null)
            {
                return;
            }

            var      targetMin = targetPosition - Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES;
            var      targetMax = targetPosition + Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES;
            Vector3I minVoxel, maxVoxel;

            MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMin, out minVoxel);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMax, out maxVoxel);
            MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref minVoxel, out targetMin);
            MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref maxVoxel, out targetMax);

            {
                BoundingBoxD bbox = BoundingBoxD.CreateInvalid();
                bbox.Include(targetMin);
                bbox.Include(targetMax);
                VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Vector3.One, 1f, 1f, true);
            }

            if (MyInput.Static.IsNewLeftMousePressed())
            {
                var cache = new MyStorageData();
                cache.Resize(minVoxel, maxVoxel);
                targetVoxelMap.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, ref minVoxel, ref maxVoxel);
                targetVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref minVoxel, ref maxVoxel);
                Debug.Assert(true);
            }
        }
コード例 #25
0
        /// <summary>
        /// called multiple times for ships, to be kept up to date.
        /// </summary>
        public override void UpdateAfterSimulation10()
        {
            if (CommandAsteroidEditClear.ActiveVoxelDeleter)
            {
                var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                var position    = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f;

                var currentAsteroidList = new List <IMyVoxelBase>();
                var bb = new BoundingBoxD(position - 0.2f, position + 0.2f);
                MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb));

                if (currentAsteroidList.Count > 0)
                {
                    _isInRange = true;
                    var storage = currentAsteroidList[0].Storage;

                    var point = new Vector3I(position - currentAsteroidList[0].PositionLeftBottomCorner);
                    var cache = new MyStorageData();
                    var min   = (point / 64) * 64;
                    var max   = min + 63;
                    var size  = max - min;
                    cache.Resize(size);
                    storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, min, max);

                    Vector3I p       = point - min;
                    var      content = cache.Content(ref p);
                    if (content > 0)
                    {
                        content = 0x00;
                        cache.Content(ref p, content);
                        storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max);
                    }
                    //storage = null;
                }
                else
                {
                    _isInRange = false;
                }
            }

            if (CommandAsteroidEditSet.ActiveVoxelSetter)
            {
                var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                CommandAsteroidEditSet.ActiveVoxelSetterPosition = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f;
            }
            else
            {
                CommandAsteroidEditSet.ActiveVoxelSetterPosition = null;
            }
        }
コード例 #26
0
        /// <summary>
        /// called multiple times for ships, to be kept up to date.
        /// </summary>
        public override void UpdateAfterSimulation10()
        {
            if (CommandAsteroidEditClear.ActiveVoxelDeleter)
            {
                var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                var position = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f;

                var currentAsteroidList = new List<IMyVoxelBase>();
                var bb = new BoundingBoxD(position - 0.2f, position + 0.2f);
                MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb));

                if (currentAsteroidList.Count > 0)
                {
                    _isInRange = true;
                    var storage = currentAsteroidList[0].Storage;

                    var point = new Vector3I(position - currentAsteroidList[0].PositionLeftBottomCorner);
                    var cache = new MyStorageData();
                    var min = (point / 64) * 64;
                    var max = min + 63;
                    var size = max - min;
                    cache.Resize(size);
                    storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, min, max);

                    Vector3I p = point - min;
                    var content = cache.Content(ref p);
                    if (content > 0)
                    {
                        content = 0x00;
                        cache.Content(ref p, content);
                        storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max);
                    }
                    //storage = null;
                }
                else
                {
                    _isInRange = false;
                }
            }

            if (CommandAsteroidEditSet.ActiveVoxelSetter)
            {
                var worldMatrix = MyAPIGateway.Session.Player.Controller.ControlledEntity.Entity.WorldMatrix;
                CommandAsteroidEditSet.ActiveVoxelSetterPosition = worldMatrix.Translation + worldMatrix.Forward * 1.6f + worldMatrix.Up * 1.35f + worldMatrix.Right * 0.1f;
            }
            else
            {
                CommandAsteroidEditSet.ActiveVoxelSetterPosition = null;
            }
        }
コード例 #27
0
        public static MyDefinitionId?VoxelMaterialAt(this MyVoxelBase voxel, Vector3D min, Vector3D grow,
                                                     ref MyStorageData cache)
        {
            if (cache == null)
            {
                cache = new MyStorageData();
            }
            var      shape = new BoundingBoxD(Vector3D.Min(min, min + grow), Vector3D.Max(min, min + grow));
            Vector3I voxMin;
            Vector3I voxMax;
            Vector3I voxCells;

            GetVoxelShapeDimensions(voxel, shape, out voxMin, out voxMax, out voxCells);
            Vector3I_RangeIterator cellsItr = new Vector3I_RangeIterator(ref Vector3I.Zero, ref voxCells);

            while (cellsItr.IsValid())
            {
                Vector3I cellMinCorner;
                Vector3I cellMaxCorner;
                GetCellCorners(ref voxMin, ref voxMax, ref cellsItr, out cellMinCorner, out cellMaxCorner);
                Vector3I rangeMin = cellMinCorner - 1;
                Vector3I rangeMax = cellMaxCorner + 1;
                voxel.Storage.ClampVoxelCoord(ref rangeMin);
                voxel.Storage.ClampVoxelCoord(ref rangeMax);
                cache.Resize(rangeMin, rangeMax);
                voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, rangeMin, rangeMax);

                var mortonCode    = -1;
                var maxMortonCode = cache.Size3D.Size;
                while (++mortonCode < maxMortonCode)
                {
                    Vector3I pos;
                    MyMortonCode3D.Decode(mortonCode, out pos);
                    var content = cache.Content(ref pos);
                    if (content <= MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                    {
                        continue;
                    }
                    var material = cache.Material(ref pos);
                    var def      = MyDefinitionManager.Static.GetVoxelMaterialDefinition(material);
                    if (def != null)
                    {
                        return(def.Id);
                    }
                }
                cellsItr.MoveNext();
            }

            return(null);
        }
コード例 #28
0
        public static MyVoxelMaterialDefinition GetMaterialAt_R(this IMyStorage self, ref Vector3I voxelCoords)
        {
            MyVoxelMaterialDefinition def;

            var cache = new MyStorageData();

            cache.Resize(Vector3I.One);
            cache.ClearMaterials(0);

            self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, voxelCoords, voxelCoords);

            def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0));

            return(def);
        }
コード例 #29
0
        private void WriteChunk(ref Vector3I coords, VoxelChunk chunk)
        {
            // We assume that we are locked here.
            Debug.Assert(m_storageLock.Owned);

            var start = coords << VoxelChunk.SizeBits;

            var end = ((coords + 1) << VoxelChunk.SizeBits) - 1;

            MyStorageData storage = chunk.MakeData();

            WriteRangeInternal(storage, chunk.Dirty, ref start, ref end);

            chunk.Dirty = 0;
        }
コード例 #30
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);
     }
 }
コード例 #31
0
            private unsafe void DrawMaterialsInfo(MyStorageData data)
            {
                int *counts = stackalloc int[256];

                int cellCount = data.SizeLinear / data.StepLinear;

                for (int i = 0; i < data.SizeLinear; i += data.StepLinear)
                {
                    byte mat = data.Material(i);
                    counts[mat]++;
                }

                Section("Probing Materials ({0} {1})", cellCount, cellCount > 1 ? "voxels" : "voxel");

                List <MatInfo> hits = new List <MatInfo>();

                for (int i = 0; i < 256; i++)
                {
                    if (counts[i] > 0)
                    {
                        hits.Add(new MatInfo()
                        {
                            Material = (byte)i,
                            Count    = counts[i]
                        });
                    }
                }

                hits.Sort();

                int maxMaterial = MyDefinitionManager.Static.VoxelMaterialCount;

                foreach (var info in hits)
                {
                    if (info.Material == MyVoxelConstants.NULL_MATERIAL)
                    {
                        Text("    Null Material: {0}", info.Count);
                    }
                    else if (info.Material > maxMaterial)
                    {
                        Text("    Invalid Material({1}): {0}", info.Count, info.Material);
                    }
                    else
                    {
                        Text("    {1}: {0}", info.Count, MyDefinitionManager.Static.GetVoxelMaterialDefinition(info.Material).Id.SubtypeName);
                    }
                }
            }
コード例 #32
0
            private void DrawContentsInfo(MyStorageData data)
            {
                byte min, max;
                uint sum     = 0;
                uint nonZero = 0;
                uint nonFull = 0;

                min = byte.MaxValue;
                max = 0;

                int cellCount = data.SizeLinear / data.StepLinear;

                for (int i = 0; i < data.SizeLinear; i += data.StepLinear)
                {
                    byte content = data.Content(i);
                    if (min > content)
                    {
                        min = content;
                    }
                    if (max < content)
                    {
                        max = content;
                    }

                    sum += content;

                    if (content != 0)
                    {
                        nonZero++;
                    }
                    if (content != 255)
                    {
                        nonFull++;
                    }
                }

                Section("Probing Contents ({0} {1})", cellCount, cellCount > 1 ? "voxels" : "voxel");

                Text("Min: {0}", min);
                Text("Average: {0}", sum / cellCount);
                Text("Max: {0}", max);

                VSpace(5);

                Text("Non-Empty: {0}", nonZero);
                Text("Non-Full: {0}", nonFull);
            }
        private bool ReplaceAsteroidMaterial(ulong steamId, IMyVoxelBase originalAsteroid, string searchMaterialName1, string searchMaterialName2)
        {
            MyVoxelMaterialDefinition material1;
            string suggestedMaterials = "";

            if (!Support.FindMaterial(searchMaterialName1, out material1, ref suggestedMaterials))
            {
                MyAPIGateway.Utilities.SendMessage(steamId, "Invalid Material1 specified.", "Cannot find the material '{0}'.\r\nTry the following: {1}", searchMaterialName1, suggestedMaterials);
                return(true);
            }

            MyVoxelMaterialDefinition material2;

            if (!Support.FindMaterial(searchMaterialName2, out material2, ref suggestedMaterials))
            {
                MyAPIGateway.Utilities.SendMessage(steamId, "Invalid Material2 specified.", "Cannot find the material '{0}'.\r\nTry the following: {1}", searchMaterialName2, suggestedMaterials);
                return(true);
            }

            var oldStorage = originalAsteroid.Storage;
            var oldCache   = new MyStorageData();

            oldCache.Resize(oldStorage.Size);
            oldStorage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, Vector3I.Zero, oldStorage.Size - 1);

            Vector3I p;

            for (p.Z = 0; p.Z < oldStorage.Size.Z; ++p.Z)
            {
                for (p.Y = 0; p.Y < oldStorage.Size.Y; ++p.Y)
                {
                    for (p.X = 0; p.X < oldStorage.Size.X; ++p.X)
                    {
                        var material = oldCache.Material(ref p);
                        if (material == material1.Index)
                        {
                            oldCache.Material(ref p, material2.Index);
                        }
                    }
                }
            }

            oldStorage.WriteRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, oldStorage.Size - 1);

            MyAPIGateway.Utilities.SendMessage(steamId, "Asteroid", "'{0}' material '{1}' replaced with '{2}'.", originalAsteroid.StorageName, material1.Id.SubtypeName, material2.Id.SubtypeName);
            return(true);
        }
コード例 #34
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();
        }
コード例 #35
0
ファイル: MyStorageBase.cs プロジェクト: Chrus/SpaceEngineers
 protected abstract void ReadRangeInternal(MyStorageData target, ref Vector3I targetWriteRange, MyStorageDataTypeFlags dataToRead, int lodIndex, ref Vector3I lodVoxelRangeMin, ref Vector3I lodVoxelRangeMax, ref MyVoxelRequestFlags requestFlags);
コード例 #36
0
ファイル: MyStorageBase.cs プロジェクト: Chrus/SpaceEngineers
        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();
        }
コード例 #37
0
ファイル: MyStorageBase.cs プロジェクト: Chrus/SpaceEngineers
 protected abstract void WriteRangeInternal(MyStorageData source, MyStorageDataTypeFlags dataToWrite, ref Vector3I voxelRangeMin, ref Vector3I voxelRangeMax);
コード例 #38
0
ファイル: MyStorageBase.cs プロジェクト: Chrus/SpaceEngineers
 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);
 }
コード例 #39
0
ファイル: MyStorageBase.cs プロジェクト: Chrus/SpaceEngineers
        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);
                        }
            }
        }
コード例 #40
0
        private void UpdateLoad()
        {
            ConstructAreas();

            if (m_checkQueue.Count == 0)
            {
                bool finishedLoading = true;
                m_ground = MySession.Static.VoxelMaps.TryGetVoxelMapByNameStart("Ground");
                if (m_ground != null)
                {
                    m_worldArea = m_ground.SizeInMetres.X * m_ground.SizeInMetres.Z;
                    m_voxelCache = new MyStorageData();
                    m_voxelCache.Resize(Vector3I.One * 3);

                    InvalidateAreaValues();

                    if (m_highLevelBoxes.Count == 0)
                    {
                        // MW: we need to find some candidates for forest starting points
                        finishedLoading = false;
                        m_findValidForestPhase = true;
                    }
                }

                if (finishedLoading)
                {
                    m_loadPhase = false;
                    if (LoadFinished != null)
                        LoadFinished();
                }
            }
        }
コード例 #41
0
        internal void ReadMaterialRange(MyStorageData target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            float lodVoxelSizeHalf;
            BoundingBox queryBox;
            BoundingSphere querySphere;
            SetupReading(lodIndex, ref minInLod, ref maxInLod, out lodVoxelSizeHalf, out queryBox, out querySphere);
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            var overlappedDeposits = OverlappedDeposits;
            {
                ProfilerShort.Begin("Testing deposit shapes");
                overlappedDeposits.Clear();
                ContainmentType testDeposits = ContainmentType.Disjoint;
                for (int i = 0; i < m_data.Deposits.Length; ++i)
                {
                    var test = m_data.Deposits[i].Shape.Contains(ref queryBox, ref querySphere, lodVoxelSize);
                    if (test != ContainmentType.Disjoint)
                    {
                        overlappedDeposits.Add(m_data.Deposits[i]);
                        testDeposits = ContainmentType.Intersects;
                    }
                }
                ProfilerShort.End();

                if (testDeposits == ContainmentType.Disjoint)
                {
                    ProfilerShort.Begin("target.BlockFillMaterial");
                    target.BlockFillMaterial(writeOffset, writeOffset + (maxInLod - minInLod), m_data.DefaultMaterial.Index);
                    ProfilerShort.End();
                    return;
                }
            }


            ProfilerShort.Begin("Material computation");

            Vector3I v;
            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    for (v.X = minInLod.X; v.X <= maxInLod.X; ++v.X)
                    {
                        Vector3 localPos = v * lodVoxelSize;

                        float closestDistance = 1f;
                        byte closestMaterialIdx = m_data.DefaultMaterial.Index;
                        if (!MyFakes.DISABLE_COMPOSITE_MATERIAL)
                        {
                            foreach (var deposit in overlappedDeposits)
                            {
                                float distance = deposit.Shape.SignedDistance(ref localPos, MyVoxelConstants.VOXEL_SIZE_IN_METRES, m_data.MacroModule, m_data.DetailModule);
                                if (distance < 0f && distance <= closestDistance)
                                {
                                    closestDistance = distance;
                                    // DA: Pass default material to the layered deposit so only that does these if-s.
                                    var materialDef = deposit.GetMaterialForPosition(ref localPos, lodVoxelSize);
                                    closestMaterialIdx = materialDef == null ? m_data.DefaultMaterial.Index : materialDef.Index;
                                }
                            }
                        }

                        var write = v - minInLod + writeOffset;
                        target.Material(ref write, closestMaterialIdx);
                    }
                }

            }
            ProfilerShort.End();
        }
コード例 #42
0
            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++;
            }
コード例 #43
0
            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;
                }
            }
コード例 #44
0
 public void LogStorageWrite(MyVoxelBase map, MyStorageData source, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin, Vector3I voxelRangeMax)
 {
     var str = source.ToBase64();
     m_log.WriteLine(String.Format("VOXOP: {0} {1} {2} {3} {4}", map.StorageName, voxelRangeMin, voxelRangeMax, dataToWrite, str));
 }
コード例 #45
0
        private static MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream)
        {
            //  Size of this voxel map (in voxels)
            Vector3I tmpSize;
            tmpSize.X = stream.ReadInt32();
            tmpSize.Y = stream.ReadInt32();
            tmpSize.Z = stream.ReadInt32();
            var storage = new MyOctreeStorage(null, tmpSize);

            //  Size of data cell in voxels. Has to be the same as current size specified by our constants.
            Vector3I cellSize;
            cellSize.X = stream.ReadInt32();
            cellSize.Y = stream.ReadInt32();
            cellSize.Z = stream.ReadInt32();
            Trace.Assert(cellSize.X == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS &&
                         cellSize.Y == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS &&
                         cellSize.Z == MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS);

            Vector3I cellsCount = tmpSize / cellSize;

            Dictionary<byte, MyVoxelMaterialDefinition> mappingTable = null;
            if (fileVersion == STORAGE_TYPE_VERSION_CELL)
            {
                // loading material names->index mappings
                mappingTable = Compatibility_LoadMaterialIndexMapping(stream);
            }
            else if (fileVersion == 1)
            {
                // material name->index mappings were not saved in this version
            }

            var startCoord = Vector3I.Zero;
            var endCoord = new Vector3I(MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);

            var cache = new MyStorageData();
            cache.Resize(Vector3I.Zero, endCoord);
            Vector3I cellCoord;
            for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++)
            {
                for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++)
                    {
                        MyVoxelRangeType cellType = (MyVoxelRangeType)stream.ReadByteNoAlloc();

                        //  Cell's are FULL by default, therefore we don't need to change them
                        switch (cellType)
                        {
                            case MyVoxelRangeType.EMPTY: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_EMPTY); break;
                            case MyVoxelRangeType.FULL: cache.ClearContent(MyVoxelConstants.VOXEL_CONTENT_FULL); break;
                            case MyVoxelRangeType.MIXED:
                                Vector3I v;
                                for (v.X = 0; v.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.X++)
                                {
                                    for (v.Y = 0; v.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Y++)
                                    {
                                        for (v.Z = 0; v.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; v.Z++)
                                        {
                                            cache.Content(ref v, stream.ReadByteNoAlloc());
                                        }
                                    }
                                }
                                break;
                        }
                        startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS;
                        endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);
                        storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref startCoord, ref endCoord);
                    }
                }
            }

            try
            { // In case materials are not saved, catch any exceptions caused by this.
                // Read materials and indestructible
                for (cellCoord.X = 0; cellCoord.X < cellsCount.X; cellCoord.X++)
                {
                    for (cellCoord.Y = 0; cellCoord.Y < cellsCount.Y; cellCoord.Y++)
                    {
                        for (cellCoord.Z = 0; cellCoord.Z < cellsCount.Z; cellCoord.Z++)
                        {
                            bool isSingleMaterial = stream.ReadByteNoAlloc() == 1;
                            MyVoxelMaterialDefinition material = null;

                            if (isSingleMaterial)
                            {
                                material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable);
                                cache.ClearMaterials(material.Index);
                            }
                            else
                            {
                                byte indestructibleContent;
                                Vector3I voxelCoordInCell;
                                for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++)
                                {
                                    for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++)
                                    {
                                        for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++)
                                        {
                                            material = Compatibility_LoadCellVoxelMaterial(stream, mappingTable);
                                            indestructibleContent = stream.ReadByteNoAlloc();
                                            cache.Material(ref voxelCoordInCell, material.Index);
                                        }
                                    }
                                }
                            }
                            startCoord = cellCoord * MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS;
                            endCoord = startCoord + (MyVoxelConstants.DATA_CELL_SIZE_IN_VOXELS - 1);
                            storage.WriteRange(cache, MyStorageDataTypeFlags.Material, ref startCoord, ref endCoord);
                        }
                    }
                }
            }
            catch (EndOfStreamException ex)
            {
                MySandboxGame.Log.WriteLine(ex);
            }

            return storage;
        }
コード例 #46
0
 void VRage.ModAPI.IMyStorage.WriteRange(MyStorageData source, MyStorageDataTypeFlags dataToWrite, Vector3I voxelRangeMin, Vector3I voxelRangeMax)
 {
     WriteRange(source, dataToWrite, ref voxelRangeMin, ref voxelRangeMax);
 }
コード例 #47
0
        public static MyVoxelMaterialDefinition GetMaterialAt(this IMyStorage self, ref Vector3I voxelCoords)
        {
            MyVoxelMaterialDefinition def;

            MyStorageData cache = new MyStorageData();
            cache.Resize(Vector3I.One);
            cache.ClearMaterials(0);

            self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref voxelCoords, ref voxelCoords);

            def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0));

            return def;
        }
コード例 #48
0
        public static MyVoxelMaterialDefinition GetMaterialAt(this IMyStorage self, ref Vector3D localCoords)
        {
            MyVoxelMaterialDefinition def;

            Vector3I voxelCoords = Vector3D.Floor(localCoords / MyVoxelConstants.VOXEL_SIZE_IN_METRES);

            MyStorageData cache = new MyStorageData();
            cache.Resize(Vector3I.One);
            cache.ClearMaterials(0);

            self.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref voxelCoords, ref voxelCoords);

            def = MyDefinitionManager.Static.GetVoxelMaterialDefinition(cache.Material(0));

            return def;
        }
コード例 #49
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);
 }
コード例 #50
0
ファイル: MyVoxelBase.cs プロジェクト: 2asoft/SpaceEngineers
        public void GetFilledStorageBounds(out Vector3I min, out Vector3I max)
        {
            min = Vector3I.MaxValue;
            max = Vector3I.MinValue;

            Vector3I sz = Size;

            Vector3I SMax = Size - 1;

            MyStorageData data = new MyStorageData();
            data.Resize(Size);

            Storage.ReadRange(data, MyStorageDataTypeFlags.Content, 0, Vector3I.Zero, SMax);

            for (int z = 0; z < sz.Z; ++z)
                for (int y = 0; y < sz.Y; ++y)
                    for (int x = 0; x < sz.X; ++x)
                    {
                        if (data.Content(x, y, z) > MyVoxelConstants.VOXEL_ISO_LEVEL)
                        {
                            Vector3I l = Vector3I.Max(new Vector3I(x - 1, y - 1, z - 1), Vector3I.Zero);
                            min = Vector3I.Min(l, min);

                            Vector3I h = Vector3I.Min(new Vector3I(x + 1, y + 1, z + 1), SMax);
                            max = Vector3I.Max(h, max);
                        }
                    }
        }
コード例 #51
0
ファイル: MyStorageBase.cs プロジェクト: rem02/SpaceEngineers
        public unsafe bool ChangeMaterials(Dictionary<byte, byte> map)
        {
            int rewrites = 0;

            if ((Size + 1).Size > 4 * 1024 * 1024)
            {
                MyLog.Default.Error("Cannot overwrite materials for a storage 4 MB or larger.");
                return false;
            }

            Vector3I minCorner = Vector3I.Zero;
            Vector3I maxCorner = Size - 1;

            // I don't like this but write range will also allocate so f.. it.
            MyStorageData cache = new MyStorageData();
            cache.Resize(Size);

            ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref minCorner, ref maxCorner);

            var len = cache.SizeLinear;

            fixed (byte* data = cache[MyStorageDataTypeEnum.Material])
                for (int i = 0; i < len; i++)
                {
                    byte to;
                    if (map.TryGetValue(data[i], out to))
                        data[i] = to;
                }

            if (rewrites > 0) this.WriteRange(cache, MyStorageDataTypeFlags.Material, ref minCorner, ref maxCorner);

            return rewrites > 0;
        }
コード例 #52
0
ファイル: MyStorageBase.cs プロジェクト: Chrus/SpaceEngineers
        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();
            }
        }
コード例 #53
0
        //  Linearly interpolates position, normal and material on poly-cube edge. Interpolated point is where an isosurface cuts an edge between two vertices, each with their own scalar value.
        void GetVertexInterpolation(MyStorageData cache, MyTemporaryVoxel inputVoxelA, MyTemporaryVoxel inputVoxelB, int edgeIndex)
        {
            MyEdge edge = m_edges[edgeIndex];

            byte contentA = cache.Content(inputVoxelA.IdxInCache);
            byte contentB = cache.Content(inputVoxelB.IdxInCache);
            byte materialA = cache.Material(inputVoxelA.IdxInCache);
            byte materialB = cache.Material(inputVoxelB.IdxInCache);

            if (Math.Abs(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) < 0.00001f)
            {
                edge.Position = inputVoxelA.Position;
                edge.Normal = inputVoxelA.Normal;
                edge.Material = materialA;
                edge.Ambient = inputVoxelA.Ambient;
                return;
            }

            if (Math.Abs(MyVoxelConstants.VOXEL_ISO_LEVEL - contentB) < 0.00001f)
            {
                edge.Position = inputVoxelB.Position;
                edge.Normal = inputVoxelB.Normal;
                edge.Material = materialB;
                edge.Ambient = inputVoxelB.Ambient;
                return;
            }

            float mu = (float)(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) / (float)(contentB - contentA);
            Debug.Assert(mu > 0.0f && mu < 1.0f);

            edge.Position.X = inputVoxelA.Position.X + mu * (inputVoxelB.Position.X - inputVoxelA.Position.X);
            edge.Position.Y = inputVoxelA.Position.Y + mu * (inputVoxelB.Position.Y - inputVoxelA.Position.Y);
            edge.Position.Z = inputVoxelA.Position.Z + mu * (inputVoxelB.Position.Z - inputVoxelA.Position.Z);
            //edge.Normal = ComputeVertexNormal(ref edge.Position);

            edge.Normal.X = inputVoxelA.Normal.X + mu * (inputVoxelB.Normal.X - inputVoxelA.Normal.X);
            edge.Normal.Y = inputVoxelA.Normal.Y + mu * (inputVoxelB.Normal.Y - inputVoxelA.Normal.Y);
            edge.Normal.Z = inputVoxelA.Normal.Z + mu * (inputVoxelB.Normal.Z - inputVoxelA.Normal.Z);
            if (MyUtils.IsZero(edge.Normal))
                edge.Normal = inputVoxelA.Normal;
            else
                edge.Normal = MyUtils.Normalize(edge.Normal);


            if (MyUtils.IsZero(edge.Normal))
                edge.Normal = inputVoxelA.Normal;

            float mu2 = ((float)contentB) / (((float)contentA) + ((float)contentB));
            edge.Material = (mu2 <= 0.5f) ? materialA : materialB;
            edge.Ambient = inputVoxelA.Ambient + mu2 * (inputVoxelB.Ambient - inputVoxelA.Ambient);

            return;
        }
コード例 #54
0
        internal void ReadContentRange(MyStorageData target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            float lodVoxelSizeHalf;
            BoundingBox queryBox;
            BoundingSphere querySphere;
            SetupReading(lodIndex, ref minInLod, ref maxInLod, out lodVoxelSizeHalf, out queryBox, out querySphere);
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            ProfilerShort.Begin("Testing removed shapes");
            var overlappedRemovedShapes = OverlappedRemovedShapes;
            overlappedRemovedShapes.Clear();
            ContainmentType testRemove = ContainmentType.Disjoint;
            for (int i = 0; i < m_data.RemovedShapes.Length; ++i)
            {
                var test = m_data.RemovedShapes[i].Contains(ref queryBox, ref querySphere, lodVoxelSize);
                if (test == ContainmentType.Contains)
                {
                    testRemove = ContainmentType.Contains;
                    break; // completely empty so we can leave
                }
                else if (test == ContainmentType.Intersects)
                {
                    testRemove = ContainmentType.Intersects;
                    overlappedRemovedShapes.Add(m_data.RemovedShapes[i]);
                }
            }
            ProfilerShort.End();
            if (testRemove == ContainmentType.Contains)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_EMPTY);
                ProfilerShort.End();
                return;
            }

            ProfilerShort.Begin("Testing filled shapes");
            var overlappedFilledShapes = OverlappedFilledShapes;
            overlappedFilledShapes.Clear();
            ContainmentType testFill = ContainmentType.Disjoint;
            for (int i = 0; i < m_data.FilledShapes.Length; ++i)
            {
                var test = m_data.FilledShapes[i].Contains(ref queryBox, ref querySphere, lodVoxelSize);
                if (test == ContainmentType.Contains)
                {
                    overlappedFilledShapes.Clear();
                    testFill = ContainmentType.Contains;
                    break;
                }
                else if (test == ContainmentType.Intersects)
                {
                    overlappedFilledShapes.Add(m_data.FilledShapes[i]);
                    testFill = ContainmentType.Intersects;
                }
            }
            ProfilerShort.End();

            if (testFill == ContainmentType.Disjoint)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_EMPTY);
                ProfilerShort.End();
                return;
            }
            else if (testRemove == ContainmentType.Disjoint && testFill == ContainmentType.Contains)
            {
                ProfilerShort.Begin("target.BlockFillContent");
                target.BlockFillContent(writeOffset, writeOffset + (maxInLod - minInLod), MyVoxelConstants.VOXEL_CONTENT_FULL);
                ProfilerShort.End();
                return;
            }

            ProfilerShort.Begin("Distance field computation");
            Vector3I v = minInLod;
            Vector3 localPos = v * lodVoxelSize;
            Vector3 localPosStart = v * lodVoxelSize;
            var writeOffsetLoc = writeOffset - minInLod;
            for (v.Z = minInLod.Z; v.Z <= maxInLod.Z; ++v.Z)
            {
                for (v.Y = minInLod.Y; v.Y <= maxInLod.Y; ++v.Y)
                {
                    v.X = minInLod.X;
                    var write2 = v + writeOffsetLoc;
                    var write = target.ComputeLinear(ref write2);
                    for (; v.X <= maxInLod.X; ++v.X)
                    {
                        //Vector3 localPos = v * lodVoxelSize;

                        //ProfilerShort.Begin("Dist filled");
                        float distFill;
                        if (testFill == ContainmentType.Contains)
                        {
                            distFill = -1f;
                        }
                        else
                        {
                            //ProfilerShort.Begin("shape distances");
                            distFill = 1f;
                            foreach (var shape in overlappedFilledShapes)
                            {
                                distFill = Math.Min(distFill, shape.SignedDistance(ref localPos, lodVoxelSize, m_data.MacroModule, m_data.DetailModule));
                                if (distFill <= -1)
                                    break;

                            }
                            //ProfilerShort.End();
                        }

                        //ProfilerShort.BeginNextBlock("Dist removed");
                        float distRemoved = 1f;
                        if (testRemove != ContainmentType.Disjoint)
                        {
                            foreach (var shape in overlappedRemovedShapes)
                            {
                                distRemoved = Math.Min(distRemoved, shape.SignedDistance(ref localPos, lodVoxelSize, m_data.MacroModule, m_data.DetailModule));
                                if (distRemoved <= -1)
                                    break;
                            }
                        }
                        //ProfilerShort.BeginNextBlock("content");
                        float signedDist = MathHelper.Max(distFill, -distRemoved);

                        var fillRatio = MathHelper.Clamp(-signedDist, -1f, 1f) * 0.5f + 0.5f;
                        byte content = (byte)(fillRatio * MyVoxelConstants.VOXEL_CONTENT_FULL);
                        target.Content(write, content);
                        Debug.Assert(Math.Abs((((float)content) / MyVoxelConstants.VOXEL_CONTENT_FULL) - fillRatio) <= 0.5f);
                        //ProfilerShort.End();
                        write += target.StepLinear;
                        localPos.X += lodVoxelSize;
                    }
                    localPos.Y += lodVoxelSize;
                    localPos.X = localPosStart.X;
                }
                localPos.Z += lodVoxelSize;
                localPos.Y = localPosStart.Y;
            }
            ProfilerShort.End();
        }
コード例 #55
0
        private Vector3I ComputeTemporaryVoxelData(MyStorageData cache, ref Vector3I coord0, int cubeIndex, int lod)
        {
            int coord0LinIdx = coord0.X * m_sX + coord0.Y * m_sY + coord0.Z * m_sZ;

            MyTemporaryVoxel tempVoxel0 = m_temporaryVoxels[coord0LinIdx];
            MyTemporaryVoxel tempVoxel1 = m_temporaryVoxels[coord0LinIdx + m_sX];
            MyTemporaryVoxel tempVoxel2 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sZ];
            MyTemporaryVoxel tempVoxel3 = m_temporaryVoxels[coord0LinIdx + m_sZ];
            MyTemporaryVoxel tempVoxel4 = m_temporaryVoxels[coord0LinIdx + m_sY];
            MyTemporaryVoxel tempVoxel5 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sY];
            MyTemporaryVoxel tempVoxel6 = m_temporaryVoxels[coord0LinIdx + m_sX + m_sY + m_sZ];
            MyTemporaryVoxel tempVoxel7 = m_temporaryVoxels[coord0LinIdx + m_sY + m_sZ];



            Vector3I coord1 = new Vector3I(coord0.X + 1, coord0.Y + 0, coord0.Z + 0);
            Vector3I coord2 = new Vector3I(coord0.X + 1, coord0.Y + 0, coord0.Z + 1);
            Vector3I coord3 = new Vector3I(coord0.X + 0, coord0.Y + 0, coord0.Z + 1);
            Vector3I coord4 = new Vector3I(coord0.X + 0, coord0.Y + 1, coord0.Z + 0);
            Vector3I coord5 = new Vector3I(coord0.X + 1, coord0.Y + 1, coord0.Z + 0);
            Vector3I coord6 = new Vector3I(coord0.X + 1, coord0.Y + 1, coord0.Z + 1);
            Vector3I coord7 = new Vector3I(coord0.X + 0, coord0.Y + 1, coord0.Z + 1);

            Vector3I tempVoxelCoord0 = coord0;
            Vector3I tempVoxelCoord1 = coord1;
            Vector3I tempVoxelCoord2 = coord2;
            Vector3I tempVoxelCoord3 = coord3;
            Vector3I tempVoxelCoord4 = coord4;
            Vector3I tempVoxelCoord5 = coord5;
            Vector3I tempVoxelCoord6 = coord6;
            Vector3I tempVoxelCoord7 = coord7;


            tempVoxel0.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord0);
            tempVoxel1.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord1);
            tempVoxel2.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord2);
            tempVoxel3.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord3);
            tempVoxel4.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord4);
            tempVoxel5.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord5);
            tempVoxel6.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord6);
            tempVoxel7.IdxInCache = cache.ComputeLinear(ref tempVoxelCoord7);

            //tempVoxel0.Position.X = m_originPosition.X + (coord0.X) * m_voxelSizeInMeters;
            //tempVoxel0.Position.Y = m_originPosition.Y + (coord0.Y) * m_voxelSizeInMeters;
            //tempVoxel0.Position.Z = m_originPosition.Z + (coord0.Z) * m_voxelSizeInMeters;

            tempVoxel0.Position.X = (m_voxelStart.X + coord0.X) * m_voxelSizeInMeters;
            tempVoxel0.Position.Y = (m_voxelStart.Y + coord0.Y) * m_voxelSizeInMeters;
            tempVoxel0.Position.Z = (m_voxelStart.Z + coord0.Z) * m_voxelSizeInMeters;


            tempVoxel1.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel1.Position.Y = tempVoxel0.Position.Y;
            tempVoxel1.Position.Z = tempVoxel0.Position.Z;

            tempVoxel2.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel2.Position.Y = tempVoxel0.Position.Y;
            tempVoxel2.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel3.Position.X = tempVoxel0.Position.X;
            tempVoxel3.Position.Y = tempVoxel0.Position.Y;
            tempVoxel3.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel4.Position.X = tempVoxel0.Position.X;
            tempVoxel4.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel4.Position.Z = tempVoxel0.Position.Z;

            tempVoxel5.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel5.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel5.Position.Z = tempVoxel0.Position.Z;

            tempVoxel6.Position.X = tempVoxel0.Position.X + m_voxelSizeInMeters;
            tempVoxel6.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel6.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            tempVoxel7.Position.X = tempVoxel0.Position.X;
            tempVoxel7.Position.Y = tempVoxel0.Position.Y + m_voxelSizeInMeters;
            tempVoxel7.Position.Z = tempVoxel0.Position.Z + m_voxelSizeInMeters;

            //  Normals at grid corners (calculated from gradient)
            GetVoxelNormal(tempVoxel0, ref coord0, ref tempVoxelCoord0, tempVoxel0);
            GetVoxelNormal(tempVoxel1, ref coord1, ref tempVoxelCoord1, tempVoxel0);
            GetVoxelNormal(tempVoxel2, ref coord2, ref tempVoxelCoord2, tempVoxel0);
            GetVoxelNormal(tempVoxel3, ref coord3, ref tempVoxelCoord3, tempVoxel0);
            GetVoxelNormal(tempVoxel4, ref coord4, ref tempVoxelCoord4, tempVoxel0);
            GetVoxelNormal(tempVoxel5, ref coord5, ref tempVoxelCoord5, tempVoxel0);
            GetVoxelNormal(tempVoxel6, ref coord6, ref tempVoxelCoord6, tempVoxel0);
            GetVoxelNormal(tempVoxel7, ref coord7, ref tempVoxelCoord7, tempVoxel0);

            //  Ambient occlusion colors at grid corners
            //  IMPORTANT: At this point normals must be calculated because GetVoxelAmbientAndSun() will be retrieving them from temp table and not checking if there is actual value
            GetVoxelAmbient(tempVoxel0, ref coord0, ref tempVoxelCoord0);
            GetVoxelAmbient(tempVoxel1, ref coord1, ref tempVoxelCoord1);
            GetVoxelAmbient(tempVoxel2, ref coord2, ref tempVoxelCoord2);
            GetVoxelAmbient(tempVoxel3, ref coord3, ref tempVoxelCoord3);
            GetVoxelAmbient(tempVoxel4, ref coord4, ref tempVoxelCoord4);
            GetVoxelAmbient(tempVoxel5, ref coord5, ref tempVoxelCoord5);
            GetVoxelAmbient(tempVoxel6, ref coord6, ref tempVoxelCoord6);
            GetVoxelAmbient(tempVoxel7, ref coord7, ref tempVoxelCoord7);

            //  Find the vertices where the surface intersects the cube
            int edgeVal = MyMarchingCubesConstants.EdgeTable[cubeIndex];
            if ((edgeVal & 1) == 1) { GetVertexInterpolation(cache, tempVoxel0, tempVoxel1, 0); }
            if ((edgeVal & 2) == 2) { GetVertexInterpolation(cache, tempVoxel1, tempVoxel2, 1); }
            if ((edgeVal & 4) == 4) { GetVertexInterpolation(cache, tempVoxel2, tempVoxel3, 2); }
            if ((edgeVal & 8) == 8) { GetVertexInterpolation(cache, tempVoxel3, tempVoxel0, 3); }
            if ((edgeVal & 16) == 16) { GetVertexInterpolation(cache, tempVoxel4, tempVoxel5, 4); }
            if ((edgeVal & 32) == 32) { GetVertexInterpolation(cache, tempVoxel5, tempVoxel6, 5); }
            if ((edgeVal & 64) == 64) { GetVertexInterpolation(cache, tempVoxel6, tempVoxel7, 6); }
            if ((edgeVal & 128) == 128) { GetVertexInterpolation(cache, tempVoxel7, tempVoxel4, 7); }
            if ((edgeVal & 256) == 256) { GetVertexInterpolation(cache, tempVoxel0, tempVoxel4, 8); }
            if ((edgeVal & 512) == 512) { GetVertexInterpolation(cache, tempVoxel1, tempVoxel5, 9); }
            if ((edgeVal & 1024) == 1024) { GetVertexInterpolation(cache, tempVoxel2, tempVoxel6, 10); }
            if ((edgeVal & 2048) == 2048) { GetVertexInterpolation(cache, tempVoxel3, tempVoxel7, 11); }

            return tempVoxelCoord0;
        }
コード例 #56
0
        private static void VoxelReading()
        {
            var camera = MySector.MainCamera;
            if (camera == null)
                return;

            var offset = 0; // MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF;
            var targetPosition = camera.Position + (Vector3D)camera.ForwardVector * 4.5f - offset;
            MyVoxelBase targetVoxelMap = null;
            foreach (var voxelMap in MySession.Static.VoxelMaps.Instances)
            {
                if (voxelMap.PositionComp.WorldAABB.Contains(targetPosition) == ContainmentType.Contains)
                {
                    targetVoxelMap = voxelMap;
                    break;
                }
            }
            if (targetVoxelMap == null)
                return;

            var targetMin = targetPosition - Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES;
            var targetMax = targetPosition + Vector3.One * MyVoxelConstants.VOXEL_SIZE_IN_METRES;
            Vector3I minVoxel, maxVoxel;
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMin, out minVoxel);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(targetVoxelMap.PositionLeftBottomCorner, ref targetMax, out maxVoxel);
            MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref minVoxel, out targetMin);
            MyVoxelCoordSystems.VoxelCoordToWorldPosition(targetVoxelMap.PositionLeftBottomCorner, ref maxVoxel, out targetMax);

            {
                BoundingBoxD bbox = BoundingBoxD.CreateInvalid();
                bbox.Include(targetMin);
                bbox.Include(targetMax);
                VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Vector3.One, 1f, 1f, true);
            }

            if (MyInput.Static.IsNewLeftMousePressed())
            {
                var cache = new MyStorageData();
                cache.Resize(minVoxel, maxVoxel);
                targetVoxelMap.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, ref minVoxel, ref maxVoxel);
                targetVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.Content, ref minVoxel, ref maxVoxel);
                Debug.Assert(true);

            }
        }
コード例 #57
0
            private unsafe void ReadLod(MyStorageData target, MyStorageDataTypeEnum dataType, byte[] dataArray, Vector3I tofft, int lod, Vector3I min, Vector3I max)
            {
                int offset = 0;
                for (int i = 0; i < lod; ++i)
                {
                    offset += Volume >> (i + i + i);
                }

                var sy = Size >> lod;
                var sz = sy * sy;

                min.Y *= sy;
                min.Z *= sz;

                max.Y *= sy;
                max.Z *= sz;

                int tsx = target.StepX, tsy = target.StepY, tsz = target.StepZ;

                tofft.Y *= tsy;
                tofft.Z *= tsz;

                fixed (byte* fixedDataArray = dataArray)
                fixed (byte* targetData = target[dataType])
                {
                    byte* voxel = fixedDataArray + offset;

                    int x, y, z;
                    int tx, ty, tz;

                    for (z = min.Z, tz = tofft.Z; z <= max.Z; z += sz, tz += tsz)
                        for (y = min.Y, ty = tofft.Y; y <= max.Y; y += sy, ty += tsy)
                            for (x = min.X, tx = tofft.X; x <= max.X; ++x, tx += tsx)
                            {
                                targetData[tz + ty + tx] = voxel[z + y + x];
                            }
                }
            }
コード例 #58
0
ファイル: MyStorageBase.cs プロジェクト: Chrus/SpaceEngineers
        public bool ChangeMaterials(byte[] materialChangeFrom, byte[] materialChangeTo)
        {
            int rewrites = 0;
            if (materialChangeFrom != null && materialChangeTo != null)
            {
                int maxIndex = Math.Min(materialChangeFrom.Length, materialChangeTo.Length);
                if (maxIndex > 0)
                {
                    Vector3I minCorner = Vector3I.Zero;
                    Vector3I maxCorner = this.Size-1;

                    MyStorageData cache = new MyStorageData();
                    cache.Resize(this.Size);
                    cache.ClearMaterials(0);

                    this.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, ref minCorner, ref maxCorner);
                    byte[] data = cache[MyStorageDataTypeEnum.Material];
                    int i, j;
                    for (i = 0; i < data.Length; i++)
                    {
                        if (data[i] > 0)
                        {
                            for (j = 0; j < maxIndex; j++)
                            {
                                if (data[i] == materialChangeFrom[j])
                                {
                                    data[i] = materialChangeTo[j];
                                    rewrites++;
                                    break;
                                }
                            }
                        }
                    }
                    if (rewrites > 0) this.WriteRange(cache, MyStorageDataTypeFlags.Material, ref minCorner, ref maxCorner);
                }
            }
            return (rewrites > 0);
        }
コード例 #59
0
            private unsafe void Write(MyStorageData source, MyStorageDataTypeEnum dataType, byte[] dataArray, Vector3I tofft, Vector3I min, Vector3I max)
            {
                Debug.Assert(Cached.Requests(dataType) || (min == Vector3I.Zero && max == MaxVector));

                var sy = Size;
                var sz = sy * sy;

                min.Y *= sy;
                min.Z *= sz;

                max.Y *= sy;
                max.Z *= sz;

                int tsx = source.StepX, tsy = source.StepY, tsz = source.StepZ;

                tofft.Y *= tsy;
                tofft.Z *= tsz;

                fixed (byte* voxel = dataArray)
                fixed (byte* sourceData = source[dataType])
                {
                    int x, y, z;
                    int tx, ty, tz;

                    for (z = min.Z, tz = tofft.Z; z <= max.Z; z += sz, tz += tsz)
                        for (y = min.Y, ty = tofft.Y; y <= max.Y; y += sy, ty += tsy)
                            for (x = min.X, tx = tofft.X; x <= max.X; ++x, tx += tsx)
                            {
                                voxel[z + y + x] = sourceData[tz + ty + tx];
                            }
                }
            }
        public override bool Invoke(ulong steamId, long playerId, string messageText)
        {
            // voxelset [0/off] [1/on] [A] [B] [C/Clear]
            if (messageText.StartsWith("/voxelset ", StringComparison.InvariantCultureIgnoreCase))
            {
                var strings = messageText.Split(' ');
                if (strings.Length > 1)
                {
                    if (strings[1].Equals("off", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("0", StringComparison.InvariantCultureIgnoreCase))
                    {
                        ActiveVoxelSetterPosition = null;
                        _activeVoxelSetterPositionA = null;
                        _activeVoxelSetterPositionB = null;
                        _activeVoxelSetterNameA = null;
                        _activeVoxelSetterNameB = null;
                        ActiveVoxelSetter = false;
                        MyAPIGateway.Utilities.ShowNotification("Voxel setter off", 1000, MyFontEnum.Green);
                        return true;
                    }
                    if (strings[1].Equals("on", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("1", StringComparison.InvariantCultureIgnoreCase))
                    {
                        ActiveVoxelSetterPosition = null;
                        _activeVoxelSetterPositionA = null;
                        _activeVoxelSetterPositionB = null;
                        _activeVoxelSetterNameA = null;
                        _activeVoxelSetterNameB = null;
                        ActiveVoxelSetter = true;
                        MyAPIGateway.Utilities.ShowNotification("Voxel setter activated", 1000, MyFontEnum.Green);
                        return true;
                    }
                    if (!ActiveVoxelSetter)
                    {
                        MyAPIGateway.Utilities.ShowNotification("Voxel setter hasn't been actived.", 2000, MyFontEnum.Red);
                        return true;
                    }
                    if (strings[1].Equals("A", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var tmp = ActiveVoxelSetterPosition;
                        if (tmp.HasValue)
                        {
                            var currentAsteroidList = new List<IMyVoxelBase>();
                            var bb = new BoundingBoxD(tmp.Value - 0.2f, tmp.Value + 0.2f);
                            MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb));

                            if (currentAsteroidList.Count > 0)
                            {
                                _activeVoxelSetterNameA = currentAsteroidList[0].StorageName;
                                _activeVoxelSetterPositionA = tmp;
                            }
                        }

                        if (_activeVoxelSetterPositionA.HasValue)
                            MyAPIGateway.Utilities.ShowMessage(_activeVoxelSetterNameA, "Voxel setter point A: active");
                        //MyAPIGateway.Utilities.ShowNotification("Voxel setter A: active.", 1000, MyFontEnum.Green);
                        else
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter A: invalid.", 1000, MyFontEnum.Red);
                        return true;
                    }
                    if (strings[1].Equals("B", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var tmp = ActiveVoxelSetterPosition;
                        if (tmp.HasValue)
                        {
                            var currentAsteroidList = new List<IMyVoxelBase>();
                            var bb = new BoundingBoxD(tmp.Value - 0.2f, tmp.Value + 0.2f);
                            MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.IsBoxIntersectingBoundingBoxOfThisVoxelMap(ref bb));

                            if (currentAsteroidList.Count > 0)
                            {
                                _activeVoxelSetterNameB = currentAsteroidList[0].StorageName;
                                _activeVoxelSetterPositionB = tmp;
                            }
                        }

                        if (_activeVoxelSetterPositionB.HasValue)
                            MyAPIGateway.Utilities.ShowMessage(_activeVoxelSetterNameB, "Voxel setter point B: active");
                        //MyAPIGateway.Utilities.ShowNotification("Voxel setter B: active.", 1000, MyFontEnum.Green);
                        else
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter B: invalid.", 1000, MyFontEnum.Red);
                        return true;
                    }
                    if (strings[1].Equals("C", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("Clear", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (_activeVoxelSetterPositionA.HasValue && _activeVoxelSetterPositionB.HasValue && _activeVoxelSetterNameA == _activeVoxelSetterNameB)
                        {
                            var currentAsteroidList = new List<IMyVoxelBase>();
                            MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(_activeVoxelSetterNameA, StringComparison.InvariantCultureIgnoreCase));
                            if (currentAsteroidList.Count > 0)
                            {
                                var storage = currentAsteroidList[0].Storage;
                                var point1 = new Vector3I(_activeVoxelSetterPositionA.Value - currentAsteroidList[0].PositionLeftBottomCorner);
                                var point2 = new Vector3I(_activeVoxelSetterPositionB.Value - currentAsteroidList[0].PositionLeftBottomCorner);

                                var cache = new MyStorageData();
                                var size = storage.Size;
                                cache.Resize(size);
                                storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, Vector3I.Zero, size - 1);

                                var min = Vector3I.Min(point1, point2);
                                var max = Vector3I.Max(point1, point2);

                                MyAPIGateway.Utilities.ShowMessage("Cutting", min.ToString() + " " + max.ToString());
                                //MyAPIGateway.Utilities.ShowNotification("cutting:" + min.ToString() + " " + max.ToString(), 5000, MyFontEnum.Blue);

                                Vector3I p;
                                for (p.Z = min.Z; p.Z <= max.Z; ++p.Z)
                                    for (p.Y = min.Y; p.Y <= max.Y; ++p.Y)
                                        for (p.X = min.X; p.X <= max.X; ++p.X)
                                            cache.Content(ref p, 0);
                                storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, size - 1);
                            }
                        }
                        else if (_activeVoxelSetterNameA != _activeVoxelSetterNameB)
                        {
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: different asteroids.", 2000, MyFontEnum.Red);
                        }
                        else
                        {
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: invalid points.", 2000, MyFontEnum.Red);
                        }
                        return true;
                    }
                    if (strings[1].Equals("F", StringComparison.InvariantCultureIgnoreCase) || strings[1].Equals("Fill", StringComparison.InvariantCultureIgnoreCase))
                    {
                        if (_activeVoxelSetterPositionA.HasValue && _activeVoxelSetterPositionB.HasValue && _activeVoxelSetterNameA == _activeVoxelSetterNameB)
                        {
                            var currentAsteroidList = new List<IMyVoxelBase>();
                            MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(_activeVoxelSetterNameA, StringComparison.InvariantCultureIgnoreCase));
                            if (currentAsteroidList.Count > 0)
                            {
                                var storage = currentAsteroidList[0].Storage;
                                var point1 = new Vector3I(_activeVoxelSetterPositionA.Value - currentAsteroidList[0].PositionLeftBottomCorner);
                                var point2 = new Vector3I(_activeVoxelSetterPositionB.Value - currentAsteroidList[0].PositionLeftBottomCorner);

                                var cache = new MyStorageData();
                                var size = storage.Size;
                                cache.Resize(size);
                                storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, (int)VRageRender.MyLodTypeEnum.LOD0, Vector3I.Zero, size - 1);

                                var min = Vector3I.Min(point1, point2);
                                var max = Vector3I.Max(point1, point2);

                                MyAPIGateway.Utilities.ShowMessage("Filling", min.ToString() + " " + max.ToString());
                                //MyAPIGateway.Utilities.ShowNotification("filling:" + min.ToString() + " " + max.ToString(), 5000, MyFontEnum.Blue);

                                Vector3I p;
                                for (p.Z = min.Z; p.Z <= max.Z; ++p.Z)
                                    for (p.Y = min.Y; p.Y <= max.Y; ++p.Y)
                                        for (p.X = min.X; p.X <= max.X; ++p.X)
                                            cache.Content(ref p, 0xff);
                                storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, Vector3I.Zero, size - 1);
                            }
                        }
                        else if (_activeVoxelSetterNameA != _activeVoxelSetterNameB)
                        {
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: different asteroids.", 2000, MyFontEnum.Red);
                        }
                        else
                        {
                            MyAPIGateway.Utilities.ShowNotification("Voxel setter Cut: invalid points.", 2000, MyFontEnum.Red);
                        }
                        return true;
                    }
                }
            } 

            return false;
        }