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); }
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); }
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."); }
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 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."); }
/// <summary> /// Builds an asteroid Voxel. Voxel detail will be completed by function callbacks. /// This allows for muti-threading, and generating content via algorithims. /// </summary> /// <param name="multiThread"></param> /// <param name="size"></param> /// <param name="material"></param> /// <param name="faceMaterial"></param> /// <param name="func"></param> /// <returns></returns> public static MyVoxelMap BuildAsteroid(bool multiThread, Vector3I size, string material, string faceMaterial, Action<MyVoxelBuilderArgs> func) { var voxelMap = new MyVoxelMap(); var actualSize = new Vector3I(size.X.RoundUpToNearest(64), size.Y.RoundUpToNearest(64), size.Z.RoundUpToNearest(64)); voxelMap.Init(VRageMath.Vector3D.Zero, actualSize, material); ProcessAsteroid(voxelMap, multiThread, material, func, false); if (faceMaterial != null) { voxelMap.ForceVoxelFaceMaterial(faceMaterial); } return voxelMap; }
public void FillAsteroid(MyVoxelMap asteroid, IMyVoxelFillProperties fillProperties) { _fillMethod.FillAsteroid(asteroid, fillProperties); }
public static void GetPreview(string filename, out Vector3I size, out BoundingBoxD contentBounds, out long voxCells, out bool isValid) { try { var map = new MyVoxelMap(); map.Load(filename, SpaceEngineersCore.Resources.GetDefaultMaterialName(), false); size = map.Size; contentBounds = map.BoundingContent; voxCells = map.SumVoxelCells(); isValid = map.IsValid; } catch (Exception ex) { size = Vector3I.Zero; contentBounds = new BoundingBoxD(); voxCells = 0; isValid = false; DiagnosticsLogging.LogWarning(string.Format(Res.ExceptionState_CorruptAsteroidFile, filename), ex); } }
public void FillAsteroid(MyVoxelMap asteroid, IMyVoxelFillProperties fillProperties) { var properties = (AsteroidSeedFillProperties)fillProperties; /* The full history behind this hack/crutch eludes me. * There are roids that won't change their materials unless their face materials forced to something other than current value. * So we have to do that manually by setting to a usually unused ore (uranium) and then reverting to the one we chose (=old one in case of a flaky roid) */ byte oldMaterial = asteroid.VoxelMaterial; asteroid.ForceVoxelFaceMaterial("Uraninite_01"); asteroid.ForceVoxelFaceMaterial(properties.MainMaterial.Value); // Cycle through veins info and add 'spherical' depisits to the voxel cell grid (not voxels themselves) int i; if (properties.FirstVeins > 0) for (i = 0; i < properties.FirstVeins; i++) asteroid.SeedMaterialSphere(properties.FirstMaterial.Value, (byte)properties.FirstRadius); if (properties.SecondVeins > 0) for (i = 0; i < properties.SecondVeins; i++) asteroid.SeedMaterialSphere(properties.SecondMaterial.Value, (byte)properties.SecondRadius); if (properties.ThirdVeins > 0) for (i = 0; i < properties.ThirdVeins; i++) asteroid.SeedMaterialSphere(properties.ThirdMaterial.Value, (byte)properties.ThirdRadius); if (properties.FourthVeins > 0) for (i = 0; i < properties.FourthVeins; i++) asteroid.SeedMaterialSphere(properties.FourthMaterial.Value, (byte)properties.FourthRadius); if (properties.FifthVeins > 0) for (i = 0; i < properties.FifthVeins; i++) asteroid.SeedMaterialSphere(properties.FifthMaterial.Value, (byte)properties.FifthRadius); if (properties.SixthVeins > 0) for (i = 0; i < properties.SixthVeins; i++) asteroid.SeedMaterialSphere(properties.SixthMaterial.Value, (byte)properties.SixthRadius); if (properties.SeventhVeins > 0) for (i = 0; i < properties.SeventhVeins; i++) asteroid.SeedMaterialSphere(properties.SeventhMaterial.Value, (byte)properties.SeventhRadius); // Hide the surface materials up to depth of 2 cells. asteroid.ForceShellMaterial(properties.MainMaterial.Value, 2); // This recovers material assigning ability for most roids (could be something specific to indestructibleContent property?) // And not for all, apparently :( //asteroid.ForceVoxelFaceMaterial(_dataModel.BaseMaterial.DisplayName); // don't change mattype // doesn't help //asteroid.ForceIndestructibleContent(0xff); // Alt ends }
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."); }
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."); }
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, 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) { newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord); } } } } } }
public MyObjectBuilder_EntityBase BuildEntity() { // Realign both asteroids to a common grid, so voxels can be lined up. Vector3I roundedPosLeft = SelectionLeft.WorldAABB.Min.RoundToVector3I(); Vector3D offsetPosLeft = SelectionLeft.WorldAABB.Min - (Vector3D)roundedPosLeft; // Use for everything. Vector3I roundedPosRight = (SelectionRight.WorldAABB.Min - offsetPosLeft).RoundToVector3I(); Vector3D offsetPosRight = SelectionRight.WorldAABB.Min - (Vector3D)roundedPosRight; // Use for everything. // calculate smallest allowable size for contents of both. const int paddCells = 3; var minLeft = SelectionLeft.WorldAABB.Min + SelectionLeft.ContentBounds.Min - offsetPosLeft; var minRight = SelectionRight.WorldAABB.Min + SelectionRight.ContentBounds.Min - offsetPosRight; var min = Vector3D.Zero; var posOffset = Vector3D.Zero; var asteroidSize = Vector3I.Zero; switch (VoxelMergeType) { case VoxelMergeType.UnionVolumeLeftToRight: case VoxelMergeType.UnionVolumeRightToLeft: min = Vector3D.Min(minLeft, minRight) - paddCells; var max = Vector3D.Max(SelectionLeft.WorldAABB.Min + SelectionLeft.ContentBounds.Max - offsetPosLeft, SelectionRight.WorldAABB.Min + SelectionRight.ContentBounds.Max - offsetPosRight) + paddCells; posOffset = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z); var size = (max - min).RoundToVector3I(); asteroidSize = new Vector3I(size.X.RoundUpToNearest(64), size.Y.RoundUpToNearest(64), size.Z.RoundUpToNearest(64)); break; case VoxelMergeType.UnionMaterialLeftToRight: min = SelectionRight.WorldAABB.Min - offsetPosRight; posOffset = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z); asteroidSize = SelectionRight.Size; break; case VoxelMergeType.UnionMaterialRightToLeft: min = SelectionLeft.WorldAABB.Min - offsetPosLeft; posOffset = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z); asteroidSize = SelectionLeft.Size; break; case VoxelMergeType.SubtractVolumeLeftFromRight: min = SelectionRight.WorldAABB.Min - offsetPosRight; posOffset = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z); asteroidSize = SelectionRight.Size; break; case VoxelMergeType.SubtractVolumeRightFromLeft: min = SelectionLeft.WorldAABB.Min - offsetPosLeft; posOffset = new Vector3D(minLeft.X < minRight.X ? offsetPosLeft.X : offsetPosRight.X, minLeft.Y < minRight.Y ? offsetPosLeft.Y : offsetPosRight.Y, minLeft.Z < minRight.Z ? offsetPosLeft.Z : offsetPosRight.Z); asteroidSize = SelectionLeft.Size; break; } // Prepare new asteroid. var newAsteroid = new MyVoxelMap(); newAsteroid.Init(Vector3D.Zero, asteroidSize, SpaceEngineersCore.Resources.GetDefaultMaterialName()); newAsteroid.RemoveContent(); if (string.IsNullOrEmpty(MergeFileName)) MergeFileName = "merge"; var filename = MainViewModel.CreateUniqueVoxelStorageName(MergeFileName); // merge. switch (VoxelMergeType) { case VoxelMergeType.UnionVolumeLeftToRight: MergeAsteroidVolumeInto(ref newAsteroid, min, SelectionRight, SelectionLeft, minRight, minLeft); break; case VoxelMergeType.UnionVolumeRightToLeft: MergeAsteroidVolumeInto(ref newAsteroid, min, SelectionLeft, SelectionRight, minLeft, minRight); break; case VoxelMergeType.UnionMaterialLeftToRight: MergeAsteroidMaterialFrom(ref newAsteroid, min, SelectionRight, SelectionLeft, minRight, minLeft); break; case VoxelMergeType.UnionMaterialRightToLeft: MergeAsteroidMaterialFrom(ref newAsteroid, min, SelectionLeft, SelectionRight, minLeft, minRight); break; case VoxelMergeType.SubtractVolumeLeftFromRight: SubtractAsteroidVolumeFrom(ref newAsteroid, min, SelectionRight, SelectionLeft, minRight, minLeft); break; case VoxelMergeType.SubtractVolumeRightFromLeft: SubtractAsteroidVolumeFrom(ref newAsteroid, min, SelectionLeft, SelectionRight, minLeft, minRight); break; } // Generate Entity var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension); newAsteroid.Save(tempfilename); SourceFile = tempfilename; var position = min + posOffset; 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, Up = Vector3.Up } }; return entity; }
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. 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; } } if (entity is StructurePlanetModel) { var voxel = (StructurePlanetModel)entity; if (voxel.SourceVoxelFilepath != null && File.Exists(voxel.SourceVoxelFilepath)) { // Any asteroid that already exists with same name, must be removed. if (File.Exists(voxel.VoxelFilepath)) { FileSystem.DeleteFile(voxel.VoxelFilepath, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); } 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; }
/// <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 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(); }
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; }
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 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, SpaceEngineersCore.Resources.GetDefaultMaterialName(), false); asteroidCenter = asteroid.BoundingContent.Center; asteroidSize = asteroid.BoundingContent.SizeInt() + 1; // Content size } else { var asteroid = new MyVoxelMap(); asteroid.Load(stockfile, StockMaterial.Value); 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.SizeInt() + 1; // Content size } } else if (IsFileVoxel) { originalFile = SourceFile; var asteroid = new MyVoxelMap(); asteroid.Load(SourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), false); asteroidCenter = asteroid.BoundingContent.Center; asteroidSize = asteroid.BoundingContent.SizeInt() + 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) { string material; if (StockMaterial != null && StockMaterial.Value != null) material = StockMaterial.Value; else material = SpaceEngineersCore.Resources.GetDefaultMaterialName(); originalFile = string.Format("sphere_{0}_{1}_{2}{3}", material.ToLowerInvariant(), SphereRadius, SphereShellRadius, MyVoxelMap.V2FileExtension); var asteroid = MyVoxelBuilder.BuildAsteroidSphere(SphereRadius > 32, SphereRadius, material, material, SphereShellRadius != 0, SphereShellRadius); // TODO: progress bar. asteroidCenter = asteroid.BoundingContent.Center; asteroidSize = asteroid.BoundingContent.SizeInt() + 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; }
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 static Dictionary<string, long> GetMaterialAssetDetails(string filename) { var map = new MyVoxelMap(); map.Load(filename, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true); if (!map.IsValid) return new Dictionary<string, long>(); IList<byte> materialAssetList; Dictionary<byte, long> materialVoxelCells; map.CalculateMaterialCellAssets(out materialAssetList, out materialVoxelCells); return map.CountAssets(materialVoxelCells); }
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); }
public void FillAsteroid(MyVoxelMap asteroid, IMyVoxelFillProperties fillProperties) { var properties = (AsteroidByteFillProperties)fillProperties; IList<byte> baseAssets; Dictionary<byte, long> materialVoxelCells; asteroid.CalculateMaterialCellAssets(out baseAssets, out materialVoxelCells); var distribution = new List<double> { Double.NaN }; var materialSelection = new List<byte> { SpaceEngineersCore.Resources.GetMaterialIndex(properties.MainMaterial.Value) }; if (properties.SecondPercent > 0) { distribution.Add((double)properties.SecondPercent / 100); materialSelection.Add(SpaceEngineersCore.Resources.GetMaterialIndex(properties.SecondMaterial.Value)); } if (properties.ThirdPercent > 0) { distribution.Add((double)properties.ThirdPercent / 100); materialSelection.Add(SpaceEngineersCore.Resources.GetMaterialIndex(properties.ThirdMaterial.Value)); } if (properties.FourthPercent > 0) { distribution.Add((double)properties.FourthPercent / 100); materialSelection.Add(SpaceEngineersCore.Resources.GetMaterialIndex(properties.FourthMaterial.Value)); } if (properties.FifthPercent > 0) { distribution.Add((double)properties.FifthPercent / 100); materialSelection.Add(SpaceEngineersCore.Resources.GetMaterialIndex(properties.FifthMaterial.Value)); } if (properties.SixthPercent > 0) { distribution.Add((double)properties.SixthPercent / 100); materialSelection.Add(SpaceEngineersCore.Resources.GetMaterialIndex(properties.SixthMaterial.Value)); } if (properties.SeventhPercent > 0) { distribution.Add((double)properties.SeventhPercent / 100); materialSelection.Add(SpaceEngineersCore.Resources.GetMaterialIndex(properties.SeventhMaterial.Value)); } var newDistributiuon = new List<byte>(); int count; for (var i = 1; i < distribution.Count(); i++) { count = (int)Math.Floor(distribution[i] * baseAssets.Count); // Round down. for (var j = 0; j < count; j++) { newDistributiuon.Add(materialSelection[i]); } } count = baseAssets.Count - newDistributiuon.Count; for (var j = 0; j < count; j++) { newDistributiuon.Add(materialSelection[0]); } newDistributiuon.Shuffle(); asteroid.SetMaterialAssets(newDistributiuon); //asteroid.ForceVoxelFaceMaterial(_dataModel.BaseMaterial.DisplayName); }
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); } } }