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
        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);
        }
        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 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)));
        }
Пример #6
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);
        }
Пример #7
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);
                }
            }
Пример #8
0
        public float GetVoxelContentInBoundingBox_Obsolete(BoundingBoxD worldAabb, out float cellCount)
        {
            MyPrecalcComponent.AssertUpdateThread();

            cellCount = 0;
            float result = 0;

            Vector3I minCorner, maxCorner;

            MyVoxelCoordSystems.WorldPositionToVoxelCoord(PositionLeftBottomCorner, ref worldAabb.Min, out minCorner);
            MyVoxelCoordSystems.WorldPositionToVoxelCoord(PositionLeftBottomCorner, ref worldAabb.Max, out maxCorner);

            minCorner += StorageMin;
            maxCorner += StorageMin;

            Storage.ClampVoxelCoord(ref minCorner);
            Storage.ClampVoxelCoord(ref maxCorner);
            m_tempStorage.Resize(minCorner, maxCorner);
            Storage.ReadRange(m_tempStorage, MyStorageDataTypeFlags.Content, 0, ref minCorner, ref maxCorner);

            BoundingBoxD voxelBox;
            Vector3I     coord, cache;

            for (coord.Z = minCorner.Z, cache.Z = 0; coord.Z <= maxCorner.Z; coord.Z++, cache.Z++)
            {
                for (coord.Y = minCorner.Y, cache.Y = 0; coord.Y <= maxCorner.Y; coord.Y++, cache.Y++)
                {
                    for (coord.X = minCorner.X, cache.X = 0; coord.X <= maxCorner.X; coord.X++, cache.X++)
                    {
                        MyVoxelCoordSystems.VoxelCoordToWorldAABB(PositionLeftBottomCorner - StorageMin * MyVoxelConstants.VOXEL_SIZE_IN_METRES, ref coord, out voxelBox);
                        if (worldAabb.Intersects(voxelBox))
                        {
                            float content        = m_tempStorage.Content(ref cache) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT;
                            float containPercent = (float)(worldAabb.Intersect(voxelBox).Volume / MyVoxelConstants.VOXEL_VOLUME_IN_METERS);
                            result    += content * containPercent;
                            cellCount += containPercent;
                        }
                    }
                }
            }
            return(result);
        }
Пример #9
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
     {
     }
 }
Пример #10
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);
        }
        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);
        }
Пример #12
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);
            }
        }
        /// <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;
            }
        }
        /// <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;
            }
        }
Пример #15
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);
        }
        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);
        }
Пример #17
0
        internal static int PointsInsideVoxel(MyVoxelBase voxel, MyStorageData tmpStorage, List <Vector3D> points)
        {
            var voxelMatrix = voxel.PositionComp.WorldMatrixInvScaled;
            var vecMax      = new Vector3I(int.MaxValue);
            var vecMin      = new Vector3I(int.MinValue);

            var results = 0;

            for (int index = 0; index < points.Count; ++index)
            {
                var      point = points[index];
                Vector3D result;
                Vector3D.Transform(ref point, ref voxelMatrix, out result);
                var r  = result + (Vector3D)(voxel.Size / 2);
                var v1 = Vector3D.Floor(r);
                Vector3D.Fract(ref r, out r);
                var v2 = v1 + voxel.StorageMin;
                var v3 = v2 + 1;
                if (v2 != vecMax && v3 != vecMin)
                {
                    tmpStorage.Resize(v2, v3);
                    voxel.Storage.ReadRange(tmpStorage, MyStorageDataTypeFlags.Content, 0, v2, v3);
                    vecMax = v2;
                    vecMin = v3;
                }
                var num1  = tmpStorage.Content(0, 0, 0);
                var num2  = tmpStorage.Content(1, 0, 0);
                var num3  = tmpStorage.Content(0, 1, 0);
                var num4  = tmpStorage.Content(1, 1, 0);
                var num5  = tmpStorage.Content(0, 0, 1);
                var num6  = tmpStorage.Content(1, 0, 1);
                var num7  = tmpStorage.Content(0, 1, 1);
                var num8  = tmpStorage.Content(1, 1, 1);
                var num9  = num1 + (num2 - num1) * r.X;
                var num10 = num3 + (num4 - num3) * r.X;
                var num11 = num5 + (num6 - num5) * r.X;
                var num12 = num7 + (num8 - num7) * r.X;
                var num13 = num9 + (num10 - num9) * r.Y;
                var num14 = num11 + (num12 - num11) * r.Y;
                if (num13 + (num14 - num13) * r.Z >= sbyte.MaxValue)
                {
                    ++results;
                }
            }
            return(results);
        }
Пример #18
0
        internal static bool CheckPointsOnLine(MyVoxelBase voxel, LineD testLine, MyStorageData tmpStorage, int distBetweenPoints)
        {
            var voxelMatrix = voxel.PositionComp.WorldMatrixInvScaled;
            var vecMax      = new Vector3I(int.MaxValue);
            var vecMin      = new Vector3I(int.MinValue);

            var checkPoints = (int)(testLine.Length / distBetweenPoints);

            for (int i = 0; i < checkPoints; i++)
            {
                var      point = testLine.From + (testLine.Direction * (distBetweenPoints * i));
                Vector3D result;
                Vector3D.Transform(ref point, ref voxelMatrix, out result);
                var r  = result + (Vector3D)(voxel.Size / 2);
                var v1 = Vector3D.Floor(r);
                Vector3D.Fract(ref r, out r);
                var v2 = v1 + voxel.StorageMin;
                var v3 = v2 + 1;
                if (v2 != vecMax && v3 != vecMin)
                {
                    tmpStorage.Resize(v2, v3);
                    voxel.Storage.ReadRange(tmpStorage, MyStorageDataTypeFlags.Content, 0, v2, v3);
                    vecMax = v2;
                    vecMin = v3;
                }
                var num1  = tmpStorage.Content(0, 0, 0);
                var num2  = tmpStorage.Content(1, 0, 0);
                var num3  = tmpStorage.Content(0, 1, 0);
                var num4  = tmpStorage.Content(1, 1, 0);
                var num5  = tmpStorage.Content(0, 0, 1);
                var num6  = tmpStorage.Content(1, 0, 1);
                var num7  = tmpStorage.Content(0, 1, 1);
                var num8  = tmpStorage.Content(1, 1, 1);
                var num9  = num1 + (num2 - num1) * r.X;
                var num10 = num3 + (num4 - num3) * r.X;
                var num11 = num5 + (num6 - num5) * r.X;
                var num12 = num7 + (num8 - num7) * r.X;
                var num13 = num9 + (num10 - num9) * r.Y;
                var num14 = num11 + (num12 - num11) * r.Y;
                if (num13 + (num14 - num13) * r.Z >= sbyte.MaxValue)
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #19
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);
        }
Пример #20
0
        public static bool CheckVoxelContent(long voxelId, Vector3D position)
        {
            IMyEntity entity;

            if (!MyAPIGateway.Entities.TryGetEntityById(voxelId, out entity))
            {
                return(false);
            }

            var      voxel = entity as IMyVoxelBase;
            var      targetMin = position;
            var      targetMax = position;
            Vector3I minVoxel, maxVoxel;

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

            MyVoxelBase voxelBase = voxel as MyVoxelBase;

            minVoxel += voxelBase.StorageMin;
            maxVoxel += voxelBase.StorageMin;

            voxel.Storage.ClampVoxel(ref minVoxel);
            voxel.Storage.ClampVoxel(ref maxVoxel);

            MyStorageData cache = new MyStorageData();

            cache.Resize(minVoxel, maxVoxel);
            voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, minVoxel, maxVoxel);

            // Grab content and material
            var original = cache.Content(0);

            //var material = cache.Material(0);

            if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY)
            {
                //Logging.Instance.WriteLine(string.Format("Content is empty"));
                return(false);
            }

            return(true);
        }
Пример #21
0
        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);
        }
Пример #22
0
        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;
                    rewrites++;
                }
            }

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

            return(rewrites > 0);
        }
Пример #23
0
        private MyVoxelMaterialDefinition GetVoxelMaterial(MyVoxelBase voxelBase, Vector3D hitPos)
        {
            if (voxelBase.Storage == null || voxelBase.PositionComp == null)
            {
                return(null);
            }

            Vector3D localPosition;
            var      wm = voxelBase.PositionComp.WorldMatrixInvScaled;

            Vector3D.TransformNoProjection(ref hitPos, ref wm, out localPosition);

            var voxelPosition = voxelBase.StorageMin + new Vector3I(localPosition) + (voxelBase.Size >> 1);

            StorageData.Resize(Vector3I.One);
            voxelBase.Storage.ReadRange(StorageData, MyStorageDataTypeFlags.Material, 0, voxelPosition, voxelPosition);

            byte materialIndex = StorageData.Material(0);

            return(MyVoxelMaterialDefinition.Get(materialIndex));
        }
Пример #24
0
        protected void RefreshCache( )
        {
            IMyVoxelMap voxelMap = (IMyVoxelMap)BackingObject;

            m_cache = new MyStorageData( );
            Vector3I size = voxelMap.Storage.Size;

            m_cache.Resize(size);

            //			SandboxGameAssemblyWrapper.Instance.GameAction(() =>
            //			{
            voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, 0, Vector3I.Zero, size - 1);
            //voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, Vector3I.Zero, size - 1);
            //			});

            foreach (byte materialIndex in m_cache.Data)
            {
                try
                {
                    MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition(materialIndex);
                    if (material == null)
                    {
                        continue;
                    }

                    if (!m_materialTotals.ContainsKey(material))
                    {
                        m_materialTotals.Add(material, 1);
                    }
                    else
                    {
                        m_materialTotals[material]++;
                    }
                }
                catch (Exception ex)
                {
                    ApplicationLog.BaseLog.Error(ex);
                }
            }
        }
Пример #25
0
        private bool excludeVoxelBase(Vector3D center, ref HashSet <IMyVoxelBase> asteroids)
        {
            MyStorageData cache = new MyStorageData();

            cache.Resize(Vector3I.One);
            Vector3I voxelCoord;

            foreach (IMyVoxelBase asteroid in asteroids)
            {
                if (asteroid.WorldAABB.Contains(center) != ContainmentType.Contains)
                {
                    continue;
                }
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(asteroid.PositionLeftBottomCorner, ref center, out voxelCoord);
                asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, voxelCoord, voxelCoord);
                if (cache.Content(ref Vector3I.Zero) != (byte)0)
                {
                    return(true);
                }
            }
            return(false);
        }
 void IMyOctreeLeafNode.WriteRange(MyStorageData source, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max)
 {
     m_octree.WriteRange(source, m_dataType, ref readOffset, ref min, ref max);
     if (DEBUG_WRITES)
     {
         var tmp = new MyStorageData();
         tmp.Resize(min, max);
         m_octree.ReadRange(tmp, m_dataType, ref Vector3I.Zero, 0, ref min, ref max);
         Vector3I p            = Vector3I.Zero;
         var      cacheEnd     = max - min;
         int      errorCounter = 0;
         for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref cacheEnd);
              it.IsValid(); it.GetNext(out p))
         {
             var read = readOffset + p;
             if (source.Get(m_dataType, ref read) != tmp.Get(m_dataType, ref p))
             {
                 ++errorCounter;
             }
         }
         Debug.Assert(errorCounter == 0, string.Format("{0} errors writing to leaf octree.", errorCounter));
     }
 }
Пример #27
0
        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);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="voxelMap"></param>
        /// <param name="resolution">0 to 8. 0 for fine/slow detail.</param>
        /// <param name="distance"></param>
        /// <returns></returns>
        private int FindMaterial(IMyVoxelBase voxelMap, Vector3D center, int resolution, double distance)
        {
            int hits = 0;
            var materials = MyDefinitionManager.Static.GetVoxelMaterialDefinitions().Where(v => v.IsRare).ToArray();
            var findMaterial = materials.Select(f => f.Index).ToArray();
            var storage = voxelMap.Storage;
            var scale = (int)Math.Pow(2, resolution);

            //MyAPIGateway.Utilities.ShowMessage("center", center.ToString());
            var point = new Vector3I(center - voxelMap.PositionLeftBottomCorner);
            //MyAPIGateway.Utilities.ShowMessage("point", point.ToString());

            var min = ((point - (int)distance) / 64) * 64;
            min = Vector3I.Max(min, Vector3I.Zero);
            //MyAPIGateway.Utilities.ShowMessage("min", min.ToString());

            var max = ((point + (int)distance) / 64) * 64;
            max = Vector3I.Max(max, min + 64);
            //MyAPIGateway.Utilities.ShowMessage("max", max.ToString());

            //MyAPIGateway.Utilities.ShowMessage("size", voxelMap.StorageName + " " + storage.Size.ToString());

            if (min.X >= storage.Size.X ||
                min.Y >= storage.Size.Y ||
                min.Z >= storage.Size.Z)
            {
                //MyAPIGateway.Utilities.ShowMessage("size", "out of range");
                return 0;
            }

            var oldCache = new MyStorageData();

            //var smin = new Vector3I(0, 0, 0);
            //var smax = new Vector3I(31, 31, 31);
            ////var size = storage.Size;
            //var size = smax - smin + 1;
            //size = new Vector3I(16, 16, 16);
            //oldCache.Resize(size);
            //storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, Vector3I.Zero, size - 1);

            var smax = (max / scale) - 1;
            var smin = (min / scale);
            var size = smax - smin + 1;
            oldCache.Resize(size);
            storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, smin, smax);

            //MyAPIGateway.Utilities.ShowMessage("smax", smax.ToString());
            //MyAPIGateway.Utilities.ShowMessage("size", size .ToString());
            //MyAPIGateway.Utilities.ShowMessage("size - 1", (size - 1).ToString());

            Vector3I p;
            for (p.Z = 0; p.Z < size.Z; ++p.Z)
                for (p.Y = 0; p.Y < size.Y; ++p.Y)
                    for (p.X = 0; p.X < size.X; ++p.X)
                    {
                        // place GPS in the center of the Voxel
                        var position = voxelMap.PositionLeftBottomCorner + (p * scale) + (scale / 2) + min;

                        if (Math.Sqrt((position - center).LengthSquared()) < distance)
                        {
                            var content = oldCache.Content(ref p);
                            var material = oldCache.Material(ref p);

                            if (content > 0 && findMaterial.Contains(material))
                            {
                                var index = Array.IndexOf(findMaterial, material);
                                var name = materials[index].MinedOre;
                                var gps = MyAPIGateway.Session.GPS.Create("Ore " + name, "scanore", position, true, false);
                                MyAPIGateway.Session.GPS.AddGps(MyAPIGateway.Session.Player.IdentityId, gps);
                                hits++;
                            }
                        }
                    }
            return hits;
        }
Пример #29
0
 void IMyOctreeLeafNode.WriteRange(MyStorageData source, ref Vector3I readOffset, ref Vector3I min, ref Vector3I max)
 {
     m_octree.WriteRange(source, m_dataType, ref readOffset, ref min, ref max);
     if (DEBUG_WRITES)
     {
         var tmp = new MyStorageData();
         tmp.Resize(min, max);
         m_octree.ReadRange(tmp, m_dataType, ref Vector3I.Zero, 0, ref min, ref max);
         Vector3I p = Vector3I.Zero;
         var cacheEnd = max - min;
         int errorCounter = 0;
         for (var it = new Vector3I.RangeIterator(ref Vector3I.Zero, ref cacheEnd);
             it.IsValid(); it.GetNext(out p))
         {
             var read = readOffset + p;
             if (source.Get(m_dataType, ref read) != tmp.Get(m_dataType, ref p))
                 ++errorCounter;
         }
         Debug.Assert(errorCounter == 0, string.Format("{0} errors writing to leaf octree.", errorCounter));
     }
 }
        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;
        }
        public override bool Invoke(string messageText)
        {
            if (messageText.StartsWith("/rotateroid ", StringComparison.InvariantCultureIgnoreCase))
            {
                var match = Regex.Match(messageText, @"/rotateroid\s{1,}(?<Key>.+){1,}\s{1,}(?<X>[+-]?((\d+(\.\d*)?)|(\.\d+)))\s{1,}(?<Y>[+-]?((\d+(\.\d*)?)|(\.\d+)))\s{1,}(?<Z>[+-]?((\d+(\.\d*)?)|(\.\d+)))", RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    var rotateVector = new Vector3(
                        double.Parse(match.Groups["X"].Value, CultureInfo.InvariantCulture),
                        double.Parse(match.Groups["Y"].Value, CultureInfo.InvariantCulture),
                        double.Parse(match.Groups["Z"].Value, CultureInfo.InvariantCulture));
                    var searchName = match.Groups["Key"].Value;

                    var currentAsteroidList = new List<IMyVoxelBase>();
                    IMyVoxelBase originalAsteroid = null;
                    MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.Equals(searchName, StringComparison.InvariantCultureIgnoreCase));
                    if (currentAsteroidList.Count == 1)
                    {
                        originalAsteroid = currentAsteroidList[0];
                    }
                    else
                    {
                        MyAPIGateway.Session.VoxelMaps.GetInstances(currentAsteroidList, v => v.StorageName.IndexOf(searchName, StringComparison.InvariantCultureIgnoreCase) >= 0);

                        if (currentAsteroidList.Count == 1)
                        {
                            originalAsteroid = currentAsteroidList[0];
                        }
                    }

                    int index;
                    if (searchName.Substring(0, 1) == "#" && Int32.TryParse(searchName.Substring(1), out index) && index > 0 && index <= CommandAsteroidsList.AsteroidCache.Count)
                    {
                        originalAsteroid = CommandAsteroidsList.AsteroidCache[index - 1];
                    }

                    if (originalAsteroid == null)
                    {
                        MyAPIGateway.Utilities.ShowMessage("Cannot find asteroid", string.Format("'{0}'", searchName));
                        return true;
                    }

                    var quaternion = Quaternion.CreateFromYawPitchRoll(rotateVector.X / (180 / MathHelper.Pi), rotateVector.Y / (180 / MathHelper.Pi), rotateVector.Z / (180 / MathHelper.Pi));
                    var oldStorage = originalAsteroid.Storage;

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

                    var transSize = Vector3I.Transform(oldStorage.Size, quaternion);
                    var newSize = Vector3I.Abs(transSize);
                    var newName = Support.CreateUniqueStorageName(originalAsteroid.StorageName);
                    var newVoxelMap = Support.CreateNewAsteroid(newName, newSize, originalAsteroid.PositionLeftBottomCorner);

                    var cache = new MyStorageData();
                    var min = Vector3I.Zero;
                    var max = newSize - 1;
                    cache.Resize(min, max);

                    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 content = oldCache.Content(ref p);
                                var material = oldCache.Material(ref p);

                                var newP = Vector3I.Transform(p, quaternion);
                                // readjust the points, as rotation occurs arround 0,0,0.
                                newP.X = newP.X < 0 ? newP.X - transSize.X - 1 : newP.X;
                                newP.Y = newP.Y < 0 ? newP.Y - transSize.Y - 1 : newP.Y;
                                newP.Z = newP.Z < 0 ? newP.Z - transSize.Z - 1 : newP.Z;

                                cache.Content(ref newP, content);
                                cache.Material(ref newP, material);
                            }

                    newVoxelMap.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, min, max);
                    MyAPIGateway.Entities.RemoveEntity((IMyEntity)originalAsteroid);

                    // Invalidate the cache, to force user to select again to prevent possible corruption by using an old cache.
                    CommandAsteroidsList.AsteroidCache.Clear();
                    return true;
                }
            }

            return false;
        }
Пример #32
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;
        }
Пример #33
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;
        }
            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);
                }
            }
        private void ProcessAsteroid(string displayType, string displayName, IMyVoxelMap voxelMap, double distance, BoundingBoxD aabb)
        {
            Vector3I min = Vector3I.MaxValue;
            Vector3I max = Vector3I.MinValue;
            Vector3I block;
            Dictionary <byte, long> assetCount = new Dictionary <byte, long>();

            // read the asteroid in chunks of 64 to avoid the Arithmetic overflow issue.
            for (block.Z = 0; block.Z < voxelMap.Storage.Size.Z; block.Z += 64)
            {
                for (block.Y = 0; block.Y < voxelMap.Storage.Size.Y; block.Y += 64)
                {
                    for (block.X = 0; block.X < voxelMap.Storage.Size.X; block.X += 64)
                    {
                        var cacheSize = new Vector3I(64);
                        var oldCache  = new MyStorageData();
                        oldCache.Resize(cacheSize);
                        // LOD1 is not detailed enough for content information on asteroids.
                        voxelMap.Storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1);

                        Vector3I p;
                        for (p.Z = 0; p.Z < cacheSize.Z; ++p.Z)
                        {
                            for (p.Y = 0; p.Y < cacheSize.Y; ++p.Y)
                            {
                                for (p.X = 0; p.X < cacheSize.X; ++p.X)
                                {
                                    var content = oldCache.Content(ref p);
                                    if (content > 0)
                                    {
                                        min = Vector3I.Min(min, p + block);
                                        max = Vector3I.Max(max, p + block + 1);

                                        var material = oldCache.Material(ref p);
                                        if (assetCount.ContainsKey(material))
                                        {
                                            assetCount[material] += content;
                                        }
                                        else
                                        {
                                            assetCount.Add(material, content);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            var assetNameCount = new Dictionary <string, long>();

            foreach (var kvp in assetCount)
            {
                var name = MyDefinitionManager.Static.GetVoxelMaterialDefinition(kvp.Key).Id.SubtypeName;
                if (assetNameCount.ContainsKey(name))
                {
                    assetNameCount[name] += kvp.Value;
                }
                else
                {
                    assetNameCount.Add(name, kvp.Value);
                }
            }
            assetNameCount = assetNameCount.OrderByDescending(e => e.Value).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            var sum  = assetNameCount.Values.Sum();
            var ores = new StringBuilder();

            foreach (var kvp in assetNameCount)
            {
                ores.AppendFormat("{0}  {1:N}  {2:P}\r\n", kvp.Key, (double)kvp.Value / 255, (double)kvp.Value / (double)sum);
            }

            var contentBox  = new BoundingBoxD(voxelMap.PositionLeftBottomCorner + min, voxelMap.PositionLeftBottomCorner + max);
            var description = string.Format("Distance: {0:N}\r\nSize: {1}\r\nBoundingBox Center: [X:{2:N} Y:{3:N} Z:{4:N}]\r\n\r\nContent Size:{5}\r\nLOD0 Content Center: [X:{6:N} Y:{7:N} Z:{8:N}]\r\n\r\nMaterial  Mass  Percent\r\n{9}",
                                            distance, voxelMap.Storage.Size,
                                            aabb.Center.X, aabb.Center.Y, aabb.Center.Z,
                                            max - min,
                                            contentBox.Center.X, contentBox.Center.Y, contentBox.Center.Z,
                                            ores);

            MyAPIGateway.Utilities.ShowMissionScreen(string.Format("ID {0}:", displayType), string.Format("'{0}'", displayName), " ", description, null, "OK");
        }
        private void ProcessAsteroid(string displayType, string displayName, IMyVoxelMap voxelMap, double distance, BoundingBoxD aabb)
        {
            Vector3I min = Vector3I.MaxValue;
            Vector3I max = Vector3I.MinValue;
            Vector3I block;
            Dictionary<byte, long> assetCount = new Dictionary<byte, long>();

            // read the asteroid in chunks of 64 to avoid the Arithmetic overflow issue.
            for (block.Z = 0; block.Z < voxelMap.Storage.Size.Z; block.Z += 64)
                for (block.Y = 0; block.Y < voxelMap.Storage.Size.Y; block.Y += 64)
                    for (block.X = 0; block.X < voxelMap.Storage.Size.X; block.X += 64)
                    {
                        var cacheSize = new Vector3I(64);
                        var oldCache = new MyStorageData();
                        oldCache.Resize(cacheSize);
                        // LOD1 is not detailed enough for content information on asteroids.
                        voxelMap.Storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1);

                        Vector3I p;
                        for (p.Z = 0; p.Z < cacheSize.Z; ++p.Z)
                            for (p.Y = 0; p.Y < cacheSize.Y; ++p.Y)
                                for (p.X = 0; p.X < cacheSize.X; ++p.X)
                                {
                                    var content = oldCache.Content(ref p);
                                    if (content > 0)
                                    {
                                        min = Vector3I.Min(min, p + block);
                                        max = Vector3I.Max(max, p + block + 1);

                                        var material = oldCache.Material(ref p);
                                        if (assetCount.ContainsKey(material))
                                            assetCount[material] += content;
                                        else
                                            assetCount.Add(material, content);
                                    }
                                }
                    }

            var assetNameCount = new Dictionary<string, long>();
            foreach (var kvp in assetCount)
            {
                var name = MyDefinitionManager.Static.GetVoxelMaterialDefinition(kvp.Key).Id.SubtypeName;
                if (assetNameCount.ContainsKey(name))
                    assetNameCount[name] += kvp.Value;
                else
                    assetNameCount.Add(name, kvp.Value);
            }
            assetNameCount = assetNameCount.OrderByDescending(e => e.Value).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            var sum = assetNameCount.Values.Sum();
            var ores = new StringBuilder();

            foreach (var kvp in assetNameCount)
                ores.AppendFormat("{0}  {1:N}  {2:P}\r\n", kvp.Key, (double)kvp.Value / 255, (double)kvp.Value / (double)sum);

            var contentBox = new BoundingBoxD(voxelMap.PositionLeftBottomCorner + min, voxelMap.PositionLeftBottomCorner + max);
            var description = string.Format("Distance: {0:N}\r\nSize: {1}\r\nBoundingBox Center: [X:{2:N} Y:{3:N} Z:{4:N}]\r\n\r\nContent Size:{5}\r\nLOD0 Content Center: [X:{6:N} Y:{7:N} Z:{8:N}]\r\n\r\nMaterial  Mass  Percent\r\n{9}",
                distance, voxelMap.Storage.Size,
                aabb.Center.X, aabb.Center.Y, aabb.Center.Z,
                max - min,
                contentBox.Center.X, contentBox.Center.Y, contentBox.Center.Z,
                ores);

            MyAPIGateway.Utilities.ShowMissionScreen(string.Format("ID {0}:", displayType), string.Format("'{0}'", displayName), " ", description, null, "OK");
        }
Пример #37
0
        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 ReplaceAsteroidMaterial(IMyVoxelBase originalAsteroid, string searchMaterialName1, string searchMaterialName2)
        {
            MyVoxelMaterialDefinition material1;
            string suggestedMaterials = "";
            if (!Support.FindMaterial(searchMaterialName1, out material1, ref suggestedMaterials))
            {
                MyAPIGateway.Utilities.ShowMessage("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.ShowMessage("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.ShowMessage("Asteroid", "'{0}' material '{1}' replaced with '{2}'.", originalAsteroid.StorageName, material1.Id.SubtypeName, material2.Id.SubtypeName);
            return true;
        }
Пример #39
0
        /// <summary>
        /// For debugging/testing only! This can be very slow for large storage.
        /// </summary>
        public void Voxelize(MyStorageDataTypeFlags data)
        {
            MyVoxelRequestFlags flags = 0;
            var cache = new MyStorageData();

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

            OnRangeChanged(Vector3I.Zero, Size - 1, data);
        }
        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;
        }
        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);

            }
        }
Пример #42
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();
#if !XB1
            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);
#else // XB1
            System.Diagnostics.Debug.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);
#endif // XB1

            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);
        }
        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;
        }
Пример #44
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="voxelMap"></param>
        /// <param name="center"></param>
        /// <param name="resolution">0 to 8. 0 for fine/slow detail.</param>
        /// <param name="distance"></param>
        /// <param name="scanHits"></param>
        /// <returns></returns>
        private void FindMaterial(IMyVoxelBase voxelMap, Vector3D center, int resolution, double distance, List <ScanHit> scanHits)
        {
            const double checkDistance = 50 * 50;  // 50 meter seperation.
            var          materials     = MyDefinitionManager.Static.GetVoxelMaterialDefinitions().Where(v => v.IsRare).ToArray();
            var          findMaterial  = materials.Select(f => f.Index).ToArray();
            var          storage       = voxelMap.Storage;
            var          scale         = (int)Math.Pow(2, resolution);

            //MyAPIGateway.Utilities.ShowMessage("center", center.ToString());
            var point = new Vector3I(center - voxelMap.PositionLeftBottomCorner);
            //MyAPIGateway.Utilities.ShowMessage("point", point.ToString());

            var min = ((point - (int)distance) / 64) * 64;

            min = Vector3I.Max(min, Vector3I.Zero);
            //MyAPIGateway.Utilities.ShowMessage("min", min.ToString());

            var max = ((point + (int)distance) / 64) * 64;

            max = Vector3I.Max(max, min + 64);
            //MyAPIGateway.Utilities.ShowMessage("max", max.ToString());

            //MyAPIGateway.Utilities.ShowMessage("size", voxelMap.StorageName + " " + storage.Size.ToString());

            if (min.X >= storage.Size.X ||
                min.Y >= storage.Size.Y ||
                min.Z >= storage.Size.Z)
            {
                //MyAPIGateway.Utilities.ShowMessage("size", "out of range");
                return;
            }

            var oldCache = new MyStorageData();

            //var smin = new Vector3I(0, 0, 0);
            //var smax = new Vector3I(31, 31, 31);
            ////var size = storage.Size;
            //var size = smax - smin + 1;
            //size = new Vector3I(16, 16, 16);
            //oldCache.Resize(size);
            //storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, Vector3I.Zero, size - 1);

            var smax = (max / scale) - 1;
            var smin = (min / scale);
            var size = smax - smin + 1;

            oldCache.Resize(size);
            storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, resolution, smin, smax);

            //MyAPIGateway.Utilities.ShowMessage("smax", smax.ToString());
            //MyAPIGateway.Utilities.ShowMessage("size", size .ToString());
            //MyAPIGateway.Utilities.ShowMessage("size - 1", (size - 1).ToString());

            Vector3I p;

            for (p.Z = 0; p.Z < size.Z; ++p.Z)
            {
                for (p.Y = 0; p.Y < size.Y; ++p.Y)
                {
                    for (p.X = 0; p.X < size.X; ++p.X)
                    {
                        // place GPS in the center of the Voxel
                        Vector3D position = voxelMap.PositionLeftBottomCorner + (p * scale) + (scale / 2f) + min;

                        if (Math.Sqrt((position - center).LengthSquared()) < distance)
                        {
                            byte content  = oldCache.Content(ref p);
                            byte material = oldCache.Material(ref p);

                            if (content > 0 && findMaterial.Any(m => m == material))
                            {
                                bool addHit = true;
                                foreach (ScanHit scanHit in scanHits)
                                {
                                    if (scanHit.Material == material && Vector3D.DistanceSquared(position, scanHit.Position) < checkDistance)
                                    {
                                        addHit = false;
                                        break;
                                    }
                                }
                                if (addHit)
                                {
                                    scanHits.Add(new ScanHit(position, material));
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #45
0
        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;
        }
Пример #46
0
        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);
        }
        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();
                }
            }
        }
Пример #48
0
        public static void MakeCrater(MyVoxelBase voxelMap, BoundingSphereD sphere, Vector3 normal, MyVoxelMaterialDefinition material)
        {
            ProfilerShort.Begin("MakeCrater");

            Vector3I minCorner, maxCorner;

            {
                Vector3D sphereMin = sphere.Center - (sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES);
                Vector3D sphereMax = sphere.Center + (sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES);
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMin, out minCorner);
                MyVoxelCoordSystems.WorldPositionToVoxelCoord(voxelMap.PositionLeftBottomCorner, ref sphereMax, out maxCorner);
            }


            voxelMap.Storage.ClampVoxelCoord(ref minCorner);
            voxelMap.Storage.ClampVoxelCoord(ref maxCorner);

            //  We are tracking which voxels were changed, so we can invalidate only needed cells in the cache
            bool changed = false;

            ProfilerShort.Begin("Reading cache");
            m_cache.Resize(minCorner, maxCorner);
            voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, ref minCorner, ref maxCorner);
            ProfilerShort.End();

            ProfilerShort.Begin("Changing cache");
            int      removedVoxelContent = 0;
            Vector3I tempVoxelCoord;
            Vector3I cachePos;

            for (tempVoxelCoord.Z = minCorner.Z, cachePos.Z = 0; tempVoxelCoord.Z <= maxCorner.Z; tempVoxelCoord.Z++, ++cachePos.Z)
            {
                for (tempVoxelCoord.Y = minCorner.Y, cachePos.Y = 0; tempVoxelCoord.Y <= maxCorner.Y; tempVoxelCoord.Y++, ++cachePos.Y)
                {
                    for (tempVoxelCoord.X = minCorner.X, cachePos.X = 0; tempVoxelCoord.X <= maxCorner.X; tempVoxelCoord.X++, ++cachePos.X)
                    {
                        Vector3D voxelPosition;
                        MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxelMap.PositionLeftBottomCorner, ref tempVoxelCoord, out voxelPosition);

                        float addDist = (float)(voxelPosition - sphere.Center).Length();
                        float addDiff = (float)(addDist - sphere.Radius);

                        byte newContent;
                        if (addDiff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (addDiff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - addDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        byte originalContent = m_cache.Content(ref cachePos);

                        if (newContent > originalContent && originalContent > 0)
                        {
                            if (material != null)
                            {
                                m_cache.Material(ref cachePos, material.Index);
                            }

                            changed = true;
                            m_cache.Content(ref cachePos, newContent);
                        }

                        float delDist = (float)(voxelPosition - (sphere.Center + (float)sphere.Radius * 0.7f * normal)).Length();
                        float delDiff = (float)(delDist - sphere.Radius);

                        byte contentToRemove;
                        if (delDiff > MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (delDiff < -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            //  This formula will work even if diff is positive or negative
                            contentToRemove = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - delDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                        }

                        originalContent = m_cache.Content(ref cachePos);

                        if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY && contentToRemove > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                        {
                            changed = true;

                            int newVal = originalContent - contentToRemove;
                            if (newVal < MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                            {
                                newVal = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            m_cache.Content(ref cachePos, (byte)newVal);

                            removedVoxelContent += originalContent - newVal;
                        }

                        float setDist = (float)(voxelPosition - (sphere.Center - (float)sphere.Radius * 0.5f * normal)).Length();
                        float setDiff = (float)(setDist - sphere.Radius / 4f);

                        if (setDiff <= MyVoxelConstants.VOXEL_SIZE_IN_METRES * 1.5f)  // could be VOXEL_SIZE_IN_METRES_HALF, but we want to set material in empty cells correctly
                        {
                            byte indestructibleContentToSet = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            if (setDiff >= MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)  // outside
                            {
                                indestructibleContentToSet = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else if (setDiff >= -MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF)  // boundary
                            {
                                indestructibleContentToSet = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - setDiff / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            }

                            MyVoxelMaterialDefinition originalMaterial = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref cachePos));

                            // Change the material:
                            // - always on boundaries between material and nothing
                            // - smoothly on inner boundaries
                            MyVoxelMaterialDefinition newMaterial = material;
                            if (setDiff > 0)
                            {
                                byte content = m_cache.Content(ref cachePos);
                                if (content == MyVoxelConstants.VOXEL_CONTENT_FULL)
                                {
                                    newMaterial = originalMaterial;
                                }
                                if (setDiff >= MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF && content != MyVoxelConstants.VOXEL_CONTENT_EMPTY)  // set material behind boundary only for empty voxels
                                {
                                    newMaterial = originalMaterial;
                                }
                            }

                            if (originalMaterial == newMaterial)
                            {
                                continue;
                            }

                            m_cache.Material(ref cachePos, newMaterial.Index);
                            changed = true;
                        }

                        float dist = (float)(voxelPosition - sphere.Center).Length();
                        float diff = (float)(dist - sphere.Radius);

                        if (diff <= 0f)
                        {
                            originalContent = m_cache.Content(ref cachePos);
                            if (originalContent > MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                            {
                                bool wrinkled = m_cache.WrinkleVoxelContent(ref cachePos, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_ADD, MyVoxelConstants.DEFAULT_WRINKLE_WEIGHT_REMOVE);
                                if (wrinkled)
                                {
                                    changed = true;
                                }
                            }
                        }
                    }
                }
            }
            ProfilerShort.End();

            if (changed)
            {
                ProfilerShort.Begin("RemoveSmallVoxelsUsingChachedVoxels");
                RemoveSmallVoxelsUsingChachedVoxels();
                ProfilerShort.BeginNextBlock("Writing cache");
                voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, ref minCorner, ref maxCorner);
                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
Пример #49
0
		protected void RefreshCache( )
		{
			IMyVoxelMap voxelMap = (IMyVoxelMap)BackingObject;
			m_cache = new MyStorageData( );
			Vector3I size = voxelMap.Storage.Size;
			m_cache.Resize( size );

			//			SandboxGameAssemblyWrapper.Instance.GameAction(() =>
			//			{
			voxelMap.Storage.ReadRange( m_cache, MyStorageDataTypeFlags.Material, 0, Vector3I.Zero, size - 1 );
			//voxelMap.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.Material, Vector3I.Zero, size - 1);
			//			});

			foreach ( byte materialIndex in m_cache.Data )
			{
				try
				{
					MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition( materialIndex );
					if ( material == null )
						continue;

					if ( !m_materialTotals.ContainsKey( material ) )
						m_materialTotals.Add( material, 1 );
					else
						m_materialTotals[ material ]++;
				}
				catch ( Exception ex )
				{
					ApplicationLog.BaseLog.Error( ex );
				}
			}
		}