public XmlDocument LoadSectorXml() { var filename = Path.Combine(Savepath, SpaceEngineersConsts.SandBoxCheckpointFilename); var xDoc = new XmlDocument(); try { if (ZipTools.IsGzipedFile(filename)) { // New file format is compressed. // These steps could probably be combined, but would have to use a MemoryStream, which has memory limits before it causes performance issues when chunking memory. // Using a temporary file in this situation has less performance issues as it's moved straight to disk. var tempFilename = TempfileUtil.NewFilename(); ZipTools.GZipUncompress(filename, tempFilename); xDoc.Load(tempFilename); _compressedCheckpointFormat = true; } else { // Old file format is raw XML. xDoc.Load(filename); _compressedCheckpointFormat = false; } } catch { return(null); } return(xDoc); }
public void SaveSectorXml(bool backupFile, XmlDocument xDoc) { var sectorFilename = Path.Combine(Savepath, SpaceEngineersConsts.SandBoxSectorFilename); if (backupFile) { var sectorBackupFilename = sectorFilename + ".bak"; if (File.Exists(sectorBackupFilename)) { FileSystem.DeleteFile(sectorBackupFilename, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); } File.Move(sectorFilename, sectorBackupFilename); } if (_compressedSectorFormat) { var tempFilename = TempfileUtil.NewFilename(); xDoc.Save(tempFilename); ZipTools.GZipCompress(tempFilename, sectorFilename); } else { xDoc.Save(sectorFilename); } }
public void SaveCheckPoint(bool backupFile) { var checkpointFilename = Path.Combine(Savepath, SpaceEngineersConsts.SandBoxCheckpointFilename); if (backupFile) { var checkpointBackupFilename = checkpointFilename + ".bak"; if (File.Exists(checkpointBackupFilename)) { FileSystem.DeleteFile(checkpointBackupFilename, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); } File.Move(checkpointFilename, checkpointBackupFilename); } if (_compressedCheckpointFormat) { var tempFilename = TempfileUtil.NewFilename(); SpaceEngineersApi.WriteSpaceEngineersFile(Checkpoint, tempFilename); ZipTools.GZipCompress(tempFilename, checkpointFilename); } else { SpaceEngineersApi.WriteSpaceEngineersFile(Checkpoint, checkpointFilename); } }
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 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(); }
public string GetDataPathOrDefault(string key, string defaultValue) { if (key != null && _contentDataPaths.ContainsKey(key.ToLower())) { if (_contentDataPaths[key.ToLower()].AbsolutePath != null) { return(_contentDataPaths[key.ToLower()].AbsolutePath); } if (_contentDataPaths[key.ToLower()].ZipFilePath != null) { var tempContentFile = TempfileUtil.NewFilename(Path.GetExtension(defaultValue)); try { ZipTools.ExtractZipFileToFile(_contentDataPaths[key.ToLower()].ZipFilePath, null, _contentDataPaths[key.ToLower()].ReferencePath, tempContentFile); return(tempContentFile); } catch (Exception ex) { // ignore errors, keep on trucking just like SE. // write event log warning of any files not loaded. DiagnosticsLogging.LogWarning(string.Format(Res.ExceptionState_CorruptModFile, _contentDataPaths[key.ToLower()].ZipFilePath), ex); return(defaultValue); } } } return(defaultValue); }
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(); }
private static bool TryReadSpaceEngineersFileXml <T>(string filename, out T outObject, out bool isCompressed, bool snapshot = false) where T : MyObjectBuilder_Base { isCompressed = false; if (File.Exists(filename)) { var tempFilename = filename; if (snapshot) { // Snapshot used for Report on Dedicated servers to prevent locking of the orginal file whilst reading it. tempFilename = TempfileUtil.NewFilename(); File.Copy(filename, tempFilename); } using (var fileStream = new FileStream(tempFilename, FileMode.Open, FileAccess.Read)) { var b1 = fileStream.ReadByte(); var b2 = fileStream.ReadByte(); isCompressed = (b1 == 0x1f && b2 == 0x8b); } return(MyObjectBuilderSerializer.DeserializeXML <T>(tempFilename, out outObject)); } outObject = null; return(false); }
public static bool TryReadSpaceEngineersFile <T>(string filename, out T outObject, out bool isCompressed, bool snapshot = false) where T : MyObjectBuilder_Base { string protoBufFile = filename + SpaceEngineersConsts.ProtobuffersExtension; if (File.Exists(protoBufFile)) { var tempFilename = protoBufFile; if (snapshot) { // Snapshot used for Report on Dedicated servers to prevent locking of the orginal file whilst reading it. tempFilename = TempfileUtil.NewFilename(); File.Copy(protoBufFile, tempFilename); } using (var fileStream = new FileStream(tempFilename, FileMode.Open, FileAccess.Read)) { var b1 = fileStream.ReadByte(); var b2 = fileStream.ReadByte(); isCompressed = (b1 == 0x1f && b2 == 0x8b); } bool retCode = MyObjectBuilderSerializer.DeserializePB <T>(tempFilename, out outObject); if (retCode && outObject != null) { return(true); } return(TryReadSpaceEngineersFileXml(filename, out outObject, out isCompressed, snapshot)); } return(TryReadSpaceEngineersFileXml(filename, out outObject, out isCompressed, snapshot)); }
public string SaveTemporarySandbox() { IsBusy = true; var tempFilename = TempfileUtil.NewFilename(".xml"); SpaceEngineersApi.WriteSpaceEngineersFile <MyObjectBuilder_Sector>(ActiveWorld.SectorData, tempFilename); IsBusy = false; return(tempFilename); }
public void GenerateTempFiles() { for (var i = 0; i < 10; i++) { var file1 = TempfileUtil.NewFilename(null); File.WriteAllBytes(file1, new byte[] { 0x00, 0x01, 0x02 }); var file2 = TempfileUtil.NewFilename(".txt"); File.WriteAllText(file2, "blah blah"); } TempfileUtil.Dispose(); }
private MyObjectBuilder_VoxelMap BuildAsteroidEntity() { var filenamepart = Path.GetFileNameWithoutExtension(Filename); var filename = MainViewModel.CreateUniqueVoxelStorageName(filenamepart + MyVoxelMap.V2FileExtension); Position = Position.RoundOff(1.0); Forward = Forward.RoundToAxis(); Up = Up.RoundToAxis(); var entity = new MyObjectBuilder_VoxelMap(Position.ToVector3(), filename) { EntityId = SpaceEngineersApi.GenerateEntityId(IDType.ASTEROID), PersistentFlags = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene, StorageName = Path.GetFileNameWithoutExtension(filename) }; double multiplier; if (IsMultipleScale) { multiplier = MultipleScale; } else { multiplier = MaxLengthScale / Math.Max(Math.Max(OriginalModelSize.Height, OriginalModelSize.Width), OriginalModelSize.Depth); } var transform = MeshHelper.TransformVector(new Vector3D(0, 0, 0), 0, 0, 0); SourceFile = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension); var baseMaterial = SpaceEngineersCore.Resources.VoxelMaterialDefinitions.FirstOrDefault(m => m.IsRare == false) ?? SpaceEngineersCore.Resources.VoxelMaterialDefinitions.FirstOrDefault(); var voxelMap = MyVoxelBuilder.BuildAsteroidFromModel(true, Filename, OutsideStockMaterial.MaterialIndex.Value, baseMaterial.Index, InsideStockMaterial.Value != null, InsideStockMaterial.MaterialIndex, ModelTraceVoxel.ThinSmoothed, multiplier, transform, MainViewModel.ResetProgress, MainViewModel.IncrementProgress); voxelMap.Save(SourceFile); MainViewModel.ClearProgress(); entity.PositionAndOrientation = new MyPositionAndOrientation { Position = Position.ToVector3D(), Forward = Forward.ToVector3(), Up = Up.ToVector3() }; IsValidModel = voxelMap.BoundingContent.Size.Volume() > 0; return(entity); }
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; }
/// <summary> /// Regenerate the Planet voxel. /// </summary> /// <param name="seed"></param> /// <param name="radius"></param> public void RegeneratePlanet(int seed, float radius) { MyPlanetStorageProvider provider = new MyPlanetStorageProvider(); MyPlanetGeneratorDefinition planetDefinition = MyDefinitionManager.Static.GetDefinition <MyPlanetGeneratorDefinition>(MyStringHash.GetOrCompute(Planet.PlanetGenerator)); provider.Init(seed, planetDefinition, radius); float minHillSize = provider.Radius * planetDefinition.HillParams.Min; float maxHillSize = provider.Radius * planetDefinition.HillParams.Max; float atmosphereRadius = planetDefinition.AtmosphereSettings.HasValue && planetDefinition.AtmosphereSettings.Value.Scale > 1f ? 1 + planetDefinition.AtmosphereSettings.Value.Scale : 1.75f; atmosphereRadius *= provider.Radius; Planet.Seed = seed; Planet.Radius = radius; Planet.AtmosphereRadius = atmosphereRadius; Planet.MinimumSurfaceRadius = radius + minHillSize; Planet.MaximumHillRadius = radius + maxHillSize; provider.Init(Planet.Seed, planetDefinition, radius); var asteroid = new MyVoxelMap(); asteroid.Storage = new MyOctreeStorage(provider, provider.StorageSize); var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension); asteroid.Save(tempfilename); //SourceVoxelFilepath = tempfilename; UpdateNewSource(asteroid, tempfilename); RaisePropertyChanged(() => Seed); RaisePropertyChanged(() => Radius); RaisePropertyChanged(() => AtmosphereRadius); RaisePropertyChanged(() => MinimumSurfaceRadius); RaisePropertyChanged(() => MaximumHillRadius); //Size = _voxelMap.Size; //_contentCenter = _voxelMap.ContentCenter; //IsValid = _voxelMap.IsValid; //RaisePropertyChanged(() => Size); //RaisePropertyChanged(() => 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)); }
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 SaveSector(bool backupFile) { var sectorFilename = Path.Combine(Savepath, SpaceEngineersConsts.SandBoxSectorFilename); if (backupFile) { // xml sector file. (it may or may not be compressed) var sectorBackupFilename = sectorFilename + ".bak"; if (File.Exists(sectorBackupFilename)) { FileSystem.DeleteFile(sectorBackupFilename, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); } File.Move(sectorFilename, sectorBackupFilename); // binary sector file. (it may or may not be compressed) sectorBackupFilename = sectorFilename + SpaceEngineersConsts.ProtobuffersExtension + ".bak"; if (File.Exists(sectorBackupFilename)) { FileSystem.DeleteFile(sectorBackupFilename, UIOption.OnlyErrorDialogs, RecycleOption.SendToRecycleBin); } // The protoBuf .sbsPB may not exist in older save games. if (File.Exists(sectorFilename + SpaceEngineersConsts.ProtobuffersExtension)) { File.Move(sectorFilename + SpaceEngineersConsts.ProtobuffersExtension, sectorBackupFilename); } } if (_compressedSectorFormat) { var tempFilename = TempfileUtil.NewFilename(); SpaceEngineersApi.WriteSpaceEngineersFile(SectorData, tempFilename); ZipTools.GZipCompress(tempFilename, sectorFilename); } else { SpaceEngineersApi.WriteSpaceEngineersFile(SectorData, sectorFilename); } SpaceEngineersApi.WriteSpaceEngineersFilePB(SectorData, sectorFilename + SpaceEngineersConsts.ProtobuffersExtension, _compressedSectorFormat); }
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(); }
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(); }
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); }
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); }
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); }
private bool BuildEntity() { var filenamepart = Path.GetFileNameWithoutExtension(Filename); var filename = MainViewModel.CreateUniqueVoxelStorageName(filenamepart + MyVoxelMap.V2FileExtension); double multiplier; if (IsMultipleScale) { multiplier = MultipleScale; } else { multiplier = MaxLengthScale / Math.Max(Math.Max(OriginalModelSize.Height, OriginalModelSize.Width), OriginalModelSize.Depth); } var scale = new ScaleTransform3D(multiplier, multiplier, multiplier); var rotateTransform = MeshHelper.TransformVector(new System.Windows.Media.Media3D.Vector3D(0, 0, 0), -RotateRoll, RotateYaw - 90, RotatePitch + 90); SourceFile = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension); var model = MeshHelper.Load(Filename, ignoreErrors: true); var meshes = new List <MyVoxelRayTracer.MyMeshModel>(); var geometeries = new List <MeshGeometry3D>(); foreach (var model3D in model.Children) { var gm = (GeometryModel3D)model3D; var geometry = gm.Geometry as MeshGeometry3D; if (geometry != null) { geometeries.Add(geometry); } } meshes.Add(new MyVoxelRayTracer.MyMeshModel(geometeries.ToArray(), InsideStockMaterial.MaterialIndex, InsideStockMaterial.MaterialIndex)); #region handle dialogs and process the conversion var doCancel = false; var progressModel = new ProgressCancelModel { Title = Res.WnProgressTitle, SubTitle = Res.WnProgressTitle, DialogText = Res.WnProgressTxtTimeRemain + " " + Res.WnProgressTxtTimeCalculating }; var progressVm = new ProgressCancelViewModel(this, progressModel); progressVm.CloseRequested += delegate(object sender, EventArgs e) { doCancel = true; }; var cancelFunc = (Func <bool>) delegate { return(doCancel); }; var completedAction = (Action) delegate { progressVm.Close(); }; MyVoxelMap voxelMap = null; var action = (Action) delegate { voxelMap = MyVoxelRayTracer.ReadModelAsteroidVolmetic(model, meshes, scale, rotateTransform, TraceType, TraceCount, TraceDirection, progressModel.ResetProgress, progressModel.IncrementProgress, cancelFunc, completedAction); }; if (RunInLowPrioity) { System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.Idle; } _dialogService.ShowDialog <WindowProgressCancel>(this, progressVm, action); if (RunInLowPrioity) { System.Diagnostics.Process.GetCurrentProcess().PriorityClass = System.Diagnostics.ProcessPriorityClass.Normal; } #endregion if (doCancel || voxelMap == null) { IsValidEntity = false; NewEntity = null; } else { voxelMap.ForceShellMaterial(OutsideStockMaterial.Value, (byte)OutsideMaterialDepth); voxelMap.Save(SourceFile); var position = VRageMath.Vector3D.Zero; var forward = Vector3.Forward; var up = Vector3.Up; if (IsAbsolutePosition) { position = Position.ToVector3(); } else if (IsInfrontofPlayer) { // Figure out where the Character is facing, and plant the new construct centered in front of the Character, but "BuildDistance" units out in front. var lookVector = (VRageMath.Vector3D)_dataModel.CharacterPosition.Forward.ToVector3(); lookVector.Normalize(); BoundingBoxD content = voxelMap.BoundingContent.ToBoundingBoxD(); VRageMath.Vector3D?boundingIntersectPoint = content.IntersectsRayAt(content.Center, -lookVector * 5000d); if (!boundingIntersectPoint.HasValue) { boundingIntersectPoint = content.Center; } var distance = VRageMath.Vector3D.Distance(boundingIntersectPoint.Value, content.Center) + (float)BuildDistance; VRageMath.Vector3D vector = lookVector * distance; position = VRageMath.Vector3D.Add(_dataModel.CharacterPosition.Position, vector) - content.Center; } var entity = new MyObjectBuilder_VoxelMap(position, filename) { EntityId = SpaceEngineersApi.GenerateEntityId(IDType.ASTEROID), PersistentFlags = MyPersistentEntityFlags2.CastShadows | MyPersistentEntityFlags2.InScene, StorageName = Path.GetFileNameWithoutExtension(filename) }; entity.PositionAndOrientation = new MyPositionAndOrientation { Position = position, Forward = forward, Up = up }; IsValidEntity = voxelMap.BoundingContent.Size.Volume() > 0; NewEntity = entity; if (BeepWhenFinished) { System.Media.SystemSounds.Asterisk.Play(); } } return(!doCancel); }
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; // Force a calculation of the ContentBounds, as multi select in the ListView doesn't necessarily make it happen, or make it happen fast enough. SelectionLeft.LoadDetailsSync(); SelectionRight.LoadDetailsSync(); var minLeft = SelectionLeft.WorldAABB.Min + SelectionLeft.InflatedContentBounds.Min - offsetPosLeft; var minRight = SelectionRight.WorldAABB.Min + SelectionRight.InflatedContentBounds.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.InflatedContentBounds.Max - offsetPosLeft, SelectionRight.WorldAABB.Min + SelectionRight.InflatedContentBounds.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 = MyVoxelBuilder.CalcRequiredSize(size); 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.Create(asteroidSize, SpaceEngineersCore.Resources.GetDefaultMaterialIndex()); 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); }
/// <returns>True if it sucessfully deserialized the file.</returns> public static bool TryReadSpaceEngineersFile <T>(string filename, out T outObject, out bool isCompressed, out string errorInformation, bool snapshot = false, bool specificExtension = false) where T : MyObjectBuilder_Base { string protoBufFile = null; if (specificExtension) { if ((Path.GetExtension(filename) ?? string.Empty).EndsWith(SpaceEngineersConsts.ProtobuffersExtension, StringComparison.OrdinalIgnoreCase)) { protoBufFile = filename; } } else { if ((Path.GetExtension(filename) ?? string.Empty).EndsWith(SpaceEngineersConsts.ProtobuffersExtension, StringComparison.OrdinalIgnoreCase)) { protoBufFile = filename; } else { protoBufFile = filename + SpaceEngineersConsts.ProtobuffersExtension; } } if (protoBufFile != null && File.Exists(protoBufFile)) { var tempFilename = protoBufFile; if (snapshot) { // Snapshot used for Report on Dedicated servers to prevent locking of the orginal file whilst reading it. tempFilename = TempfileUtil.NewFilename(); File.Copy(protoBufFile, tempFilename); } using (var fileStream = new FileStream(tempFilename, FileMode.Open, FileAccess.Read)) { var b1 = fileStream.ReadByte(); var b2 = fileStream.ReadByte(); isCompressed = (b1 == 0x1f && b2 == 0x8b); } bool retCode; try { // A failure to load here, will only mean it falls back to try and read the xml file instead. // So a file corruption could easily have been covered up. retCode = MyObjectBuilderSerializer.DeserializePB <T>(tempFilename, out outObject); } catch (InvalidCastException ex) { outObject = null; errorInformation = string.Format(Res.ErrorLoadFileError, filename, ex.AllMessages()); return(false); } if (retCode && outObject != null) { errorInformation = null; return(true); } return(TryReadSpaceEngineersFileXml(filename, out outObject, out isCompressed, out errorInformation, snapshot)); } return(TryReadSpaceEngineersFileXml(filename, out outObject, out isCompressed, out errorInformation, snapshot)); }
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(Quaternion quaternion) { var sourceFile = SourceVoxelFilepath ?? VoxelFilepath; var asteroid = new MyVoxelMap(); asteroid.Load(sourceFile); var newAsteroid = new MyVoxelMap(); var newSize = asteroid.Size; newAsteroid.Create(newSize, SpaceEngineersCore.Resources.GetDefaultMaterialIndex()); Vector3I block; var halfSize = asteroid.Storage.Size / 2; // Don't use anything smaller than 64 for smaller voxels, as it trashes the cache. var cacheSize = new Vector3I(64); var halfCacheSize = new Vector3I(32); // This should only be used for the Transform, not the cache. // 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) { #region source voxel var cache = new MyStorageData(); cache.Resize(cacheSize); // LOD1 is not detailed enough for content information on asteroids. asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1); #endregion #region target Voxel // the block is a cubiod. The entire space needs to rotate, to be able to gauge where the new block position starts from. var newBlockMin = Vector3I.Transform(block - halfSize, quaternion) + halfSize; var newBlockMax = Vector3I.Transform(block + 64 - halfSize, quaternion) + halfSize; var newBlock = Vector3I.Min(newBlockMin, newBlockMax); var newCache = new MyStorageData(); newCache.Resize(cacheSize); newAsteroid.Storage.ReadRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, newBlock, newBlock + cacheSize - 1); #endregion 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) { byte volume = cache.Content(ref p); byte cellMaterial = cache.Material(ref p); var newP1 = Vector3I.Transform(p - halfCacheSize, quaternion) + halfCacheSize; var newP2 = Vector3I.Transform(p + 1 - halfCacheSize, quaternion) + halfCacheSize; var newP = Vector3I.Min(newP1, newP2); newCache.Content(ref newP, volume); newCache.Material(ref newP, cellMaterial); changed = true; } } } if (changed) { newAsteroid.Storage.WriteRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1); } } } } var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension); newAsteroid.Save(tempfilename); SourceVoxelFilepath = tempfilename; }