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);
        }
Esempio n. 2
0
        byte IMyOctreeLeafNode.GetFilteredValue()
        {
            MyStorageData filteredValueBuffer = FilteredValueBuffer;

            this.m_provider.ReadRange(filteredValueBuffer, this.m_dataType.ToFlags(), ref Vector3I.Zero, this.m_cell.Lod, ref this.m_cell.CoordInLod, ref this.m_cell.CoordInLod);
            return((this.m_dataType == MyStorageDataTypeEnum.Material) ? filteredValueBuffer.Material(0) : filteredValueBuffer.Content(0));
        }
        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);
        }
Esempio n. 4
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)));
        }
Esempio n. 5
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);
        }
        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);
        }
Esempio n. 7
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 unsafe void DrawMaterialsInfo(MyStorageData data)
            {
                int *counts = stackalloc int[256];

                int cellCount = data.SizeLinear / data.StepLinear;

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

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

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

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

                hits.Sort();

                int maxMaterial = MyDefinitionManager.Static.VoxelMaterialCount;

                foreach (var info in hits)
                {
                    if (info.Material == MyVoxelConstants.NULL_MATERIAL)
                    {
                        Text("    Null Material: {0}", info.Count);
                    }
                    else if (info.Material > maxMaterial)
                    {
                        Text("    Invalid Material({1}): {0}", info.Count, info.Material);
                    }
                    else
                    {
                        Text("    {1}: {0}", info.Count, MyDefinitionManager.Static.GetVoxelMaterialDefinition(info.Material).Id.SubtypeName);
                    }
                }
            }
Esempio n. 9
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);
        }
Esempio n. 10
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));
        }
        private bool IsValidVoxelTarget(NaniteMiningItem target, IMyEntity entity)
        {
            if (entity == null)
            {
                return(false);
            }

            byte         material2 = 0;
            float        amount = 0;
            IMyVoxelBase voxel = entity as IMyVoxelBase;
            Vector3D     targetMin = target.Position;
            Vector3D     targetMax = target.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);
            var flag = MyVoxelRequestFlags.AdviseCache;

            cache.ClearContent(0);
            cache.ClearMaterials(0);

            byte original = 0;

            voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, minVoxel, maxVoxel, ref flag);

            original  = cache.Content(0);
            material2 = cache.Material(0);

            if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY)
            {
                Logging.Instance.WriteLine("[Mining] Content is empty!", 2);
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                          { AddMinedPosition(target); });
                return(false);
            }

            Logging.Instance.WriteLine($"[Mining] Material: SizeLinear: {cache.SizeLinear}, Size3D: {cache.Size3D}, AboveISO: {cache.ContainsVoxelsAboveIsoLevel()}", 2);
            cache.Content(0, 0);

            var voxelMat = target.Definition;

            target.Amount = CalculateAmount(voxelMat, original * 8f);

            Logging.Instance.WriteLine($"[Mining] Removing: {target.Position} ({material2} {amount})", 2);

            if (material2 == 0)
            {
                Logging.Instance.WriteLine("[Mining] Material is 0", 2);
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                          { AddMinedPosition(target); });
                return(false);
            }

            if (target.Amount == 0f)
            {
                Logging.Instance.WriteLine("[Mining] Amount is 0", 2);
                MyAPIGateway.Utilities.InvokeOnGameThread(() =>
                                                          { AddMinedPosition(target); });
                return(false);
            }

            return(true);
        }
        internal void ReadMaterialRange(MyStorageData target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            float          lodVoxelSizeHalf;
            BoundingBox    queryBox;
            BoundingSphere querySphere;

            SetupReading(lodIndex, ref minInLod, ref maxInLod, out lodVoxelSizeHalf, out queryBox, out querySphere);
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

            var overlappedDeposits = OverlappedDeposits;

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

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


            ProfilerShort.Begin("Material computation");

            Vector3I v;

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

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

                        var write = v - minInLod + writeOffset;
                        target.Material(ref write, closestMaterialIdx);
                    }
                }
            }
            ProfilerShort.End();
        }
        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;
        }
        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;
        }
        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");
        }
Esempio n. 16
0
        private void MergeAsteroidMaterialFrom(ref MyVoxelMap newAsteroid, Vector3 min, StructureVoxelModel modelPrimary, StructureVoxelModel modelSecondary, Vector3 minPrimary, Vector3 minSecondary)
        {
            var      filenameSecondary = modelSecondary.SourceVoxelFilepath ?? modelSecondary.VoxelFilepath;
            var      filenamePrimary   = modelPrimary.SourceVoxelFilepath ?? modelPrimary.VoxelFilepath;
            Vector3I block;
            Vector3I newBlock;
            Vector3I cacheSize;

            var asteroid = new MyVoxelMap();

            asteroid.Load(filenamePrimary);
            BoundingBoxI content = modelPrimary.InflatedContentBounds;

            for (block.Z = content.Min.Z; block.Z <= content.Max.Z; block.Z += 64)
            {
                for (block.Y = content.Min.Y; block.Y <= content.Max.Y; block.Y += 64)
                {
                    for (block.X = content.Min.X; block.X <= content.Max.X; block.X += 64)
                    {
                        var cache = new MyStorageData();
                        cacheSize = new Vector3I(MathHelper.Min(content.Max.X, block.X + 63) - block.X + 1,
                                                 MathHelper.Min(content.Max.Y, block.Y + 63) - block.Y + 1,
                                                 MathHelper.Min(content.Max.Z, block.Z + 63) - block.Z + 1);

                        cache.Resize(cacheSize);
                        asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1);

                        newBlock = ((minPrimary - min) + (Vector3D)(block - content.Min)).RoundToVector3I();
                        newAsteroid.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1);
                    }
                }
            }

            asteroid.Load(filenameSecondary);
            content = modelSecondary.InflatedContentBounds;
            for (block.Z = content.Min.Z; block.Z <= content.Max.Z; block.Z += 64)
            {
                for (block.Y = content.Min.Y; block.Y <= content.Max.Y; block.Y += 64)
                {
                    for (block.X = content.Min.X; block.X <= content.Max.X; block.X += 64)
                    {
                        var cache = new MyStorageData();
                        cacheSize = new Vector3I(MathHelper.Min(content.Max.X, block.X + 63) - block.X + 1,
                                                 MathHelper.Min(content.Max.Y, block.Y + 63) - block.Y + 1,
                                                 MathHelper.Min(content.Max.Z, block.Z + 63) - block.Z + 1);

                        cache.Resize(cacheSize);
                        asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1);

                        newBlock = ((minSecondary - min) + (Vector3D)(block - content.Min)).RoundToVector3I();
                        var newCache = new MyStorageData();
                        newCache.Resize(cacheSize);
                        newAsteroid.Storage.ReadRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, newBlock, newBlock + 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)
                                {
                                    byte volume   = cache.Content(ref p);
                                    byte material = cache.Material(ref p);
                                    if (volume > 0)
                                    {
                                        newCache.Material(ref p, material);
                                    }
                                }
                            }
                        }

                        newAsteroid.Storage.WriteRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1);
                    }
                }
            }
        }
        /// <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;
        }
        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;
        }
Esempio n. 19
0
        public MyIsoMesh Precalc(IMyStorage storage, int lod, Vector3I voxelStart, Vector3I voxelEnd, bool generateMaterials, bool useAmbient, bool doNotCheck = false)
        {
            // change range so normal can be computed at edges (expand by 1 in all directions)
            voxelStart -= 1;
            voxelEnd   += 1;

            if (storage == null)
            {
                return(null);
            }

            using (storage.Pin())
            {
                if (storage.Closed)
                {
                    return(null);
                }

                MyVoxelRequestFlags request = MyVoxelRequestFlags.ContentChecked; // | (doNotCheck ? MyVoxelRequestFlags.DoNotCheck : 0);
                //if (lod == 0 && generateMaterials) request |= MyVoxelRequestFlags.AdviseCache;

                bool readAmbient = false;

                if (generateMaterials && storage.DataProvider != null && storage.DataProvider.ProvidesAmbient)
                {
                    readAmbient = true;
                }

                m_cache.Resize(voxelStart, voxelEnd);
                if (readAmbient)
                {
                    m_cache.StoreOcclusion = true;
                }

                storage.ReadRange(m_cache, MyStorageDataTypeFlags.Content, lod, ref voxelStart, ref voxelEnd, ref request);

                if (request.HasFlag(MyVoxelRequestFlags.EmptyContent) || request.HasFlag(MyVoxelRequestFlags.FullContent) ||
                    (!request.HasFlag(MyVoxelRequestFlags.ContentChecked) && !m_cache.ContainsIsoSurface()))
                {
                    //if(generateMaterials && lod == 0) Debugger.Break();
                    //storage.DebugDrawChunk(voxelStart, voxelEnd);
                    return(null);
                }

                var    center           = (storage.Size / 2) * MyVoxelConstants.VOXEL_SIZE_IN_METRES;
                var    voxelSize        = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << lod);
                var    vertexCellOffset = voxelStart - AffectedRangeOffset;
                double numCellsHalf     = 0.5 * (m_cache.Size3D.X - 3);
                var    posOffset        = ((Vector3D)vertexCellOffset + numCellsHalf) * (double)voxelSize;

                if (generateMaterials)
                {
                    // 255 is the new black
                    m_cache.ClearMaterials(255);
                }

                if (readAmbient)
                {
                    m_cache.Clear(MyStorageDataTypeEnum.Occlusion, 0);
                }

                IsoMesher mesher = new IsoMesher();
                ProfilerShort.Begin("Dual Contouring");
                unsafe
                {
                    fixed(byte *content = m_cache[MyStorageDataTypeEnum.Content])
                    fixed(byte *material = m_cache[MyStorageDataTypeEnum.Material])
                    {
                        var size3d = m_cache.Size3D;

                        Debug.Assert(size3d.X == size3d.Y && size3d.Y == size3d.Z);
                        mesher.Calculate(size3d.X, content, material, m_buffer, useAmbient, posOffset - center);
                    }
                }
                ProfilerShort.End();

                if (generateMaterials)
                {
                    request = 0;

                    request |= MyVoxelRequestFlags.SurfaceMaterial;
                    request |= MyVoxelRequestFlags.ConsiderContent;

                    var req = readAmbient ? MyStorageDataTypeFlags.Material | MyStorageDataTypeFlags.Occlusion : MyStorageDataTypeFlags.Material;

                    storage.ReadRange(m_cache, req, lod, ref voxelStart, ref voxelEnd, ref request);

                    FixCacheMaterial(voxelStart, voxelEnd);
                    unsafe
                    {
                        fixed(byte *content = m_cache[MyStorageDataTypeEnum.Content])
                        fixed(byte *material = m_cache[MyStorageDataTypeEnum.Material])
                        {
                            int materialOverride = request.HasFlag(MyVoxelRequestFlags.OneMaterial) ? m_cache.Material(0) : -1;
                            var size3d           = m_cache.Size3D;

                            Debug.Assert(size3d.X == size3d.Y && size3d.Y == size3d.Z);

                            if (readAmbient)
                                fixed(byte *ambient = m_cache[MyStorageDataTypeEnum.Occlusion])
                                mesher.CalculateMaterials(size3d.X, content, material, ambient, materialOverride);
                            else
                            {
                                mesher.CalculateMaterials(size3d.X, content, material, null, materialOverride);
                            }
                        }
                    }
                }
                else
                {
                    m_cache.ClearMaterials(0);
                }

                mesher.Finish(m_buffer);

                if (m_buffer.VerticesCount == 0 || m_buffer.Triangles.Count == 0)
                {
                    return(null);
                }

                ProfilerShort.Begin("Geometry post-processing");
                {
                    var positions   = m_buffer.Positions.GetInternalArray();
                    var vertexCells = m_buffer.Cells.GetInternalArray();
                    var materials   = m_buffer.Materials.GetInternalArray();
                    for (int i = 0; i < m_buffer.VerticesCount; i++)
                    {
                        Debug.Assert(positions[i].IsInsideInclusive(ref Vector3.MinusOne, ref Vector3.One));
                        vertexCells[i] += vertexCellOffset;
                        Debug.Assert(vertexCells[i].IsInsideInclusive(voxelStart + 1, voxelEnd - 1));
                        Debug.Assert(materials[i] != MyVoxelConstants.NULL_MATERIAL);
                    }

                    m_buffer.PositionOffset = posOffset;
                    m_buffer.PositionScale  = new Vector3((float)(numCellsHalf * voxelSize));
                    m_buffer.CellStart      = voxelStart + 1;
                    m_buffer.CellEnd        = voxelEnd - 1;
                }
                ProfilerShort.End();

                // Replace filled mesh with new one.
                // This way prevents allocation of meshes which then end up empty.
                var buffer = m_buffer;
                m_buffer = new MyIsoMesh();
                return(buffer);
            }
        }
        protected override IEnumerator <bool> ProcessVoxels(HashSet <IMyVoxelBase> Voxels)
        {
            if (!MyKernel.Session.Settings.EnableDrilling)
            {
                yield return(false);
            }
            if (Voxels.Count == 0)
            {
                yield return(false);
            }
            if (MyKernel.TermControls.ToolMode == true)
            {
                yield return(false);
            }
            if (!SafeZonesHelper.IsActionAllowed(MyKernel.Block.GetPosition(), MySafeZoneAction.Drilling, MyKernel.Block.EntityId))
            {
                yield return(false);
            }
            //WriteToLog("ProcessVoxels", $"Processing {Voxels.Count} voxels");
            Stopwatch stopwatch  = Stopwatch.StartNew();
            LineD     WorkingRay = new LineD(MyKernel.BeamDrawer.BeamStart, MyKernel.BeamDrawer.BeamEnd);

            foreach (MyVoxelBase Voxel in Voxels.OfType <MyVoxelBase>())
            {
                if (!SafeZonesHelper.IsActionAllowed((Voxel as IMyEntity).WorldAABB, MySafeZoneAction.Drilling, MyKernel.Block.EntityId))
                {
                    continue;
                }
                if (Voxel.GetOrePriority() == -1)
                {
                    continue;                               // Idk why, but the same early exit is found in MyShipDrill
                }
                Vector3D?VoxelHit = Voxel.GetClosestPointOnRay(WorkingRay, step: 0.99f);
                if (VoxelHit.HasValue)
                {
                    MyKernel.ResponderModule.UpdateStatusReport($"\r\nFound a voxel", true);
                    lock (BlockedVoxels)
                    {
                        if (!BlockedVoxels.ContainsKey(Voxel.EntityId))
                        {
                            BlockedVoxels.Add(Voxel.EntityId, new List <Vector3I>());
                        }
                    }
                    Vector3D hitpos = VoxelHit.Value;
                    //MyVoxelMaterialDefinition Material = Voxel.GetMaterialAt(ref hitpos);
                    Vector3D CutoutSphereCenter = hitpos + (-WorkingRay.Direction * DrillingOffsetM);
                    //stopwatch.Stop();
                    //WriteToLog("ProcessVoxels", $"Hit: {Math.Round(Vector3D.Distance(WorkingRay.From, hitpos), 2)}m, cutout: {Math.Round(Vector3D.Distance(WorkingRay.From, CutoutSphereCenter), 2)} m away, Material: {(Material != null ? Material.MaterialTypeName : "null")}");
                    //stopwatch.Start();

                    BoundingSphereD Cutout = new BoundingSphereD(CutoutSphereCenter, CutoutRadius);

                    //List<Vector3I> VoxelPoints = Voxel.GetVoxelPointsInSphere(Cutout);
                    Vector3I      refCorner;
                    Vector3I      refMaxCorner;
                    MyStorageData cutoutVoxels = Voxel.GetVoxelCacheInSphere(Cutout, out refCorner, out refMaxCorner);
                    //WriteToLog("ProcessVoxels", $"Cutout cache Min is {Math.Round(Vector3D.Distance(hitpos, Voxel.PositionLeftBottomCorner + refCorner), 2)}m away");
                    //WriteToLog("ProcessVoxels", $"Cutout cache Max is {Math.Round(Vector3D.Distance(hitpos, Voxel.PositionLeftBottomCorner + refCorner + cutoutVoxels.Size3D), 2)}m away");
                    Dictionary <MyVoxelMaterialDefinition, float> Materials = new Dictionary <MyVoxelMaterialDefinition, float>();

                    int       nullMaterials   = 0;
                    int       totalPoints     = 0;
                    Stopwatch enumeratorWatch = new Stopwatch();
                    using (MyStorageData.MortonEnumerator VoxelLoop = new MyStorageData.MortonEnumerator(cutoutVoxels, MyStorageDataTypeEnum.Content | MyStorageDataTypeEnum.Material))
                    {
                        MyKernel.ResponderModule.UpdateStatusReport($"Entered enumerator", true);
                        enumeratorWatch.Start();
                        Dictionary <byte, float> RawMaterials = new Dictionary <byte, float>();
                        Vector3I VoxelInSphereCenter;
                        Vector3  CoordsSystemOutValue;
                        //MyVoxelCoordSystems.WorldPositionToLocalPosition(Cutout.Center, Voxel.PositionComp.WorldMatrix, Voxel.PositionComp.WorldMatrixInvScaled, Voxel.SizeInMetresHalf, out CoordsSystemOutValue);
                        //VoxelInSphereCenter = new Vector3I(CoordsSystemOutValue / 1f) + Voxel.StorageMin;
                        Vector3D sphereCenter = Cutout.Center;
                        MyVoxelCoordSystems.WorldPositionToLocalPosition(Voxel.PositionLeftBottomCorner, ref sphereCenter, out CoordsSystemOutValue);
                        VoxelInSphereCenter = new Vector3I(CoordsSystemOutValue / 1f) + Voxel.StorageMin;
                        Vector3D ReconstructedPosition = Voxel.PositionLeftBottomCorner + VoxelInSphereCenter;
                        //WriteToLog("ProcessVoxels", $"VoxelInSphereCenter is {Math.Round(Vector3D.Distance(hitpos, ReconstructedPosition), 2)}m away from hitpos");
                        double CutoutRadiusSquared = Cutout.Radius * Cutout.Radius;

                        int processedPoints = 0;
                        int skippedPoints   = 0;
                        int linearIndex     = -1;
                        for (bool move = true; move != false;)
                        {
                            enumeratorWatch.Start();
                            try
                            {
                                move = VoxelLoop.MoveNext();
                            }
                            catch
                            {
                                move = false;
                                MyKernel.ResponderModule.UpdateStatusReport("Keen enumerator died", true);
                            }
                            if (move)
                            {
                                linearIndex++;
                                Vector3I voxelPoint;
                                cutoutVoxels.ComputePosition(linearIndex, out voxelPoint);
                                voxelPoint += refCorner;
                                BoundingBoxD voxelBox = new BoundingBoxD(Voxel.PositionLeftBottomCorner + voxelPoint, Voxel.PositionLeftBottomCorner + voxelPoint + 1);

                                var  PointContainment = Cutout.Contains(voxelBox);
                                bool Contacts         = PointContainment.HasFlag(ContainmentType.Contains) || PointContainment.HasFlag(ContainmentType.Intersects);
                                if (Contacts || Vector3D.DistanceSquared(ReconstructedPosition, Voxel.PositionLeftBottomCorner + voxelPoint) <= CutoutRadiusSquared)
                                {
                                    bool pointBlocked = true;
                                    lock (BlockedVoxels)
                                    {
                                        pointBlocked = BlockedVoxels[Voxel.EntityId].Contains(voxelPoint);
                                        if (!pointBlocked)
                                        {
                                            BlockedVoxels[Voxel.EntityId].Add(voxelPoint);
                                        }
                                    }
                                    if (!pointBlocked)
                                    {
                                        byte  ContentFillLevel  = cutoutVoxels.Content(linearIndex);
                                        byte  MaterialId        = cutoutVoxels.Material(linearIndex);
                                        float MaterialFillRatio = ContentFillLevel / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT;

                                        if (!RawMaterials.ContainsKey(MaterialId))
                                        {
                                            RawMaterials.Add(MaterialId, MaterialFillRatio);
                                        }
                                        else
                                        {
                                            RawMaterials[MaterialId] += MaterialFillRatio;
                                        }

                                        processedPoints++;
                                    }
                                    else
                                    {
                                        skippedPoints++;
                                    }
                                }
                                else
                                {
                                    skippedPoints++;
                                }

                                int voxelIterationLimit = MyKernel.Session.Settings.SpeedMultiplierAcceleratesDrilling ? VoxelIterationLimit * MyKernel.TermControls.SpeedMultiplier : VoxelIterationLimit;
                                if (processedPoints > 0 && processedPoints % voxelIterationLimit == 0)
                                {
                                    //MyKernel.ResponderModule.UpdateStatusReport($"Cutting out {Math.Round(Cutout.Radius * 2, 1)}m sphere:\r\n{linearIndex} voxels processed", append: true);
                                    enumeratorWatch.Stop();
                                    yield return(true);
                                }
                            }
                            totalPoints = linearIndex;
                        }
                        MyKernel.ResponderModule.UpdateStatusReport($"Total processed points: {totalPoints} ({processedPoints}/{skippedPoints})", true);
                        enumeratorWatch.Stop();
                        MyKernel.ResponderModule.UpdateStatusReport($"EnumeratorWatch: {Math.Round(enumeratorWatch.Elapsed.TotalMilliseconds, 3)}ms", true);
                        //WriteToLog("ProcessVoxels", $"Found {processedPoints} valid voxel points out of {totalPoints}", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);

                        foreach (KeyValuePair <byte, float> kvp in RawMaterials)
                        {
                            MyVoxelMaterialDefinition material = MyDefinitionManager.Static.GetVoxelMaterialDefinition(kvp.Key);
                            if (material != null)
                            {
                                Materials.Add(material, kvp.Value * DrillingYield);
                            }
                            else
                            {
                                nullMaterials++;
                                continue;
                            }
                        }
                    }
                    MyKernel.ResponderModule.UpdateStatusReport($"Quitted enumerator", true);
                    //WriteToLog("ProcessVoxels", $"Found {VoxelPoints.Count} valid voxel points", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);
                    //WriteToLog("ProcessVoxels", $"Found {Materials.Count} valid materials{(nullMaterials > 0 ? $" and {nullMaterials} null materials" : "")}", EemRdx.SessionModules.LoggingLevelEnum.DebugLog, true, 2000);
                    //foreach (var kvp in Materials)
                    //{
                    //    WriteToLog("ProcessVoxels", $"Material: {kvp.Key.MaterialTypeName} (mined ore: {(kvp.Key.MinedOre != null ? kvp.Key.MinedOre : "null")}), amount: {kvp.Value}");
                    //}

                    MyKernel.ResponderModule.UpdateStatusReport($"Calculating materials", true);
                    Dictionary <MyObjectBuilder_Ore, float> MaterialsToAdd = new Dictionary <MyObjectBuilder_Ore, float>();
                    int nullMinedOres = 0;
                    foreach (KeyValuePair <MyVoxelMaterialDefinition, float> kvp in Materials)
                    {
                        MyVoxelMaterialDefinition material = kvp.Key;
                        if (string.IsNullOrWhiteSpace(material.MinedOre))
                        {
                            nullMinedOres++;
                            continue;
                        }
                        try
                        {
                            if (MyKernel.TermControls.DumpStone && material.MinedOre == "Stone")
                            {
                                continue;
                            }
                            MyObjectBuilder_Ore oreBuilder = MyObjectBuilderSerializer.CreateNewObject <MyObjectBuilder_Ore>(material.MinedOre);
                            oreBuilder.MaterialTypeName = new MyStringHash?(material.Id.SubtypeId);
                            MyPhysicalItemDefinition oreDef = MyDefinitionManager.Static.GetPhysicalItemDefinition(oreBuilder);
                            float MinedAmountInKg           = (kvp.Value / 1000 / oreDef.Volume) * oreDef.Mass * kvp.Key.MinedOreRatio * 32;
                            stopwatch.Stop();
                            //WriteToLog("ProcessVoxels", $"Found material {material.MaterialTypeName}, {Math.Round(kvp.Value)} points, mined amount would be {Math.Round(MinedAmountInKg)} kg");
                            stopwatch.Start();
                            MaterialsToAdd.Add(oreBuilder, MinedAmountInKg);
                        }
                        catch (Exception Scrap)
                        {
                            LogError("ProcessVoxels().dict_Materials.Iterate", $"Unknown error occurred on material {material.MinedOre}", Scrap);
                        }
                    }

                    Stopwatch cutoutWatch = Stopwatch.StartNew();
                    //Voxel.Storage.WriteRange(cutoutVoxels, MyStorageDataTypeFlags.ContentAndMaterial, refCorner - 1, refMaxCorner + 1);
                    Voxel.RootVoxel.PerformCutOutSphereFast(Cutout.Center, (float)Cutout.Radius, true);
                    cutoutWatch.Stop();
                    //WriteToLog("ProcessVoxels", $"Sphere was cut in {cutoutWatch.ElapsedTicks} ticks, which is {Math.Round(cutoutWatch.Elapsed.TotalMilliseconds, 4)} ms");

                    foreach (var kvp in MaterialsToAdd)
                    {
                        MyDefinitionId OreId       = kvp.Key.GetId();
                        MyItemType     oreItemType = new MyItemType(OreId.TypeId, OreId.SubtypeId);
                        float          amountToAdd = kvp.Value;
                        while (amountToAdd > 0.1f)
                        {
                            while (((float)ToolCargo.CurrentVolume / (float)ToolCargo.MaxVolume) > 0.9f)
                            {
                                yield return(true);
                            }

                            MyInventoryItem oreItem       = new MyInventoryItem(oreItemType, 0, (VRage.MyFixedPoint)amountToAdd);
                            float           FittingAmount = (float)(ToolCargo as Sandbox.Game.MyInventory).ComputeAmountThatFits(OreId);
                            if (FittingAmount > amountToAdd)
                            {
                                FittingAmount = amountToAdd;
                            }
                            ToolCargo.AddItems((VRage.MyFixedPoint)FittingAmount, kvp.Key);
                            amountToAdd -= FittingAmount;
                            //MyKernel.ResponderModule.UpdateStatusReport($"Adding {Math.Round(FittingAmount)}u of {OreId.SubtypeId}, {amountToAdd} remains", append: false);
                        }
                    }
                }
                else
                {
                    MyKernel.ResponderModule.UpdateStatusReport($"No voxel found", true);
                }
            }
            stopwatch.Stop();
            double ElapsedMs = stopwatch.Elapsed.TotalMilliseconds;

            //WriteToLog("ProcessVoxels", $"Voxels processed, elapsed time: {stopwatch.ElapsedTicks} ticks, which is {Math.Round(ElapsedMs, 3)} ms");
            MyKernel.ResponderModule.UpdateStatusReport($"Cycle finished", true);
            yield return(false);
        }
Esempio n. 21
0
        public unsafe void ReadMaterialRange(ref MyVoxelDataRequest req, bool detectOnly = false)
        {
            Vector3I vectori4;

            req.Flags = req.RequestFlags & MyVoxelRequestFlags.RequestFlags;
            Vector3I minInLod            = req.MinInLod;
            Vector3I maxInLod            = req.MaxInLod;
            float    lodSize             = 1 << (req.Lod & 0x1f);
            bool     flag                = req.RequestFlags.HasFlags(MyVoxelRequestFlags.SurfaceMaterial);
            bool     flag2               = req.RequestFlags.HasFlags(MyVoxelRequestFlags.ConsiderContent);
            bool     preciseOrePositions = req.RequestFlags.HasFlags(MyVoxelRequestFlags.PreciseOrePositions);

            this.m_planetShape.PrepareCache();
            if (this.m_biomes != null)
            {
                if (req.SizeLinear > 0x7d)
                {
                    BoundingBox request = new BoundingBox((Vector3)(minInLod * lodSize), (Vector3)(maxInLod * lodSize));
                    this.PrepareRulesForBoxInternal(ref request);
                }
                else if (!m_rangeClean || !ReferenceEquals(CachedProvider, this))
                {
                    this.CleanRules();
                }
            }
            Vector3  vector   = (minInLod + 0.5f) * lodSize;
            Vector3  pos      = vector;
            Vector3I vectori3 = (Vector3I)(-minInLod + req.Offset);

            if (detectOnly)
            {
                vectori4.Z = minInLod.Z;
                while (vectori4.Z <= maxInLod.Z)
                {
                    vectori4.Y = minInLod.Y;
                    while (true)
                    {
                        if (vectori4.Y > maxInLod.Y)
                        {
                            float *singlePtr3 = (float *)ref pos.Z;
                            singlePtr3[0] += lodSize;
                            pos.Y          = vector.Y;
                            int *numPtr3 = (int *)ref vectori4.Z;
                            numPtr3[0]++;
                            break;
                        }
                        vectori4.X = minInLod.X;
                        while (true)
                        {
                            byte num2;
                            if (vectori4.X > maxInLod.X)
                            {
                                float *singlePtr2 = (float *)ref pos.Y;
                                singlePtr2[0] += lodSize;
                                pos.X          = vector.X;
                                int *numPtr2 = (int *)ref vectori4.Y;
                                numPtr2[0]++;
                                break;
                            }
                            MyVoxelMaterialDefinition definition = this.GetMaterialForPosition(ref pos, lodSize, out num2, preciseOrePositions);
                            if ((definition != null) && (definition.Index != 0xff))
                            {
                                return;
                            }
                            float *singlePtr1 = (float *)ref pos.X;
                            singlePtr1[0] += lodSize;
                            int *numPtr1 = (int *)ref vectori4.X;
                            numPtr1[0]++;
                        }
                    }
                }
                MyVoxelRequestFlags *flagsPtr1 = (MyVoxelRequestFlags *)ref req.Flags;
                *((int *)flagsPtr1) |= 8;
            }
            else
            {
                bool          flag4  = true;
                MyStorageData target = req.Target;
                vectori4.Z = minInLod.Z;
                while (true)
                {
                    while (true)
                    {
                        if (vectori4.Z <= maxInLod.Z)
                        {
                            vectori4.Y = minInLod.Y;
                            break;
                        }
                        if (flag4)
                        {
                            MyVoxelRequestFlags *flagsPtr2 = (MyVoxelRequestFlags *)ref req.Flags;
                            *((int *)flagsPtr2) |= 8;
                        }
                        return;
                    }
                    while (true)
                    {
                        if (vectori4.Y > maxInLod.Y)
                        {
                            float *singlePtr6 = (float *)ref pos.Z;
                            singlePtr6[0] += lodSize;
                            pos.Y          = vector.Y;
                            int *numPtr6 = (int *)ref vectori4.Z;
                            numPtr6[0]++;
                            break;
                        }
                        vectori4.X = minInLod.X;
                        Vector3I p         = (Vector3I)(vectori4 + vectori3);
                        int      linearIdx = target.ComputeLinear(ref p);
                        while (true)
                        {
                            if (vectori4.X <= maxInLod.X)
                            {
                                byte num4;
                                if ((!flag || (target.Material(linearIdx) == 0)) && (!flag2 || (target.Content(linearIdx) != 0)))
                                {
                                    byte num5;
                                    MyVoxelMaterialDefinition definition2 = this.GetMaterialForPosition(ref pos, lodSize, out num5, preciseOrePositions);
                                    num4 = (definition2 != null) ? definition2.Index : ((byte)0xff);
                                }
                                else
                                {
                                    num4 = 0xff;
                                }
                                target.Material(linearIdx, num4);
                                flag4     &= num4 == 0xff;
                                linearIdx += target.StepLinear;
                                float *singlePtr4 = (float *)ref pos.X;
                                singlePtr4[0] += lodSize;
                                int *numPtr4 = (int *)ref vectori4.X;
                                numPtr4[0]++;
                                continue;
                            }
                            else
                            {
                                float *singlePtr5 = (float *)ref pos.Y;
                                singlePtr5[0] += lodSize;
                                pos.X          = vector.X;
                                int *numPtr5 = (int *)ref vectori4.Y;
                                numPtr5[0]++;
                            }
                            break;
                        }
                    }
                }
            }
        }
        internal void ReadMaterialRange(MyStorageData target, ref Vector3I writeOffset, int lodIndex, ref Vector3I minInLod, ref Vector3I maxInLod)
        {
            float lodVoxelSizeHalf;
            BoundingBox queryBox;
            BoundingSphere querySphere;
            SetupReading(lodIndex, ref minInLod, ref maxInLod, out lodVoxelSizeHalf, out queryBox, out querySphere);
            float lodVoxelSize = 2f * lodVoxelSizeHalf;

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

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


            ProfilerShort.Begin("Material computation");

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

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

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

            }
            ProfilerShort.End();
        }
Esempio n. 23
0
        public static void MakeCrater(MyVoxelBase voxelMap, BoundingSphereD sphere, Vector3 direction, MyVoxelMaterialDefinition material)
        {
            ProfilerShort.Begin("MakeCrater");

            Vector3 normal = Vector3.Normalize(sphere.Center - voxelMap.RootVoxel.WorldMatrix.Translation);

            Vector3I minCorner, maxCorner;

            {
                Vector3D sphereMin = sphere.Center - (sphere.Radius - MyVoxelConstants.VOXEL_SIZE_IN_METRES) * 1.3f;
                Vector3D sphereMax = sphere.Center + (sphere.Radius + MyVoxelConstants.VOXEL_SIZE_IN_METRES) * 1.3f;
                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);

            Vector3I worldMinCorner = minCorner + voxelMap.StorageMin;
            Vector3I worldMaxCorner = maxCorner + voxelMap.StorageMin;

            //  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 worldMinCorner, ref worldMaxCorner);

            ProfilerShort.End();

            ProfilerShort.Begin("Changing cache");
            int      removedVoxelContent = 0;
            Vector3I tempVoxelCoord;
            Vector3I cachePos = (maxCorner - minCorner) / 2;

            byte oldMaterial = m_cache.Material(ref cachePos);

            float digRatio = 1 - Vector3.Dot(normal, direction);

            Vector3 newCenter = sphere.Center - normal * (float)sphere.Radius * 1.1f;//0.9f;
            float   sphRadA   = (float)(sphere.Radius * 1.5f);
            float   sphRadSqA = (float)(sphRadA * sphRadA);
            float   voxelSizeHalfTransformedPosA = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadA + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);
            float   voxelSizeHalfTransformedNegA = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (-2 * sphRadA + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            Vector3 newDelCenter = newCenter + normal * (float)sphere.Radius * (0.7f + digRatio) + direction * (float)sphere.Radius * 0.65f;
            float   sphRadD      = (float)(sphere.Radius);
            float   sphRadSqD    = (float)(sphRadD * sphRadD);
            float   voxelSizeHalfTransformedPosD = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadD + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);
            float   voxelSizeHalfTransformedNegD = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (-2 * sphRadD + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            Vector3 newSetCenter = newCenter + normal * (float)sphere.Radius * (digRatio) + direction * (float)sphere.Radius * 0.3f;
            float   sphRadS      = (float)(sphere.Radius * 0.1f);
            float   sphRadSqS    = (float)(sphRadS * sphRadS);
            float   voxelSizeHalfTransformedPosS = MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * (2 * sphRadS + MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF);

            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);

                        byte originalContent = m_cache.Content(ref cachePos);

                        //Add sphere
                        if (originalContent != MyVoxelConstants.VOXEL_CONTENT_FULL)
                        {
                            float addDist = (float)(voxelPosition - newCenter).LengthSquared();
                            float addDiff = (float)(addDist - sphRadSqA);

                            byte newContent;
                            if (addDiff > voxelSizeHalfTransformedPosA)
                            {
                                newContent = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                            }
                            else if (addDiff < voxelSizeHalfTransformedNegA)
                            {
                                newContent = MyVoxelConstants.VOXEL_CONTENT_FULL;
                            }
                            else
                            {
                                float value = (float)Math.Sqrt(addDist + sphRadSqA - 2 * sphRadA * Math.Sqrt(addDist));
                                if (addDiff < 0)
                                {
                                    value = -value;
                                }
                                //  This formula will work even if diff is positive or negative
                                newContent = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - value / MyVoxelConstants.VOXEL_SIZE_IN_METRES_HALF * MyVoxelConstants.VOXEL_ISO_LEVEL);
                            }

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

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

                        //Delete sphere
                        float delDist = (float)(voxelPosition - newDelCenter).LengthSquared();
                        float delDiff = (float)(delDist - sphRadSqD);

                        byte contentToRemove;
                        if (delDiff > voxelSizeHalfTransformedPosD)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_EMPTY;
                        }
                        else if (delDiff < voxelSizeHalfTransformedNegD)
                        {
                            contentToRemove = MyVoxelConstants.VOXEL_CONTENT_FULL;
                        }
                        else
                        {
                            float value = (float)Math.Sqrt(delDist + sphRadSqD - 2 * sphRadD * Math.Sqrt(delDist));
                            if (delDiff < 0)
                            {
                                value = -value;
                            }
                            //  This formula will work even if diff is positive or negative
                            contentToRemove = (byte)(MyVoxelConstants.VOXEL_ISO_LEVEL - value / 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;
                        }

                        //Set material

                        float setDist = (float)(voxelPosition - newSetCenter).LengthSquared();
                        float setDiff = (float)(setDist - sphRadSqS);

                        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
                        {
                            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 >= voxelSizeHalfTransformedPosS && 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 - newCenter).LengthSquared();
                        float diff = (float)(dist - sphRadSqA);

                        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");
                minCorner += voxelMap.StorageMin;
                maxCorner += voxelMap.StorageMin;
                voxelMap.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, ref minCorner, ref maxCorner);
                MyShapeSphere sphereShape = new MyShapeSphere();
                sphereShape.Center = sphere.Center;
                sphereShape.Radius = (float)(sphere.Radius * 1.5);
                OnVoxelChanged(MyVoxelBase.OperationType.Cut, voxelMap, sphereShape);
                ProfilerShort.End();
            }

            ProfilerShort.End();
        }
        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;
        }
        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;
        }
        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;
        }
Esempio n. 27
0
        public unsafe MyStorageBase Compatibility_LoadCellStorage(int fileVersion, Stream stream)
        {
            Vector3I vectori;
            Vector3I vectori2;
            Vector3I vectori6;

            vectori.X = stream.ReadInt32();
            vectori.Y = stream.ReadInt32();
            vectori.Z = stream.ReadInt32();
            MyOctreeStorage storage = new MyOctreeStorage(null, vectori);

            vectori2.X = stream.ReadInt32();
            vectori2.Y = stream.ReadInt32();
            vectori2.Z = stream.ReadInt32();
            Vector3I vectori3 = (Vector3I)(vectori / vectori2);
            Dictionary <byte, MyVoxelMaterialDefinition> mapping = null;

            if (fileVersion == 2)
            {
                mapping = this.Compatibility_LoadMaterialIndexMapping(stream);
            }
            else
            {
                int num2 = fileVersion;
            }
            Vector3I      zero   = Vector3I.Zero;
            Vector3I      end    = new Vector3I(7);
            MyStorageData source = new MyStorageData(MyStorageDataTypeFlags.All);

            source.Resize(Vector3I.Zero, end);
            vectori6.X = 0;
            while (vectori6.X < vectori3.X)
            {
                vectori6.Y = 0;
                while (true)
                {
                    if (vectori6.Y >= vectori3.Y)
                    {
                        int *numPtr6 = (int *)ref vectori6.X;
                        numPtr6[0]++;
                        break;
                    }
                    vectori6.Z = 0;
                    while (true)
                    {
                        if (vectori6.Z >= vectori3.Z)
                        {
                            int *numPtr5 = (int *)ref vectori6.Y;
                            numPtr5[0]++;
                            break;
                        }
                        MyVoxelContentConstitution constitution = (MyVoxelContentConstitution)stream.ReadByteNoAlloc();
                        switch (constitution)
                        {
                        case MyVoxelContentConstitution.Empty:
                            source.ClearContent(0);
                            break;

                        case MyVoxelContentConstitution.Full:
                            source.ClearContent(0xff);
                            break;

                        case MyVoxelContentConstitution.Mixed:
                            Vector3I vectori7;
                            vectori7.X = 0;
                            while (vectori7.X < 8)
                            {
                                vectori7.Y = 0;
                                while (true)
                                {
                                    if (vectori7.Y >= 8)
                                    {
                                        int *numPtr3 = (int *)ref vectori7.X;
                                        numPtr3[0]++;
                                        break;
                                    }
                                    vectori7.Z = 0;
                                    while (true)
                                    {
                                        if (vectori7.Z >= 8)
                                        {
                                            int *numPtr2 = (int *)ref vectori7.Y;
                                            numPtr2[0]++;
                                            break;
                                        }
                                        source.Content(ref vectori7, stream.ReadByteNoAlloc());
                                        int *numPtr1 = (int *)ref vectori7.Z;
                                        numPtr1[0]++;
                                    }
                                }
                            }
                            break;

                        default:
                            break;
                        }
                        zero = vectori6 * 8;
                        storage.WriteRange(source, MyStorageDataTypeFlags.Content, zero, (Vector3I)(zero + 7), true, false);
                        int *numPtr4 = (int *)ref vectori6.Z;
                        numPtr4[0]++;
                    }
                }
            }
            try
            {
                vectori6.X = 0;
                while (vectori6.X < vectori3.X)
                {
                    vectori6.Y = 0;
                    while (true)
                    {
                        if (vectori6.Y >= vectori3.Y)
                        {
                            int *numPtr12 = (int *)ref vectori6.X;
                            numPtr12[0]++;
                            break;
                        }
                        vectori6.Z = 0;
                        while (true)
                        {
                            if (vectori6.Z >= vectori3.Z)
                            {
                                int *numPtr11 = (int *)ref vectori6.Y;
                                numPtr11[0]++;
                                break;
                            }
                            MyVoxelMaterialDefinition definition = null;
                            if (stream.ReadByteNoAlloc() == 1)
                            {
                                source.ClearMaterials(this.Compatibility_LoadCellVoxelMaterial(stream, mapping).Index);
                            }
                            else
                            {
                                Vector3I vectori8;
                                vectori8.X = 0;
                                while (vectori8.X < 8)
                                {
                                    vectori8.Y = 0;
                                    while (true)
                                    {
                                        if (vectori8.Y >= 8)
                                        {
                                            int *numPtr9 = (int *)ref vectori8.X;
                                            numPtr9[0]++;
                                            break;
                                        }
                                        vectori8.Z = 0;
                                        while (true)
                                        {
                                            if (vectori8.Z >= 8)
                                            {
                                                int *numPtr8 = (int *)ref vectori8.Y;
                                                numPtr8[0]++;
                                                break;
                                            }
                                            definition = this.Compatibility_LoadCellVoxelMaterial(stream, mapping);
                                            stream.ReadByteNoAlloc();
                                            source.Material(ref vectori8, definition.Index);
                                            int *numPtr7 = (int *)ref vectori8.Z;
                                            numPtr7[0]++;
                                        }
                                    }
                                }
                            }
                            zero = vectori6 * 8;
                            storage.WriteRange(source, MyStorageDataTypeFlags.Material, zero, (Vector3I)(zero + 7), true, false);
                            int *numPtr10 = (int *)ref vectori6.Z;
                            numPtr10[0]++;
                        }
                    }
                }
            }
            catch (EndOfStreamException exception)
            {
                MySandboxGame.Log.WriteLine(exception);
            }
            return(storage);
        }
        //  Linearly interpolates position, normal and material on poly-cube edge. Interpolated point is where an isosurface cuts an edge between two vertices, each with their own scalar value.
        void GetVertexInterpolation(MyStorageData cache, MyTemporaryVoxel inputVoxelA, MyTemporaryVoxel inputVoxelB, int edgeIndex)
        {
            MyEdge edge = m_edges[edgeIndex];

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

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

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

            float mu = (float)(MyVoxelConstants.VOXEL_ISO_LEVEL - contentA) / (float)(contentB - contentA);

            Debug.Assert(mu > 0.0f && mu < 1.0f);

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

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


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

            float mu2 = ((float)contentB) / (((float)contentA) + ((float)contentB));

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

            return;
        }
        //  Linearly interpolates position, normal and material on poly-cube edge. Interpolated point is where an isosurface cuts an edge between two vertices, each with their own scalar value.
        void GetVertexInterpolation(MyStorageData cache, MyTemporaryVoxel inputVoxelA, MyTemporaryVoxel inputVoxelB, int edgeIndex)
        {
            MyEdge edge = m_edges[edgeIndex];

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

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

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

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

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

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


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

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

            return;
        }
Esempio n. 30
0
        private unsafe void ProcessCell(MyStorageData cache, IMyStorage storage, Vector3I cell, long detectorId)
        {
            Vector3I lodVoxelRangeMin = cell << 3;
            Vector3I lodVoxelRangeMax = (Vector3I)(lodVoxelRangeMin + 7);

            storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 2, lodVoxelRangeMin, lodVoxelRangeMax);
            if (cache.ContainsVoxelsAboveIsoLevel())
            {
                Vector3I            vectori3;
                MyVoxelRequestFlags preciseOrePositions = MyVoxelRequestFlags.PreciseOrePositions;
                storage.ReadRange(cache, MyStorageDataTypeFlags.Material, 2, lodVoxelRangeMin, lodVoxelRangeMax, ref preciseOrePositions);
                MaterialPositionData[] materialData = MaterialData;
                vectori3.Z = 0;
                while (vectori3.Z < 8)
                {
                    vectori3.Y = 0;
                    while (true)
                    {
                        if (vectori3.Y >= 8)
                        {
                            int *numPtr4 = (int *)ref vectori3.Z;
                            numPtr4[0]++;
                            break;
                        }
                        vectori3.X = 0;
                        while (true)
                        {
                            if (vectori3.X >= 8)
                            {
                                int *numPtr3 = (int *)ref vectori3.Y;
                                numPtr3[0]++;
                                break;
                            }
                            int linearIdx = cache.ComputeLinear(ref vectori3);
                            if (cache.Content(linearIdx) > 0x7f)
                            {
                                byte     index      = cache.Material(linearIdx);
                                Vector3D vectord    = ((vectori3 + lodVoxelRangeMin) * 4f) + 2f;
                                Vector3 *vectorPtr1 = (Vector3 *)ref materialData[index].Sum;
                                vectorPtr1[0] += vectord;
                                int *numPtr1 = (int *)ref materialData[index].Count;
                                numPtr1[0]++;
                            }
                            int *numPtr2 = (int *)ref vectori3.X;
                            numPtr2[0]++;
                        }
                    }
                }
                MyEntityOreDeposit item = null;
                for (int i = 0; i < materialData.Length; i++)
                {
                    if (materialData[i].Count != 0)
                    {
                        MyVoxelMaterialDefinition voxelMaterialDefinition = MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)i);
                        if ((voxelMaterialDefinition != null) && voxelMaterialDefinition.IsRare)
                        {
                            if (item == null)
                            {
                                item = new MyEntityOreDeposit(this.VoxelMap, cell, detectorId);
                            }
                            MyEntityOreDeposit.Data data = new MyEntityOreDeposit.Data {
                                Material             = voxelMaterialDefinition,
                                AverageLocalPosition = (Vector3)Vector3D.Transform((materialData[i].Sum / ((float)materialData[i].Count)) - this.VoxelMap.SizeInMetresHalf, Quaternion.CreateFromRotationMatrix(this.VoxelMap.WorldMatrix))
                            };
                            item.Materials.Add(data);
                        }
                    }
                }
                if (item != null)
                {
                    this.m_result.Add(item);
                }
                else
                {
                    this.m_emptyCells.Add(cell);
                }
                Array.Clear(materialData, 0, materialData.Length);
            }
        }
        private void ProcessCell(MyStorageData cache, IMyStorage storage, Vector3I cell, long detectorId)
        {
            //bool m_miningDebug = false;

            if (cache == null || storage == null)
            {
                return;
            }

            Vector3I vector3I         = cell << 3;
            Vector3I lodVoxelRangeMax = vector3I + 7;

            // Advice cache because of performance issues
            var flag = MyVoxelRequestFlags.ContentCheckedDeep;

            Stopwatch stopwatch = Stopwatch.StartNew();

            storage.ReadRange(cache, MyStorageDataTypeFlags.Content, 0, vector3I, lodVoxelRangeMax, ref flag);
            stopwatch.Stop();

            int readingTime = (int)((stopwatch.ElapsedTicks * 1000000) / Stopwatch.Frequency);

            if (readingTime > 1000)
            {
                int changeAmount = (int)(readingTime / 1000);

                if (MyAPIGateway.Physics.ServerSimulationRatio < 1.00f)
                {
                    sleepTimer += changeAmount * 100;
                }
                else
                {
                    sleepTimer = Math.Max(sleepTimer - 1, 1);
                }

                MyAPIGateway.Parallel.Sleep(sleepTimer);
            }

            //if (m_miningDebug)
            //Logging.Instance.WriteLine($"ProcessCell.ReadRange(1) took {(stopwatch.ElapsedTicks * 1000000)/Stopwatch.Frequency} microseconds");

            if (cache.ContainsVoxelsAboveIsoLevel())
            {
                //Stopwatch stopwatch2 = Stopwatch.StartNew();
                storage.ReadRange(cache, MyStorageDataTypeFlags.Material, 0, vector3I, lodVoxelRangeMax, ref flag);
                //stopwatch2.Stop();

                //if (m_miningDebug)
                //Logging.Instance.WriteLine($"ProcessCell.ReadRange(2) took {(stopwatch2.ElapsedTicks * 1000000)/Stopwatch.Frequency} microseconds");

                Vector3I p = default(Vector3I);
                p.Z = 0;
                while (p.Z < 8)
                {
                    p.Y = 0;
                    while (p.Y < 8)
                    {
                        p.X = 0;
                        while (p.X < 8)
                        {
                            int linearIdx = cache.ComputeLinear(ref p);

                            if (cache.Content(linearIdx) > 127)
                            {
                                byte b = cache.Material(linearIdx);

                                if (HasFilterUpgrade)
                                {
                                    var voxelDefinition = MyDefinitionManager.Static.GetVoxelMaterialDefinition(b);

                                    if (voxelDefinition != null && voxelDefinition.MinedOre != null)
                                    {
                                        foreach (string mat in OreListSelected)
                                        {
                                            if (voxelDefinition.MinedOre.ToLower() == mat.ToLower())
                                            {
                                                Materials.AddMaterial(b, vector3I + p);
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Materials.AddMaterial(b, vector3I + p);
                                    }
                                }
                                else
                                {
                                    Materials.AddMaterial(b, vector3I + p);
                                }
                            }
                            p.X++;
                        }
                        p.Y++;
                    }
                    p.Z++;
                }
            }
        }
Esempio n. 32
0
        private void ReadVoxel(IMyVoxelBase voxel, Vector3D position, Dictionary <Vector3D, NaniteMiningItem> targets, HashSet <string> allowedOreList = null)
        {
            var m_cache = new MyStorageData();
            NaniteShapeSphere shapeSphere = new NaniteShapeSphere();

            shapeSphere.Center = position;
            shapeSphere.Radius = NaniteConstructionManager.Settings.MiningRadius / 2;

            //NaniteShapeCapsule shapeCapsule = new NaniteShapeCapsule();
            //shapeCapsule.A = positionA;
            //shapeCapsule.B = positionB;
            //shapeCapsule.Radius = NaniteConstructionManager.Settings.MiningRadius;

            Vector3I minCorner, maxCorner, numCells;

            GetVoxelShapeDimensions(voxel, shapeSphere, out minCorner, out maxCorner, out numCells);

            var cacheMin = minCorner - 1;
            var cacheMax = maxCorner + 1;

            //bool bRareOnly = true;
            //if (allowedOreList != null && allowedOreList.Contains("Stone"))
            //    bRareOnly = false;

            m_cache.Resize(cacheMin, cacheMax);
            m_cache.ClearContent(0);
            m_cache.ClearMaterials(0);
            var flags = MyVoxelRequestFlags.AdviseCache;

            voxel.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, cacheMin, cacheMax, ref flags);

            //voxel.Storage.PinAndExecute(() =>
            {
                Vector3I pos;
                for (pos.X = minCorner.X; pos.X <= maxCorner.X; ++pos.X)
                {
                    for (pos.Y = minCorner.Y; pos.Y <= maxCorner.Y; ++pos.Y)
                    {
                        for (pos.Z = minCorner.Z; pos.Z <= maxCorner.Z; ++pos.Z)
                        {
                            // get original amount
                            var relPos = pos - cacheMin;
                            var lin    = m_cache.ComputeLinear(ref relPos);

                            //var relPos = pos - cacheMin; // Position of voxel in local space
                            var original = m_cache.Content(lin); // Content at this position

                            if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY)
                            {
                                continue;
                            }

                            var      material = m_cache.Material(lin); // Material at this position
                            Vector3D vpos;
                            MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxel.PositionLeftBottomCorner, ref pos, out vpos);
                            if (targets.ContainsKey(vpos))
                            {
                                continue;
                            }

                            /*
                             * var volume = shapeSphere.GetVolume(ref vpos);
                             * if (volume == 0f) // Shape and voxel do not intersect at this position, so continue
                             *  continue;
                             */

                            // Pull information about voxel required for later processing
                            var voxelMat = MyDefinitionManager.Static.GetVoxelMaterialDefinition(material);
                            //if ((bRareOnly && voxelMat.IsRare) || !bRareOnly)
                            //if(voxelMat.IsRare)
                            if (allowedOreList != null)// || (allowedOreList == null && bRareOnly && voxelMat.IsRare))
                            {
                                if (allowedOreList != null && !allowedOreList.Contains(voxelMat.MinedOre))
                                {
                                    continue;
                                }


                                NaniteMiningItem miningItem = new NaniteMiningItem();
                                miningItem.Position      = vpos;
                                miningItem.VoxelMaterial = material;
                                miningItem.VoxelId       = voxel.EntityId;
                                miningItem.Amount        = original; // * 3.9f;
                                miningItem.MiningHammer  = this;
                                targets.Add(vpos, miningItem);
                                //count++;
                            }

                            //m_cache.Content(lin, 0);
                            //m_cache.Material(lin, 0);
                        }
                    }
                }


                //voxel.Storage.WriteRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, cacheMin, cacheMax);
            };

            /*
             * int count = 0;
             * for (var itCells = new Vector3I_RangeIterator(ref Vector3I.Zero, ref numCells); itCells.IsValid(); itCells.MoveNext())
             * {
             *  Vector3I cellMinCorner, cellMaxCorner;
             *  GetCellCorners(ref minCorner, ref maxCorner, ref itCells, out cellMinCorner, out cellMaxCorner);
             *
             *  var cacheMin = cellMinCorner - 1;
             *  var cacheMax = cellMaxCorner + 1;
             *  voxel.Storage.ClampVoxel(ref cacheMin);
             *  voxel.Storage.ClampVoxel(ref cacheMax);
             *
             *  m_cache.Resize(cacheMin, cacheMax);
             *  voxel.Storage.ReadRange(m_cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, cacheMin, cacheMax);
             *
             *  for (var it = new Vector3I_RangeIterator(ref cellMinCorner, ref cellMaxCorner); it.IsValid(); it.MoveNext())
             *  {
             *      var relPos = it.Current - cacheMin; // Position of voxel in local space
             *      var original = m_cache.Content(ref relPos); // Content at this position
             *      var material = m_cache.Material(ref relPos); // Material at this position
             *
             *      if (original == MyVoxelConstants.VOXEL_CONTENT_EMPTY)
             *          continue;
             *
             *      Vector3D vpos;
             *      MyVoxelCoordSystems.VoxelCoordToWorldPosition(voxel.PositionLeftBottomCorner, ref it.Current, out vpos);
             *      if (targets.ContainsKey(vpos))
             *          continue;
             *
             *      var volume = shapeSphere.GetVolume(ref vpos);
             *      if (volume == 0f) // Shape and voxel do not intersect at this position, so continue
             *          continue;
             *
             *      // Pull information about voxel required for later processing
             *      var voxelMat = MyDefinitionManager.Static.GetVoxelMaterialDefinition(m_cache.Material(ref relPos));
             *      //if ((bRareOnly && voxelMat.IsRare) || !bRareOnly)
             *      //if(voxelMat.IsRare)
             *      if (allowedOreList != null)// || (allowedOreList == null && bRareOnly && voxelMat.IsRare))
             *      {
             *          if (allowedOreList != null && !allowedOreList.Contains(voxelMat.MinedOre))
             *              continue;
             *
             *          NaniteMiningItem miningItem = new NaniteMiningItem();
             *          miningItem.Position = vpos;
             *          miningItem.VoxelMaterial = material;
             *          miningItem.VoxelId = voxel.EntityId;
             *          miningItem.Amount = original; // * 3.9f;
             *          miningItem.MiningHammer = this;
             *          targets.Add(vpos, miningItem);
             *          count++;
             *      }
             *  }
             * }
             */

            //Logging.Instance.WriteLine(string.Format("Voxels Read: {0} - {1}", voxel.GetType().Name, count));
        }
Esempio n. 33
0
        private void MergeAsteroidVolumeInto(ref MyVoxelMap newAsteroid, Vector3D min, StructureVoxelModel modelPrimary, StructureVoxelModel modelSecondary, Vector3D minPrimary, Vector3D minSecondary)
        {
            var      filenameSecondary = modelSecondary.SourceVoxelFilepath ?? modelSecondary.VoxelFilepath;
            var      filenamePrimary   = modelPrimary.SourceVoxelFilepath ?? modelPrimary.VoxelFilepath;
            Vector3I block;
            Vector3I newBlock;
            Vector3I cacheSize;

            var asteroid = new MyVoxelMap();

            asteroid.Load(filenameSecondary);
            BoundingBoxI content = modelSecondary.InflatedContentBounds;

            for (block.Z = content.Min.Z; block.Z <= content.Max.Z; block.Z += 64)
            {
                for (block.Y = content.Min.Y; block.Y <= content.Max.Y; block.Y += 64)
                {
                    for (block.X = content.Min.X; block.X <= content.Max.X; block.X += 64)
                    {
                        var cache = new MyStorageData();
                        cacheSize = new Vector3I(MathHelper.Min(content.Max.X, block.X + 63) - block.X + 1,
                                                 MathHelper.Min(content.Max.Y, block.Y + 63) - block.Y + 1,
                                                 MathHelper.Min(content.Max.Z, block.Z + 63) - block.Z + 1);

                        cache.Resize(cacheSize);
                        asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1);

                        newBlock = ((minSecondary - min) + (Vector3D)(block - content.Min)).RoundToVector3I();
                        newAsteroid.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1);
                    }
                }
            }

            asteroid.Load(filenamePrimary);
            content = modelPrimary.InflatedContentBounds;
            for (block.Z = content.Min.Z; block.Z <= content.Max.Z; block.Z += 64)
            {
                for (block.Y = content.Min.Y; block.Y <= content.Max.Y; block.Y += 64)
                {
                    for (block.X = content.Min.X; block.X <= content.Max.X; block.X += 64)
                    {
                        var cache = new MyStorageData();
                        cacheSize = new Vector3I(MathHelper.Min(content.Max.X, block.X + 63) - block.X + 1,
                                                 MathHelper.Min(content.Max.Y, block.Y + 63) - block.Y + 1,
                                                 MathHelper.Min(content.Max.Z, block.Z + 63) - block.Z + 1);

                        cache.Resize(cacheSize);
                        asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1);

                        newBlock = ((minPrimary - min) + (Vector3D)(block - content.Min)).RoundToVector3I();
                        var newCache = new MyStorageData();
                        newCache.Resize(cacheSize);
                        newAsteroid.Storage.ReadRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, newBlock, newBlock + 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)
                                {
                                    byte volume   = cache.Content(ref p);
                                    byte material = cache.Material(ref p);
                                    if (volume > 0)
                                    {
                                        byte existingVolume = newCache.Content(ref p);
                                        if (volume > existingVolume)
                                        {
                                            newCache.Content(ref p, volume);
                                        }
                                        // Overwrites secondary material with primary.
                                        newCache.Material(ref p, material);
                                    }
                                    else
                                    {
                                        // try to find cover material.
                                        Vector3I[] points = CreateTestPoints(p, cacheSize - 1);
                                        for (int i = 0; i < points.Length; i++)
                                        {
                                            byte testVolume = cache.Content(ref points[i]);
                                            if (testVolume > 0)
                                            {
                                                material = cache.Material(ref points[i]);
                                                newCache.Material(ref p, material);
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        newAsteroid.Storage.WriteRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1);
                    }
                }
            }
        }
Esempio n. 34
0
        public static void RemoveVoxelContent(long voxelId, Vector3D position, out byte materialRemoved, out float amountOfMaterial)
        {
            materialRemoved  = 0;
            amountOfMaterial = 0f;

            IMyEntity entity;

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

            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 + 1;

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

            MyStorageData cache = new MyStorageData();

            cache.Resize(minVoxel, maxVoxel);
            var flag = MyVoxelRequestFlags.AdviseCache;

            cache.ClearContent(0);
            cache.ClearMaterials(0);

            byte original = 0;
            byte material = 0;

            // I don't really think pinning is necessary since I'm in the main thread, but this hasn't been working for awhile, so I'll keep it here.
            voxel.Storage.PinAndExecute(() =>
            {
                voxel.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, minVoxel, maxVoxel, ref flag);

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

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

                // Remove Content
                Logging.Instance.WriteLine($"Material: SizeLinear: {cache.SizeLinear}, Size3D: {cache.Size3D}, AboveISO: {cache.ContainsVoxelsAboveIsoLevel()}");
                cache.Content(0, 0);
                voxel.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, minVoxel, maxVoxel);
            });

            // Calculate Material Mined
            var voxelMat = MyDefinitionManager.Static.GetVoxelMaterialDefinition(material);

            materialRemoved  = material;
            amountOfMaterial = CalculateAmount(voxelMat, original * 3.9f);

            // This will sync the clients.  Apparently voxel writes do not sync, lovely.
            if (Sync.IsServer)
            {
                VoxelRemovalData data = new VoxelRemovalData();
                data.VoxelID  = voxelId;
                data.Position = position;
                MyAPIGateway.Multiplayer.SendMessageToOthers(8969, ASCIIEncoding.ASCII.GetBytes(MyAPIGateway.Utilities.SerializeToXML(data)));
            }
        }
Esempio n. 35
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);
        }
Esempio n. 36
0
            private void ExecuteQuery()
            {
                try
                {
                    var      shape = _component._cachedRegion;
                    var      worldMin = shape.Center - shape.Radius;
                    var      worldMax = shape.Center + shape.Radius;
                    Vector3I voxMin, voxMax;
                    MyVoxelCoordSystems.WorldPositionToVoxelCoord(_vox.PositionLeftBottomCorner, ref worldMin, out voxMin);
                    MyVoxelCoordSystems.WorldPositionToVoxelCoord(_vox.PositionLeftBottomCorner, ref worldMax, out voxMax);

                    {
                        var tmp = Vector3I.Max(voxMin, voxMax);
                        voxMin = Vector3I.Min(voxMin, voxMax);
                        voxMax = tmp;
                    }

                    {
                        voxMin = voxMin >> _component.Definition.LevelOfDetail;
                        voxMax = (voxMax >> _component.Definition.LevelOfDetail) + 1;
                    }

                    _storage.Resize(voxMin, voxMax);
                    // ReSharper disable once RedundantCast
                    ((IMyStorage)_vox.Storage).ReadRange(_storage, MyStorageDataTypeFlags.ContentAndMaterial, _component.Definition.LevelOfDetail, in voxMin,
                                                         in voxMax);

                    for (var i = 0; i < _countsWorking.Length; i++)
                    {
                        _countsWorking[i] = 0;
                    }
                    for (var itr = new Vector3I_RangeIterator(ref voxMin, ref voxMax); itr.IsValid(); itr.MoveNext())
                    {
                        var      local     = itr.Current;
                        var      localRoot = local << _component.Definition.LevelOfDetail;
                        Vector3D box;
                        MyVoxelCoordSystems.VoxelCoordToWorldPosition(_vox.PositionLeftBottomCorner, ref localRoot, out box);
                        if (!shape.Intersects(new BoundingBoxD(box, box + (1 << _component.Definition.LevelOfDetail))))
                        {
                            continue;
                        }
                        var stor    = local - voxMin;
                        var idx     = _storage.ComputeLinear(ref stor);
                        var content = _storage.Content(idx);
                        if (content == 0)
                        {
                            continue;
                        }
                        if (_component.Definition.Mode == VoxelPowerCountMode.Surface)
                        {
                            if (content == byte.MaxValue)
                            {
                                continue;
                            }
                            content = 1;
                        }

                        _countsWorking[_storage.Material(idx)] += content;
                    }

                    {
                        var tmp = _countsWorking;
                        _countsWorking = Counts;
                        Counts         = tmp;
                    }
                }
                finally
                {
                    _currentlyExecuting = false;
                    _component.QueryFinishedAsync();
                }
            }
Esempio n. 37
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));
                                }
                            }
                        }
                    }
                }
            }
        }
        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");
        }
Esempio n. 39
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();
        }
Esempio n. 40
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)
        {
            Util.GetInstance().Log("Finding Mineral", "findingOres.txt");
            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;
                                Util.GetInstance().Log(hits + " Ore " + name + " scanore " + position, "findingOres.txt");
                                //var gps = MyAPIGateway.Session.GPS.Create("Ore " + name, "scanore", position, true, false);
                                //MyAPIGateway.Session.GPS.AddLocalGps(gps);
                                hits++;
                            }
                        }
                    }
                }
            }
            return(hits);
        }