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

            var asteroid = new MyVoxelMap();

            asteroid.Load(filenameSecondary, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            for (coords.Z = (int)modelSecondary.ContentBounds.Min.Z; coords.Z <= modelSecondary.ContentBounds.Max.Z; coords.Z++)
            {
                for (coords.Y = (int)modelSecondary.ContentBounds.Min.Y; coords.Y <= modelSecondary.ContentBounds.Max.Y; coords.Y++)
                {
                    for (coords.X = (int)modelSecondary.ContentBounds.Min.X; coords.X <= modelSecondary.ContentBounds.Max.X; coords.X++)
                    {
                        byte   volume;
                        string cellMaterial;
                        asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                        var newCoord = ((minSecondary - min) + ((Vector3D)coords - modelSecondary.ContentBounds.Min)).RoundToVector3I();
                        newAsteroid.SetVoxelContent(volume, ref newCoord);
                        newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord);
                    }
                }
            }

            asteroid.Load(filenamePrimary, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            for (coords.Z = (int)modelPrimary.ContentBounds.Min.Z; coords.Z <= modelPrimary.ContentBounds.Max.Z; coords.Z++)
            {
                for (coords.Y = (int)modelPrimary.ContentBounds.Min.Y; coords.Y <= modelPrimary.ContentBounds.Max.Y; coords.Y++)
                {
                    for (coords.X = (int)modelPrimary.ContentBounds.Min.X; coords.X <= modelPrimary.ContentBounds.Max.X; coords.X++)
                    {
                        byte   volume;
                        string cellMaterial;
                        asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                        if (volume > 0)
                        {
                            byte   existingVolume;
                            string existingCellMaterial;

                            var newCoord = ((minPrimary - min) + ((Vector3D)coords - modelPrimary.ContentBounds.Min)).RoundToVector3I();
                            newAsteroid.GetVoxelMaterialContent(ref newCoord, out existingCellMaterial, out existingVolume);

                            if (volume > existingVolume)
                            {
                                newAsteroid.SetVoxelContent(volume, ref newCoord);
                            }
                            // Overwrites secondary material with primary.
                            newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord);
                        }
                    }
                }
            }
        }
        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 coords;

            var asteroid = new MyVoxelMap();

            asteroid.Load(filenamePrimary);

            for (coords.Z = (int)modelPrimary.ContentBounds.Min.Z; coords.Z <= modelPrimary.ContentBounds.Max.Z; coords.Z++)
            {
                for (coords.Y = (int)modelPrimary.ContentBounds.Min.Y; coords.Y <= modelPrimary.ContentBounds.Max.Y; coords.Y++)
                {
                    for (coords.X = (int)modelPrimary.ContentBounds.Min.X; coords.X <= modelPrimary.ContentBounds.Max.X; coords.X++)
                    {
                        byte   volume;
                        string cellMaterial;
                        asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                        var newCoord = ((minPrimary - min) + ((Vector3D)coords - modelPrimary.ContentBounds.Min)).RoundToVector3I();
                        newAsteroid.SetVoxelContent(volume, ref newCoord);
                        newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord);
                    }
                }
            }

            asteroid.Load(filenameSecondary);

            for (coords.Z = (int)modelSecondary.ContentBounds.Min.Z; coords.Z <= modelSecondary.ContentBounds.Max.Z; coords.Z++)
            {
                for (coords.Y = (int)modelSecondary.ContentBounds.Min.Y; coords.Y <= modelSecondary.ContentBounds.Max.Y; coords.Y++)
                {
                    for (coords.X = (int)modelSecondary.ContentBounds.Min.X; coords.X <= modelSecondary.ContentBounds.Max.X; coords.X++)
                    {
                        var newCoord = ((minSecondary - min) + ((Vector3D)coords - modelSecondary.ContentBounds.Min)).RoundToVector3I();
                        if (Vector3I.BoxContains(Vector3I.Zero, modelPrimary.Size - 1, newCoord))
                        {
                            byte   volume;
                            string cellMaterial;
                            asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                            if (volume > 0)
                            {
                                newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        public void VoxelMaterialAssets_FixedSize_MixedContent()
        {
            SpaceEngineersCore.LoadDefinitions();
            var materials = SpaceEngineersCore.Resources.GetMaterialList();

            Assert.IsTrue(materials.Count > 0, "Materials should exist. Has the developer got Space Engineers installed?");

            var goldMaterial = materials.FirstOrDefault(m => m.Id.SubtypeId.Contains("Gold"));

            Assert.IsNotNull(goldMaterial, "Gold material should exist.");

            const string fileOriginal = @".\TestAssets\test_cube_mixed_2x2x2.vx2";

            var voxelMap = new MyVoxelMap();

            voxelMap.Load(fileOriginal, materials[0].Id.SubtypeId);
            var                     cellCount = voxelMap.SumVoxelCells();
            IList <byte>            materialAssets;
            Dictionary <byte, long> materialVoxelCells;

            voxelMap.CalculateMaterialCellAssets(out materialAssets, out materialVoxelCells);
            var assetNameCount = voxelMap.CountAssets(materialAssets);

            Assert.AreEqual(8 * 255, cellCount, "Cell count should be equal.");
            Assert.AreEqual(8, materialAssets.Count, "Asset count should be equal.");
            Assert.AreEqual(8, assetNameCount.Count, "Asset Mertials count should be equal.");
        }
Esempio n. 4
0
        public void VoxelMaterialAssets_MixedGeneratedAsset()
        {
            SpaceEngineersCore.LoadDefinitions();
            var materials = SpaceEngineersCore.Resources.GetMaterialList();

            Assert.IsTrue(materials.Count > 0, "Materials should exist. Has the developer got Space Engineers installed?");

            var goldMaterial = materials.FirstOrDefault(m => m.Id.SubtypeId.Contains("Gold"));

            Assert.IsNotNull(goldMaterial, "Gold material should exist.");

            const string fileOriginal = @".\TestAssets\asteroid0moon4.vx2";

            var voxelMap = new MyVoxelMap();

            voxelMap.Load(fileOriginal, materials[0].Id.SubtypeId);

            IList <byte>            materialAssets;
            Dictionary <byte, long> materialVoxelCells;

            voxelMap.CalculateMaterialCellAssets(out materialAssets, out materialVoxelCells);

            Assert.AreEqual(44135, materialAssets.Count, "Asset count should be equal.");

            var otherAssets = materialAssets.Where(c => c != 4).ToList();

            Assert.AreEqual(0, otherAssets.Count, "Other Asset count should be equal.");

            var assetNameCount = voxelMap.CountAssets(materialAssets);

            Assert.IsTrue(assetNameCount.Count > 0, "Contains assets.");
        }
        public void ReseedExecuted()
        {
            MainViewModel.IsBusy = true;
            var sourceFile = DataModel.SourceVoxelFilepath ?? DataModel.VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            var cellCount = asteroid.SumVoxelCells();

            // TODO: regenerate the materials inside of the asteroid randomly.


            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);

            asteroid.Save(tempfilename);
            DataModel.SourceVoxelFilepath = tempfilename;

            MainViewModel.IsModified = true;
            MainViewModel.IsBusy     = false;

            DataModel.MaterialAssets = null;
            DataModel.InitializeAsync();
        }
Esempio n. 6
0
        public void VoxelLoadStock()
        {
            SpaceEngineersCore.LoadDefinitions();
            var materials = SpaceEngineersCore.Resources.GetMaterialList();

            Assert.IsTrue(materials.Count > 0, "Materials should exist. Has the developer got Space Engineers installed?");

            var contentPath = ToolboxUpdater.GetApplicationContentPath();
            var redShipCrashedAsteroidPath = Path.Combine(contentPath, "VoxelMaps", "RedShipCrashedAsteroid.vx2");

            var voxelMap = new MyVoxelMap();

            voxelMap.Load(redShipCrashedAsteroidPath, materials[0].Id.SubtypeId);

            Assert.AreEqual(1, voxelMap.FileVersion, "FileVersion should be equal.");

            IList <byte>            materialAssets;
            Dictionary <byte, long> materialVoxelCells;

            voxelMap.CalculateMaterialCellAssets(out materialAssets, out materialVoxelCells);
            Assert.AreEqual(563742, materialAssets.Count, "Asset count should be equal.");

            var asset0 = materialAssets.Where(c => c == 0).ToList();

            Assert.AreEqual(563742, asset0.Count, "asset0 count should be equal.");

            var assetNameCount = voxelMap.CountAssets(materialAssets);

            Assert.IsTrue(assetNameCount.Count > 0, "Contains assets.");

            var lengthOriginal = new FileInfo(redShipCrashedAsteroidPath).Length;

            Assert.AreEqual(51819, lengthOriginal, "File size must match.");
        }
        public void ReplaceSelectedExecuted(string materialName)
        {
            MainViewModel.IsBusy = true;
            var sourceFile = DataModel.SourceVoxelFilepath ?? DataModel.VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            if (string.IsNullOrEmpty(materialName))
            {
                asteroid.RemoveContent(SelectedMaterialAsset.MaterialName, null);
                DataModel.VoxCells = asteroid.SumVoxelCells();
            }
            else
            {
                asteroid.ReplaceMaterial(SelectedMaterialAsset.MaterialName, materialName);
            }

            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);

            asteroid.Save(tempfilename);
            DataModel.SourceVoxelFilepath = tempfilename;

            MainViewModel.IsModified = true;
            MainViewModel.IsBusy     = false;

            DataModel.UpdateGeneralFromEntityBase();
            DataModel.MaterialAssets = null;
            DataModel.InitializeAsync();
        }
        public void ReseedExecuted()
        {
            MainViewModel.IsBusy = true;
            var sourceFile = DataModel.SourceVoxelFilepath ?? DataModel.VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile);

            var cellCount = asteroid.VoxCells;

            // TODO: regenerate the materials inside of the asteroid randomly.


            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);

            asteroid.Save(tempfilename);
            DataModel.UpdateNewSource(asteroid, tempfilename);

            MainViewModel.IsModified = true;
            MainViewModel.IsBusy     = false;

            DataModel.MaterialAssets = null;
            DataModel.InitializeAsync();
        }
Esempio n. 9
0
        public static void StripMaterial(string loadFile, string saveFile, string defaultMaterial, string stripMaterial, string replaceFillMaterial)
        {
            var voxelMap = new MyVoxelMap();

            voxelMap.Load(loadFile, defaultMaterial);
            voxelMap.RemoveContent(stripMaterial, replaceFillMaterial);
            voxelMap.Save(saveFile);
        }
Esempio n. 10
0
        public static void ConvertAsteroid(string loadFile, string saveFile, string defaultMaterial, string material)
        {
            var voxelMap = new MyVoxelMap();

            voxelMap.Load(loadFile, material);
            voxelMap.ForceBaseMaterial(defaultMaterial, material);
            voxelMap.Save(saveFile);
        }
Esempio n. 11
0
        public void SaveCheckPointAndSandBox()
        {
            IsBusy = true;
            ActiveWorld.SaveCheckPointAndSector(true);

            // Manages the adding of new voxel files.
            foreach (var entity in Structures)
            {
                if (entity is StructureVoxelModel)
                {
                    var voxel = (StructureVoxelModel)entity;
                    if (voxel.SourceVoxelFilepath != null && File.Exists(voxel.SourceVoxelFilepath))
                    {
                        // Any asteroid that already exists with same name, must be removed.
                        // TODO: must improve this later when multiple sectors are implemented and the asteroid filename is used in a different sector.
                        if (File.Exists(voxel.VoxelFilepath))
                        {
                            FileSystem.DeleteFile(voxel.VoxelFilepath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                        }

                        if (Path.GetExtension(voxel.SourceVoxelFilepath).Equals(MyVoxelMap.V1FileExtension, StringComparison.InvariantCultureIgnoreCase))
                        {
                            // Convert between formats.
                            var voxelmap = new MyVoxelMap();
                            voxelmap.Load(voxel.SourceVoxelFilepath, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);
                            voxelmap.Save(voxel.VoxelFilepath);
                        }
                        else
                        {
                            File.Copy(voxel.SourceVoxelFilepath, voxel.VoxelFilepath);
                        }
                        voxel.SourceVoxelFilepath = null;
                    }
                }
            }

            // Manages the removal old voxels files.
            foreach (var file in SpaceEngineersCore.ManageDeleteVoxelList)
            {
                var filename = Path.Combine(ActiveWorld.Savepath, file);
                if (File.Exists(filename))
                {
                    FileSystem.DeleteFile(filename, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin);
                }
            }
            SpaceEngineersCore.ManageDeleteVoxelList.Clear();

            IsModified = false;
            IsBusy     = false;
        }
Esempio n. 12
0
        public void VoxelMaterialAssetsGenerateFixed()
        {
            SpaceEngineersCore.LoadDefinitions();
            var materials = SpaceEngineersCore.Resources.GetMaterialList();

            Assert.IsTrue(materials.Count > 0, "Materials should exist. Has the developer got Space Engineers installed?");

            var files = new[] { @".\TestAssets\Arabian_Border_7.vx2", @".\TestAssets\cube_52x52x52.vx2" };

            foreach (var fileOriginal in files)
            {
                foreach (var material in materials)
                {
                    var fileNewVoxel =
                        Path.Combine(Path.GetDirectoryName(Path.GetFullPath(fileOriginal)),
                                     Path.GetFileNameWithoutExtension(fileOriginal) + "_" + material.Id.SubtypeId + ".vx2").ToLower();

                    var voxelMap = new MyVoxelMap();
                    voxelMap.Load(fileOriginal, materials[0].Id.SubtypeId);

                    IList <byte>            materialAssets;
                    Dictionary <byte, long> materialVoxelCells;
                    voxelMap.CalculateMaterialCellAssets(out materialAssets, out materialVoxelCells);

                    var distribution      = new[] { Double.NaN, .99, };
                    var materialSelection = new byte[] { 0, SpaceEngineersCore.Resources.GetMaterialIndex(material.Id.SubtypeId) };

                    var newDistributiuon = new List <byte>();
                    int count;
                    for (var i = 1; i < distribution.Count(); i++)
                    {
                        count = (int)Math.Floor(distribution[i] * materialAssets.Count); // Round down.
                        for (var j = 0; j < count; j++)
                        {
                            newDistributiuon.Add(materialSelection[i]);
                        }
                    }
                    count = materialAssets.Count - newDistributiuon.Count;
                    for (var j = 0; j < count; j++)
                    {
                        newDistributiuon.Add(materialSelection[0]);
                    }

                    newDistributiuon.Shuffle();

                    voxelMap.SetMaterialAssets(newDistributiuon);
                    voxelMap.Save(fileNewVoxel);
                }
            }
        }
        private void ReadVoxelDetails(string filename)
        {
            if (filename != null && File.Exists(filename) && _voxelMap == null)
            {
                _voxelMap = new MyVoxelMap();
                _voxelMap.Load(filename);

                Size           = _voxelMap.Size;
                _contentCenter = _voxelMap.ContentCenter;
                IsValid        = _voxelMap.IsValid;
                OnPropertyChanged(nameof(Size), nameof(IsValid));
                Center    = new Vector3D(_contentCenter.X + 0.5f + PositionX, _contentCenter.Y + 0.5f + PositionY, _contentCenter.Z + 0.5f + PositionZ);
                WorldAABB = new BoundingBoxD(PositionAndOrientation.Value.Position, PositionAndOrientation.Value.Position + new Vector3D(Size));
            }
        }
Esempio n. 14
0
        public void SliceHalfExecuted()
        {
            MainViewModel.IsBusy = true;
            var sourceFile = DataModel.SourceVoxelFilepath ?? DataModel.VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile);
            asteroid.RefreshAssets();

            var height = asteroid.BoundingContent.Size.Y + 1;

            // remove the Top half.
            asteroid.RemoveMaterial(null, null, (int)Math.Round(asteroid.ContentCenter.Y, 0), asteroid.Size.Y, null, null);

            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);

            asteroid.Save(tempfilename);

            var newFilename = MainViewModel.CreateUniqueVoxelStorageName(DataModel.Name);
            var posOrient   = DataModel.PositionAndOrientation.HasValue ? DataModel.PositionAndOrientation.Value : new MyPositionAndOrientation();

            posOrient.Position.y += height;

            // genreate a new Asteroid entry.
            var newEntity = new MyObjectBuilder_VoxelMap
            {
                EntityId               = SpaceEngineersApi.GenerateEntityId(IDType.ASTEROID),
                PersistentFlags        = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                StorageName            = Path.GetFileNameWithoutExtension(newFilename),
                PositionAndOrientation = new MyPositionAndOrientation
                {
                    Position = posOrient.Position,
                    Forward  = posOrient.Forward,
                    Up       = posOrient.Up
                }
            };

            var structure = MainViewModel.AddEntity(newEntity);

            ((StructureVoxelModel)structure).UpdateNewSource(asteroid, tempfilename); // Set the temporary file location of the Source Voxel, as it hasn't been written yet.

            MainViewModel.IsModified = true;
            MainViewModel.IsBusy     = false;
        }
Esempio n. 15
0
        private void ReadVoxelDetails(string filename)
        {
            if (_voxelMap == null && filename != null && File.Exists(filename))
            {
                _voxelMap = new MyVoxelMap();
                _voxelMap.Load(filename);

                Size          = _voxelMap.Size;
                ContentBounds = _voxelMap.BoundingContent;
                IsValid       = _voxelMap.IsValid;

                RaisePropertyChanged(() => Size);
                RaisePropertyChanged(() => ContentSize);
                RaisePropertyChanged(() => IsValid);
                Center    = new Vector3D(_contentBounds.Center.X + 0.5f + PositionX, _contentBounds.Center.Y + 0.5f + PositionY, _contentBounds.Center.Z + 0.5f + PositionZ);
                WorldAABB = new BoundingBoxD(PositionAndOrientation.Value.Position, PositionAndOrientation.Value.Position + new Vector3D(Size));
            }
        }
Esempio n. 16
0
        public void RotateAsteroid(VRageMath.Quaternion quaternion)
        {
            var sourceFile = SourceVoxelFilepath ?? VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            var newAsteroid = new MyVoxelMap();
            var transSize   = Vector3I.Transform(asteroid.Size, quaternion);
            var newSize     = Vector3I.Abs(transSize);

            newAsteroid.Init(Vector3D.Zero, newSize, SpaceEngineersCore.Resources.GetDefaultMaterialName());

            Vector3I coords;

            for (coords.Z = 0; coords.Z < asteroid.Size.Z; coords.Z++)
            {
                for (coords.Y = 0; coords.Y < asteroid.Size.Y; coords.Y++)
                {
                    for (coords.X = 0; coords.X < asteroid.Size.X; coords.X++)
                    {
                        byte   volume = 0xff;
                        string cellMaterial;

                        asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                        var newCoord = Vector3I.Transform(coords, quaternion);
                        // readjust the points, as rotation occurs arround 0,0,0.
                        newCoord.X = newCoord.X < 0 ? newCoord.X - transSize.X : newCoord.X;
                        newCoord.Y = newCoord.Y < 0 ? newCoord.Y - transSize.Y : newCoord.Y;
                        newCoord.Z = newCoord.Z < 0 ? newCoord.Z - transSize.Z : newCoord.Z;
                        newAsteroid.SetVoxelContent(volume, ref newCoord);
                        newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord);
                    }
                }
            }

            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);

            newAsteroid.Save(tempfilename);

            SourceVoxelFilepath = tempfilename;
        }
Esempio n. 17
0
        public void VoxelLoadSaveVox()
        {
            SpaceEngineersCore.LoadDefinitions();
            var materials = SpaceEngineersCore.Resources.GetMaterialList();

            Assert.IsTrue(materials.Count > 0, "Materials should exist. Has the developer got Space Engineers installed?");

            const string fileOriginal = @".\TestAssets\asteroid0moon4.vox";
            const string fileNew      = @".\TestOutput\asteroid0moon4_save.vox";

            var voxelMap = new MyVoxelMap();

            voxelMap.Load(fileOriginal, materials[0].Id.SubtypeId);
            voxelMap.Save(fileNew);

            var lengthOriginal = new FileInfo(fileOriginal).Length;
            var lengthNew      = new FileInfo(fileNew).Length;

            Assert.AreEqual(9428, lengthOriginal, "File size must match.");
            Assert.AreEqual(9428, lengthNew, "File size must match.");
        }
Esempio n. 18
0
        public void LoadAllVoxelFiles()
        {
            SpaceEngineersCore.LoadDefinitions();

            var files = Directory.GetFiles(Path.Combine(ToolboxUpdater.GetApplicationContentPath(), "VoxelMaps"), "*.vx2");

            foreach (var filename in files)
            {
                var voxelMap = new MyVoxelMap();
                voxelMap.Load(filename, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

                Assert.IsTrue(voxelMap.Size.X > 0, "Voxel Size must be greater than zero.");
                Assert.IsTrue(voxelMap.Size.Y > 0, "Voxel Size must be greater than zero.");
                Assert.IsTrue(voxelMap.Size.Z > 0, "Voxel Size must be greater than zero.");

                Debug.WriteLine(string.Format("Filename:\t{0}.vx2", Path.GetFileName(filename)));
                Debug.WriteLine(string.Format("Bounding Size:\t{0} × {1} × {2} blocks", voxelMap.Size.X, voxelMap.Size.Y, voxelMap.Size.Z));
                Debug.WriteLine(string.Format("Size:\t{0} m × {1} m × {2} m", voxelMap.BoundingContent.SizeInt().X + 1, voxelMap.BoundingContent.SizeInt().Y + 1, voxelMap.BoundingContent.SizeInt().Z + 1));
                Debug.WriteLine(string.Format("Volume:\t{0:##,###.00} m³", (double)voxelMap.SumVoxelCells() / 255));
                Debug.WriteLine("");
            }
        }
Esempio n. 19
0
        public void ReplaceAllExecuted(string materialName)
        {
            MainViewModel.IsBusy = true;
            var sourceFile = DataModel.SourceVoxelFilepath ?? DataModel.VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile);

            asteroid.ForceBaseMaterial(materialName, materialName);

            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);

            asteroid.Save(tempfilename);
            DataModel.UpdateNewSource(asteroid, tempfilename);

            MainViewModel.IsModified = true;
            MainViewModel.IsBusy     = false;

            DataModel.MaterialAssets = null;
            DataModel.InitializeAsync();
        }
Esempio n. 20
0
        public void ReplaceSurfaceExecuted(string materialName)
        {
            MainViewModel.IsBusy = true;
            var sourceFile = DataModel.SourceVoxelFilepath ?? DataModel.VoxelFilepath;

            var asteroid = new MyVoxelMap();

            asteroid.Load(sourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            asteroid.ForceShellMaterial(materialName, 2);

            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);

            asteroid.Save(tempfilename);
            DataModel.SourceVoxelFilepath = tempfilename;

            MainViewModel.IsModified = true;
            MainViewModel.IsBusy     = false;

            DataModel.MaterialAssets = null;
            DataModel.InitializeAsync();
        }
Esempio n. 21
0
        public void VoxelDetails()
        {
            SpaceEngineersCore.LoadDefinitions();
            var materials = SpaceEngineersCore.Resources.GetMaterialList();

            Assert.IsTrue(materials.Count > 0, "Materials should exist. Has the developer got Space Engineers installed?");

            const string fileOriginal = @".\TestAssets\DeformedSphereWithHoles_64x128x64.vx2";

            var voxelMap = new MyVoxelMap();

            voxelMap.Load(fileOriginal, materials[0].Id.SubtypeId);
            var voxCells = voxelMap.SumVoxelCells();

            Assert.AreEqual(64, voxelMap.Size.X, "Voxel Bounding size must match.");
            Assert.AreEqual(128, voxelMap.Size.Y, "Voxel Bounding size must match.");
            Assert.AreEqual(64, voxelMap.Size.Z, "Voxel Bounding size must match.");

            Assert.AreEqual(48, voxelMap.BoundingContent.SizeInt().X + 1, "Voxel Content size must match.");
            Assert.AreEqual(112, voxelMap.BoundingContent.SizeInt().Y + 1, "Voxel Content size must match.");
            Assert.AreEqual(48, voxelMap.BoundingContent.SizeInt().Z + 1, "Voxel Content size must match.");

            Assert.AreEqual(30909925, voxCells, "Voxel cells must match.");
        }
Esempio n. 22
0
        public MyObjectBuilder_EntityBase BuildEntity()
        {
            var asteroidCenter = new VRageMath.Vector3D();
            var asteroidSize   = new Vector3I();

            string originalFile = null;

            if (IsStockVoxel)
            {
                var stockfile = StockVoxel.SourceFilename;

                if (StockMaterial == null || StockMaterial.Value == null)
                {
                    SourceFile   = stockfile;
                    originalFile = SourceFile;
                    var asteroid = new MyVoxelMap();
                    asteroid.Load(stockfile);
                    asteroidCenter = asteroid.BoundingContent.Center;
                    asteroidSize   = asteroid.BoundingContent.Size + 1; // Content size
                }
                else
                {
                    var asteroid = new MyVoxelMap();
                    asteroid.Load(stockfile);
                    asteroid.ForceBaseMaterial(SpaceEngineersCore.Resources.GetDefaultMaterialName(), StockMaterial.Value);
                    SourceFile = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                    asteroid.Save(SourceFile);

                    originalFile   = StockVoxel.SourceFilename;
                    asteroidCenter = asteroid.BoundingContent.Center;
                    asteroidSize   = asteroid.BoundingContent.Size + 1; // Content size
                }
            }
            else if (IsFileVoxel)
            {
                originalFile = SourceFile;

                var asteroid = new MyVoxelMap();
                asteroid.Load(SourceFile);
                asteroidCenter = asteroid.BoundingContent.Center;
                asteroidSize   = asteroid.BoundingContent.Size + 1; // Content size

                if (StockMaterial != null && StockMaterial.Value != null)
                {
                    asteroid.ForceBaseMaterial(SpaceEngineersCore.Resources.GetDefaultMaterialName(), StockMaterial.Value);
                    SourceFile = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                    asteroid.Save(SourceFile);
                }
            }
            else if (IsSphere)
            {
                byte materialIndex;
                if (StockMaterial?.MaterialIndex != null)
                {
                    materialIndex = StockMaterial.MaterialIndex.Value;
                }
                else
                {
                    materialIndex = SpaceEngineersCore.Resources.GetDefaultMaterialIndex();
                }

                string materialName = SpaceEngineersCore.Resources.GetMaterialName(materialIndex);

                originalFile = string.Format("sphere_{0}_{1}_{2}{3}", materialName.ToLowerInvariant(), SphereRadius, SphereShellRadius, MyVoxelMap.V2FileExtension);

                var asteroid = MyVoxelBuilder.BuildAsteroidSphere(SphereRadius > 32, SphereRadius, materialIndex, materialIndex, SphereShellRadius != 0, SphereShellRadius);
                // TODO: progress bar.
                asteroidCenter = asteroid.BoundingContent.Center;
                asteroidSize   = asteroid.BoundingContent.Size + 1; // Content size
                SourceFile     = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                asteroid.Save(SourceFile);
            }

            // automatically number all files, and check for duplicate filenames.
            Filename = MainViewModel.CreateUniqueVoxelStorageName(originalFile);

            // Figure out where the Character is facing, and plant the new constrcut right in front.
            // Calculate the hypotenuse, as it will be the safest distance to place in front.
            double distance = Math.Sqrt(Math.Pow(asteroidSize.X, 2) + Math.Pow(asteroidSize.Y, 2) + Math.Pow(asteroidSize.Z, 2)) / 2;

            var vector = new BindableVector3DModel(_dataModel.CharacterPosition.Forward).Vector3D;

            vector.Normalize();
            vector   = System.Windows.Media.Media3D.Vector3D.Multiply(vector, distance);
            Position = new BindablePoint3DModel(Point3D.Add(new BindablePoint3DModel(_dataModel.CharacterPosition.Position).Point3D, vector));
            //Forward = new BindableVector3DModel(_dataModel.CharacterPosition.Forward);
            //Up = new BindableVector3DModel(_dataModel.CharacterPosition.Up);
            Forward = new BindableVector3DModel(Vector3.Forward);  // Asteroids currently don't have any orientation.
            Up      = new BindableVector3DModel(Vector3.Up);

            var entity = new MyObjectBuilder_VoxelMap
            {
                EntityId               = SpaceEngineersApi.GenerateEntityId(IDType.ASTEROID),
                PersistentFlags        = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                StorageName            = Path.GetFileNameWithoutExtension(Filename),
                PositionAndOrientation = new MyPositionAndOrientation
                {
                    Position = Position.ToVector3D() - asteroidCenter,
                    Forward  = Forward.ToVector3(),
                    Up       = Up.ToVector3()
                }
            };

            return(entity);
        }
Esempio n. 23
0
        private bool ExtractStationIntersect(bool tightIntersection)
        {
            // Make a shortlist of station Entities in the bounding box of the asteroid.
            var asteroidWorldAABB = new BoundingBoxD(DataModel.ContentBounds.Min + DataModel.PositionAndOrientation.Value.Position, DataModel.ContentBounds.Max + DataModel.PositionAndOrientation.Value.Position);
            var stations          = MainViewModel.GetIntersectingEntities(asteroidWorldAABB).Where(e => e.ClassType == ClassType.Station).Cast <StructureCubeGridModel>().ToList();

            if (stations.Count == 0)
            {
                return(false);
            }

            var modified   = false;
            var sourceFile = DataModel.SourceVoxelFilepath ?? DataModel.VoxelFilepath;
            var asteroid   = new MyVoxelMap();

            asteroid.Load(sourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            var total = stations.Sum(s => s.CubeGrid.CubeBlocks.Count);

            MainViewModel.ResetProgress(0, total);

            // Search through station entities cubes for intersection with this voxel.
            foreach (var station in stations)
            {
                var quaternion = station.PositionAndOrientation.Value.ToQuaternion();

                foreach (var cube in station.CubeGrid.CubeBlocks)
                {
                    MainViewModel.IncrementProgress();

                    var definition = SpaceEngineersApi.GetCubeDefinition(cube.TypeId, station.CubeGrid.GridSizeEnum, cube.SubtypeName);

                    var orientSize    = definition.Size.Transform(cube.BlockOrientation).Abs();
                    var min           = cube.Min.ToVector3() * station.CubeGrid.GridSizeEnum.ToLength();
                    var max           = (cube.Min + orientSize) * station.CubeGrid.GridSizeEnum.ToLength();
                    var p1            = Vector3D.Transform(min, quaternion) + station.PositionAndOrientation.Value.Position - (station.CubeGrid.GridSizeEnum.ToLength() / 2);
                    var p2            = Vector3D.Transform(max, quaternion) + station.PositionAndOrientation.Value.Position - (station.CubeGrid.GridSizeEnum.ToLength() / 2);
                    var cubeWorldAABB = new BoundingBoxD(Vector3.Min(p1, p2), Vector3.Max(p1, p2));

                    // find worldAABB of block.
                    if (asteroidWorldAABB.Intersects(cubeWorldAABB))
                    {
                        var pointMin = new Vector3I(cubeWorldAABB.Min - DataModel.PositionAndOrientation.Value.Position);
                        var pointMax = new Vector3I(cubeWorldAABB.Max - DataModel.PositionAndOrientation.Value.Position);

                        Vector3I coords;
                        for (coords.Z = pointMin.Z; coords.Z <= pointMax.Z; coords.Z++)
                        {
                            for (coords.Y = pointMin.Y; coords.Y <= pointMax.Y; coords.Y++)
                            {
                                for (coords.X = pointMin.X; coords.X <= pointMax.X; coords.X++)
                                {
                                    if (coords.X >= 0 && coords.Y >= 0 && coords.Z >= 0 && coords.X < asteroid.Size.X && coords.Y < asteroid.Size.Y && coords.Z < asteroid.Size.Z)
                                    {
                                        asteroid.SetVoxelContent(0, ref coords);
                                    }
                                }
                            }
                        }

                        modified = true;
                    }
                }
            }

            MainViewModel.ClearProgress();

            if (modified)
            {
                var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                asteroid.Save(tempfilename);
                // replaces the existing asteroid file, as it is still the same size and dimentions.
                DataModel.SourceVoxelFilepath = tempfilename;
            }
            return(modified);
        }
Esempio n. 24
0
        public bool ExtractStationIntersect(IMainView mainViewModel, bool tightIntersection)
        {
            // Make a shortlist of station Entities in the bounding box of the asteroid.
            var asteroidWorldAABB = new BoundingBoxD((Vector3D)ContentBounds.Min + PositionAndOrientation.Value.Position, (Vector3D)ContentBounds.Max + PositionAndOrientation.Value.Position);
            var stations          = mainViewModel.GetIntersectingEntities(asteroidWorldAABB).Where(e => e.ClassType == ClassType.LargeStation).Cast <StructureCubeGridModel>().ToList();

            if (stations.Count == 0)
            {
                return(false);
            }

            var modified   = false;
            var sourceFile = SourceVoxelFilepath ?? VoxelFilepath;
            var asteroid   = new MyVoxelMap();

            asteroid.Load(sourceFile);

            var total = stations.Sum(s => s.CubeGrid.CubeBlocks.Count);

            mainViewModel.ResetProgress(0, total);

            // Search through station entities cubes for intersection with this voxel.
            foreach (var station in stations)
            {
                var quaternion = station.PositionAndOrientation.Value.ToQuaternion();

                foreach (var cube in station.CubeGrid.CubeBlocks)
                {
                    mainViewModel.IncrementProgress();

                    var definition = SpaceEngineersApi.GetCubeDefinition(cube.TypeId, station.CubeGrid.GridSizeEnum, cube.SubtypeName);

                    var orientSize    = definition.Size.Transform(cube.BlockOrientation).Abs();
                    var min           = cube.Min.ToVector3() * station.CubeGrid.GridSizeEnum.ToLength();
                    var max           = (cube.Min + orientSize) * station.CubeGrid.GridSizeEnum.ToLength();
                    var p1            = Vector3D.Transform(min, quaternion) + station.PositionAndOrientation.Value.Position - (station.CubeGrid.GridSizeEnum.ToLength() / 2);
                    var p2            = Vector3D.Transform(max, quaternion) + station.PositionAndOrientation.Value.Position - (station.CubeGrid.GridSizeEnum.ToLength() / 2);
                    var cubeWorldAABB = new BoundingBoxD(Vector3.Min(p1, p2), Vector3.Max(p1, p2));

                    // find worldAABB of block.
                    if (asteroidWorldAABB.Intersects(cubeWorldAABB))
                    {
                        Vector3I block;
                        var      cacheSize = new Vector3I(64);
                        Vector3D position  = PositionAndOrientation.Value.Position;

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

                                    bool     changed = false;
                                    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)
                                            {
                                                BoundingBoxD    voxelCellBox = new BoundingBoxD(position + p + block, position + p + block + 1);
                                                ContainmentType contains     = cubeWorldAABB.Contains(voxelCellBox);

                                                // TODO: finish tightIntersection. Will require high interpretation of voxel content volumes.

                                                if (contains == ContainmentType.Contains || contains == ContainmentType.Intersects)
                                                {
                                                    cache.Content(ref p, 0);
                                                    changed = true;
                                                }
                                            }
                                        }
                                    }

                                    if (changed)
                                    {
                                        asteroid.Storage.WriteRange(cache, MyStorageDataTypeFlags.Content, block, maxRange);
                                        modified = true;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            mainViewModel.ClearProgress();

            if (modified)
            {
                var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                asteroid.Save(tempfilename);
                // replaces the existing asteroid file, as it is still the same size and dimentions.
                UpdateNewSource(asteroid, tempfilename);
                MaterialAssets = null;
                InitializeAsync();
            }
            return(modified);
        }
Esempio n. 25
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);
                    }
                }
            }
        }
Esempio n. 26
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. 27
0
        public void VoxelMaterialAssetsRandom()
        {
            SpaceEngineersCore.LoadDefinitions();
            var materials = SpaceEngineersCore.Resources.GetMaterialList();

            Assert.IsTrue(materials.Count > 0, "Materials should exist. Has the developer got Space Engineers installed?");

            var stoneMaterial = materials.FirstOrDefault(m => m.Id.SubtypeId.Contains("Stone_05"));

            Assert.IsNotNull(stoneMaterial, "Stone material should exist.");
            var goldMaterial = materials.FirstOrDefault(m => m.Id.SubtypeId.Contains("Gold"));

            Assert.IsNotNull(goldMaterial, "Gold material should exist.");
            var uraniumMaterial = materials.FirstOrDefault(m => m.Id.SubtypeId.Contains("Uraninite_01"));

            Assert.IsNotNull(uraniumMaterial, "Uranium material should exist.");

            const string fileOriginal = @".\TestAssets\Arabian_Border_7.vx2";
            const string fileNewVoxel = @".\TestOutput\Arabian_Border_7_mixed.vx2";

            var voxelMap = new MyVoxelMap();

            voxelMap.Load(fileOriginal, materials[0].Id.SubtypeId);
            IList <byte>            materialAssets;
            Dictionary <byte, long> materialVoxelCells;

            voxelMap.CalculateMaterialCellAssets(out materialAssets, out materialVoxelCells);

            Assert.AreEqual(35465, materialAssets.Count, "Asset count should be equal.");

            var distribution      = new[] { Double.NaN, .5, .25 };
            var materialSelection = new[] { SpaceEngineersCore.Resources.GetMaterialIndex(stoneMaterial.Id.SubtypeId), SpaceEngineersCore.Resources.GetMaterialIndex(goldMaterial.Id.SubtypeId), SpaceEngineersCore.Resources.GetMaterialIndex(uraniumMaterial.Id.SubtypeId) };

            var newDistributiuon = new List <byte>();
            int count;

            for (var i = 1; i < distribution.Count(); i++)
            {
                count = (int)Math.Floor(distribution[i] * materialAssets.Count); // Round down.
                for (var j = 0; j < count; j++)
                {
                    newDistributiuon.Add(materialSelection[i]);
                }
            }
            count = materialAssets.Count - newDistributiuon.Count;
            for (var j = 0; j < count; j++)
            {
                newDistributiuon.Add(materialSelection[0]);
            }

            newDistributiuon.Shuffle();

            var assetNameCount = voxelMap.CountAssets(newDistributiuon);

            Assert.AreEqual(3, assetNameCount.Count, "Asset Mertials count should be equal.");
            Assert.AreEqual(8867, assetNameCount[stoneMaterial.Id.SubtypeId], "Asset Mertials count should be equal.");
            Assert.AreEqual(17732, assetNameCount[goldMaterial.Id.SubtypeId], "Asset Mertials count should be equal.");
            Assert.AreEqual(8866, assetNameCount[uraniumMaterial.Id.SubtypeId], "Asset Mertials count should be equal.");

            voxelMap.SetMaterialAssets(newDistributiuon);

            voxelMap.CalculateMaterialCellAssets(out materialAssets, out materialVoxelCells);
            var cellCount = voxelMap.SumVoxelCells();

            voxelMap.Save(fileNewVoxel);
        }
        private void SubtractAsteroidVolumeFrom(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 coords;

            var asteroid = new MyVoxelMap();

            asteroid.Load(filenamePrimary, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            for (coords.Z = (int)modelPrimary.ContentBounds.Min.Z; coords.Z <= modelPrimary.ContentBounds.Max.Z; coords.Z++)
            {
                for (coords.Y = (int)modelPrimary.ContentBounds.Min.Y; coords.Y <= modelPrimary.ContentBounds.Max.Y; coords.Y++)
                {
                    for (coords.X = (int)modelPrimary.ContentBounds.Min.X; coords.X <= modelPrimary.ContentBounds.Max.X; coords.X++)
                    {
                        byte   volume;
                        string cellMaterial;
                        asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                        var newCoord = ((minPrimary - min) + ((Vector3D)coords - modelPrimary.ContentBounds.Min)).RoundToVector3I();
                        newAsteroid.SetVoxelContent(volume, ref newCoord);
                        newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord);
                    }
                }
            }

            asteroid.Load(filenameSecondary, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            for (coords.Z = (int)modelSecondary.ContentBounds.Min.Z; coords.Z <= modelSecondary.ContentBounds.Max.Z; coords.Z++)
            {
                for (coords.Y = (int)modelSecondary.ContentBounds.Min.Y; coords.Y <= modelSecondary.ContentBounds.Max.Y; coords.Y++)
                {
                    for (coords.X = (int)modelSecondary.ContentBounds.Min.X; coords.X <= modelSecondary.ContentBounds.Max.X; coords.X++)
                    {
                        var newCoord = ((minSecondary - min) + ((Vector3D)coords - modelSecondary.ContentBounds.Min)).RoundToVector3I();
                        if (Vector3I.BoxContains(Vector3I.Zero, modelPrimary.Size - 1, newCoord))
                        {
                            byte   volume;
                            string cellMaterial;
                            asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                            if (volume > 0)
                            {
                                byte   existingVolume;
                                string existingCellMaterial;

                                newAsteroid.GetVoxelMaterialContent(ref newCoord, out existingCellMaterial, out existingVolume);

                                if (existingVolume - volume < 0)
                                {
                                    volume = 0;
                                }
                                else
                                {
                                    volume = (byte)(existingVolume - volume);
                                }

                                newAsteroid.SetVoxelContent(volume, ref newCoord);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 29
0
        public void VoxelLoadSaveVx2V1()
        {
            SpaceEngineersCore.LoadDefinitions();
            var materials = SpaceEngineersCore.Resources.GetMaterialList();

            Assert.IsTrue(materials.Count > 0, "Materials should exist. Has the developer got Space Engineers installed?");

            const string fileOriginal = @".\TestAssets\AsteroidV1Format.vx2";
            const string fileNew      = @".\TestOutput\AsteroidV1Format_save.vx2";

            var voxelMap = new MyVoxelMap();

            voxelMap.Load(fileOriginal, materials[0].Id.SubtypeId);

            IList <byte>            materialAssets;
            Dictionary <byte, long> materialVoxelCells;

            voxelMap.CalculateMaterialCellAssets(out materialAssets, out materialVoxelCells);
            Assert.AreEqual(594485, materialAssets.Count, "Asset count should be equal.");

            var asset0 = materialAssets.Where(c => c == 0).ToList();

            Assert.AreEqual(0, asset0.Count, "asset0 count should be equal.");

            var asset1 = materialAssets.Where(c => c == 1).ToList();

            Assert.AreEqual(0, asset1.Count, "asset1 Asset count should be equal.");

            var asset2 = materialAssets.Where(c => c == 2).ToList();

            Assert.AreEqual(0, asset2.Count, "asset2 Asset count should be equal.");

            var asset3 = materialAssets.Where(c => c == 3).ToList();

            Assert.AreEqual(251145, asset3.Count, "asset3 Asset count should be equal.");

            var asset4 = materialAssets.Where(c => c == 4).ToList();

            Assert.AreEqual(0, asset4.Count, "asset4 Asset count should be equal.");

            var asset5 = materialAssets.Where(c => c == 5).ToList();

            Assert.AreEqual(0, asset5.Count, "asset5 Asset count should be equal.");

            var asset6 = materialAssets.Where(c => c == 6).ToList();

            Assert.AreEqual(217283, asset6.Count, "asset6 Asset count should be equal.");

            var asset7 = materialAssets.Where(c => c == 7).ToList();

            Assert.AreEqual(237, asset7.Count, "asset7 Asset count should be equal.");

            var asset8 = materialAssets.Where(c => c == 8).ToList();

            Assert.AreEqual(9608, asset8.Count, "asset8 Asset count should be equal.");

            var asset9 = materialAssets.Where(c => c == 9).ToList();

            Assert.AreEqual(40801, asset9.Count, "asset9 Asset count should be equal.");

            var asset10 = materialAssets.Where(c => c == 10).ToList();

            Assert.AreEqual(152, asset10.Count, "asset10 Asset count should be equal.");

            var assetNameCount = voxelMap.CountAssets(materialAssets);

            Assert.IsTrue(assetNameCount.Count > 0, "Contains assets.");

            voxelMap.Save(fileNew);

            var lengthOriginal = new FileInfo(fileOriginal).Length;
            var lengthNew      = new FileInfo(fileNew).Length;

            Assert.AreEqual(88299, lengthOriginal, "File size must match.");
            Assert.AreEqual(72296, lengthNew, "File size must match.");
        }
        public void BuildEntities(out string[] sourceVoxelFiles, out MyObjectBuilder_EntityBase[] sourceEntities)
        {
            var entities    = new List <MyObjectBuilder_EntityBase>();
            var sourceFiles = new List <string>();

            MainViewModel.ResetProgress(0, VoxelCollection.Count);

            foreach (var voxelDesign in VoxelCollection)
            {
                MainViewModel.Progress++;
                if (string.IsNullOrEmpty(voxelDesign.VoxelFile.SourceFilename) || !MyVoxelMap.IsVoxelMapFile(voxelDesign.VoxelFile.SourceFilename))
                {
                    continue;
                }


                var    asteroid           = new MyVoxelMap();
                string tempSourcefilename = null;

                switch (AsteroidFillType)
                {
                case Support.AsteroidFillType.None:
                    asteroid.Load(voxelDesign.VoxelFile.SourceFilename, voxelDesign.MainMaterial.Value, false);
                    tempSourcefilename = voxelDesign.VoxelFile.SourceFilename;
                    break;

                case AsteroidFillType.ByteFiller:
                    asteroid.Load(voxelDesign.VoxelFile.SourceFilename, voxelDesign.MainMaterial.Value, false);
                    var filler = new AsteroidByteFiller();
                    filler.FillAsteroid(asteroid, voxelDesign);
                    tempSourcefilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
                    asteroid.Save(tempSourcefilename);
                    break;
                }


                // automatically number all files, and check for duplicate filenames.
                var filename = MainViewModel.CreateUniqueVoxelStorageName(voxelDesign.VoxelFile.Name + MyVoxelMap.V2FileExtension, entities.ToArray());

                var radius    = RandomUtil.GetDouble(MinimumRange, MaximumRange);
                var longitude = RandomUtil.GetDouble(0, 2 * Math.PI);
                var latitude  = RandomUtil.GetDouble(-Math.PI / 2, (Math.PI / 2) + double.Epsilon);

                // Test data. Place asteroids items into a circle.
                //radius = 500;
                //longitude = Math.PI * 2 * ((double)voxelDesign.Index / VoxelCollection.Count);
                //latitude = 0;

                var x = radius * Math.Cos(latitude) * Math.Cos(longitude);
                var z = radius * Math.Cos(latitude) * Math.Sin(longitude);
                var y = radius * Math.Sin(latitude);

                var center   = new Vector3D(CenterPositionX, CenterPositionY, CenterPositionZ);
                var position = center + new Vector3D(x, y, z) - asteroid.BoundingContent.Center;
                var entity   = new MyObjectBuilder_VoxelMap(position, filename)
                {
                    EntityId               = SpaceEngineersApi.GenerateEntityId(IDType.ASTEROID),
                    PersistentFlags        = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene,
                    StorageName            = Path.GetFileNameWithoutExtension(filename),
                    PositionAndOrientation = new MyPositionAndOrientation
                    {
                        Position = position,
                        Forward  = Vector3.Forward, // Asteroids currently don't have any orientation.
                        Up       = Vector3.Up
                    }
                };

                entities.Add(entity);
                sourceFiles.Add(tempSourcefilename);
            }

            sourceVoxelFiles = sourceFiles.ToArray();
            sourceEntities   = entities.ToArray();
        }