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(); }
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 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."); }
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(""); } }
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."); }
/// <summary> /// Processes an asteroid Voxel using function callbacks. /// This allows for muti-threading, and generating content via algorithims. /// </summary> /// <param name="voxelMap"></param> /// <param name="multiThread"></param> /// <param name="material"></param> /// <param name="func"></param> /// <param name="readWrite"></param> /// <returns></returns> public static void ProcessAsteroid(MyVoxelMap voxelMap, bool multiThread, string material, Action <MyVoxelBuilderArgs> func, bool readWrite = true) { long counterTotal = (long)voxelMap.Size.X * (long)voxelMap.Size.Y * (long)voxelMap.Size.Z; long counter = 0; decimal progress = 0; var timer = new Stopwatch(); Debug.Write(string.Format("Building Asteroid : {0:000},", progress)); Console.Write(string.Format("Building Asteroid : {0:000},", progress)); Exception threadException = null; timer.Start(); if (!multiThread) { #region single thread processing for (var x = 0; x < voxelMap.Size.X; x++) { for (var y = 0; y < voxelMap.Size.Y; y++) { for (var z = 0; z < voxelMap.Size.Z; z++) { var coords = new Vector3I(x, y, z); byte volume = 0xff; var cellMaterial = material; if (readWrite) { voxelMap.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume); } var args = new MyVoxelBuilderArgs(voxelMap.Size, coords, cellMaterial, volume, 0xff); try { func(args); } catch (Exception ex) { threadException = ex; break; } if (args.Volume != MyVoxelConstants.VOXEL_CONTENT_FULL) { voxelMap.SetVoxelContent(args.Volume, ref coords); } if (material != args.Material) { voxelMap.SetVoxelMaterialAndIndestructibleContent(args.Material, args.Indestructible, ref coords); } counter++; var prog = Math.Floor(counter / (decimal)counterTotal * 100); if (prog != progress) { progress = prog; Debug.Write(string.Format("{0:000},", progress)); } } } } #endregion } else { #region multi thread processing // TODO: re-write the multi thread processing to be more stable. // But still try and max out the processors. long threadCounter = counterTotal / MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE / MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE / MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE; var baseCoords = new Vector3I(0, 0, 0); for (baseCoords.X = 0; baseCoords.X < voxelMap.Size.X; baseCoords.X += MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE) { for (baseCoords.Y = 0; baseCoords.Y < voxelMap.Size.Y; baseCoords.Y += MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE) { for (baseCoords.Z = 0; baseCoords.Z < voxelMap.Size.Z; baseCoords.Z += MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE) { var task = new Task(obj => { var bgw = (MyVoxelTaskWorker)obj; var coords = new Vector3I(0, 0, 0); for (coords.X = bgw.BaseCoords.X; coords.X < bgw.BaseCoords.X + MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE; coords.X++) { for (coords.Y = bgw.BaseCoords.Y; coords.Y < bgw.BaseCoords.Y + MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE; coords.Y++) { for (coords.Z = bgw.BaseCoords.Z; coords.Z < bgw.BaseCoords.Z + MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE; coords.Z++) { byte volume = 0xff; var cellMaterial = material; if (readWrite) { voxelMap.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume); } var args = new MyVoxelBuilderArgs(voxelMap.Size, coords, cellMaterial, volume, 0xff); try { func(args); } catch (Exception ex) { threadException = ex; threadCounter = 0; break; } if (args.Volume != MyVoxelConstants.VOXEL_CONTENT_FULL) { voxelMap.SetVoxelContent(args.Volume, ref coords); } if (material != args.Material) { voxelMap.SetVoxelMaterialAndIndestructibleContent(args.Material, args.Indestructible, ref coords); } } } } lock (Locker) { counter += (long)MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE * MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE * MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE; var prog = Math.Floor(counter / (decimal)counterTotal * 100); if (prog != progress) { progress = prog; Debug.Write(string.Format("{0:000},", progress)); Console.Write(string.Format("{0:000},", progress)); GC.Collect(); } threadCounter--; } }, new MyVoxelTaskWorker(baseCoords)); task.Start(); } } } GC.Collect(); while (threadCounter > 0) { System.Windows.Forms.Application.DoEvents(); } System.Threading.Thread.Sleep(100); System.Windows.Forms.Application.DoEvents(); #endregion } timer.Stop(); if (threadException != null) { throw threadException; } voxelMap.UpdateContentBounds(); var count = voxelMap.SumVoxelCells(); Debug.WriteLine(" Done. | {0} | VoxCells {1:#,##0}", timer.Elapsed, count); Console.WriteLine(" Done. | {0} | VoxCells {1:#,##0}", timer.Elapsed, count); }
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); }