private void MergeAsteroidMaterialFrom(ref MyVoxelMap newAsteroid, Vector3 min, StructureVoxelModel modelPrimary, StructureVoxelModel modelSecondary, Vector3 minPrimary, Vector3 minSecondary) { var filenameSecondary = modelSecondary.SourceVoxelFilepath ?? modelSecondary.VoxelFilepath; var filenamePrimary = modelPrimary.SourceVoxelFilepath ?? modelPrimary.VoxelFilepath; Vector3I block; Vector3I newBlock; Vector3I cacheSize; var asteroid = new MyVoxelMap(); asteroid.Load(filenamePrimary); BoundingBoxI content = modelPrimary.InflatedContentBounds; for (block.Z = content.Min.Z; block.Z <= content.Max.Z; block.Z += 64) { for (block.Y = content.Min.Y; block.Y <= content.Max.Y; block.Y += 64) { for (block.X = content.Min.X; block.X <= content.Max.X; block.X += 64) { var cache = new MyStorageData(); cacheSize = new Vector3I(MathHelper.Min(content.Max.X, block.X + 63) - block.X + 1, MathHelper.Min(content.Max.Y, block.Y + 63) - block.Y + 1, MathHelper.Min(content.Max.Z, block.Z + 63) - block.Z + 1); cache.Resize(cacheSize); asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1); newBlock = ((minPrimary - min) + (Vector3D)(block - content.Min)).RoundToVector3I(); newAsteroid.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1); } } } asteroid.Load(filenameSecondary); content = modelSecondary.InflatedContentBounds; for (block.Z = content.Min.Z; block.Z <= content.Max.Z; block.Z += 64) { for (block.Y = content.Min.Y; block.Y <= content.Max.Y; block.Y += 64) { for (block.X = content.Min.X; block.X <= content.Max.X; block.X += 64) { var cache = new MyStorageData(); cacheSize = new Vector3I(MathHelper.Min(content.Max.X, block.X + 63) - block.X + 1, MathHelper.Min(content.Max.Y, block.Y + 63) - block.Y + 1, MathHelper.Min(content.Max.Z, block.Z + 63) - block.Z + 1); cache.Resize(cacheSize); asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1); newBlock = ((minSecondary - min) + (Vector3D)(block - content.Min)).RoundToVector3I(); var newCache = new MyStorageData(); newCache.Resize(cacheSize); newAsteroid.Storage.ReadRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, newBlock, newBlock + cacheSize - 1); Vector3I p; for (p.Z = 0; p.Z < cacheSize.Z; ++p.Z) { for (p.Y = 0; p.Y < cacheSize.Y; ++p.Y) { for (p.X = 0; p.X < cacheSize.X; ++p.X) { byte volume = cache.Content(ref p); byte material = cache.Material(ref p); if (volume > 0) { newCache.Material(ref p, material); } } } } newAsteroid.Storage.WriteRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1); } } } }
private void MergeAsteroidVolumeInto(ref MyVoxelMap newAsteroid, Vector3D min, StructureVoxelModel modelPrimary, StructureVoxelModel modelSecondary, Vector3D minPrimary, Vector3D minSecondary) { var filenameSecondary = modelSecondary.SourceVoxelFilepath ?? modelSecondary.VoxelFilepath; var filenamePrimary = modelPrimary.SourceVoxelFilepath ?? modelPrimary.VoxelFilepath; Vector3I block; Vector3I newBlock; Vector3I cacheSize; var asteroid = new MyVoxelMap(); asteroid.Load(filenameSecondary); BoundingBoxI content = modelSecondary.InflatedContentBounds; for (block.Z = content.Min.Z; block.Z <= content.Max.Z; block.Z += 64) { for (block.Y = content.Min.Y; block.Y <= content.Max.Y; block.Y += 64) { for (block.X = content.Min.X; block.X <= content.Max.X; block.X += 64) { var cache = new MyStorageData(); cacheSize = new Vector3I(MathHelper.Min(content.Max.X, block.X + 63) - block.X + 1, MathHelper.Min(content.Max.Y, block.Y + 63) - block.Y + 1, MathHelper.Min(content.Max.Z, block.Z + 63) - block.Z + 1); cache.Resize(cacheSize); asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1); newBlock = ((minSecondary - min) + (Vector3D)(block - content.Min)).RoundToVector3I(); newAsteroid.Storage.WriteRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1); } } } asteroid.Load(filenamePrimary); content = modelPrimary.InflatedContentBounds; for (block.Z = content.Min.Z; block.Z <= content.Max.Z; block.Z += 64) { for (block.Y = content.Min.Y; block.Y <= content.Max.Y; block.Y += 64) { for (block.X = content.Min.X; block.X <= content.Max.X; block.X += 64) { var cache = new MyStorageData(); cacheSize = new Vector3I(MathHelper.Min(content.Max.X, block.X + 63) - block.X + 1, MathHelper.Min(content.Max.Y, block.Y + 63) - block.Y + 1, MathHelper.Min(content.Max.Z, block.Z + 63) - block.Z + 1); cache.Resize(cacheSize); asteroid.Storage.ReadRange(cache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, block + cacheSize - 1); newBlock = ((minPrimary - min) + (Vector3D)(block - content.Min)).RoundToVector3I(); var newCache = new MyStorageData(); newCache.Resize(cacheSize); newAsteroid.Storage.ReadRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, newBlock, newBlock + cacheSize - 1); Vector3I p; for (p.Z = 0; p.Z < cacheSize.Z; ++p.Z) { for (p.Y = 0; p.Y < cacheSize.Y; ++p.Y) { for (p.X = 0; p.X < cacheSize.X; ++p.X) { byte volume = cache.Content(ref p); byte material = cache.Material(ref p); if (volume > 0) { byte existingVolume = newCache.Content(ref p); if (volume > existingVolume) { newCache.Content(ref p, volume); } // Overwrites secondary material with primary. newCache.Material(ref p, material); } else { // try to find cover material. Vector3I[] points = CreateTestPoints(p, cacheSize - 1); for (int i = 0; i < points.Length; i++) { byte testVolume = cache.Content(ref points[i]); if (testVolume > 0) { material = cache.Material(ref points[i]); newCache.Material(ref p, material); break; } } } } } } newAsteroid.Storage.WriteRange(newCache, MyStorageDataTypeFlags.ContentAndMaterial, newBlock, newBlock + cacheSize - 1); } } } }
private void SubtractAsteroidVolumeFrom(ref MyVoxelMap newAsteroid, Vector3D min, StructureVoxelModel modelPrimary, StructureVoxelModel modelSecondary, Vector3D minPrimary, Vector3D minSecondary) { var filenameSecondary = modelSecondary.SourceVoxelFilepath ?? modelSecondary.VoxelFilepath; var filenamePrimary = modelPrimary.SourceVoxelFilepath ?? modelPrimary.VoxelFilepath; Vector3I coords; var asteroid = new MyVoxelMap(); asteroid.Load(filenamePrimary); for (coords.Z = (int)modelPrimary.ContentBounds.Min.Z; coords.Z <= modelPrimary.ContentBounds.Max.Z; coords.Z++) { for (coords.Y = (int)modelPrimary.ContentBounds.Min.Y; coords.Y <= modelPrimary.ContentBounds.Max.Y; coords.Y++) { for (coords.X = (int)modelPrimary.ContentBounds.Min.X; coords.X <= modelPrimary.ContentBounds.Max.X; coords.X++) { byte volume; string cellMaterial; asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume); var newCoord = ((minPrimary - min) + ((Vector3D)coords - modelPrimary.ContentBounds.Min)).RoundToVector3I(); newAsteroid.SetVoxelContent(volume, ref newCoord); newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord); } } } asteroid.Load(filenameSecondary); for (coords.Z = (int)modelSecondary.ContentBounds.Min.Z; coords.Z <= modelSecondary.ContentBounds.Max.Z; coords.Z++) { for (coords.Y = (int)modelSecondary.ContentBounds.Min.Y; coords.Y <= modelSecondary.ContentBounds.Max.Y; coords.Y++) { for (coords.X = (int)modelSecondary.ContentBounds.Min.X; coords.X <= modelSecondary.ContentBounds.Max.X; coords.X++) { var newCoord = ((minSecondary - min) + ((Vector3D)coords - modelSecondary.ContentBounds.Min)).RoundToVector3I(); if (Vector3I.BoxContains(Vector3I.Zero, modelPrimary.Size - 1, newCoord)) { byte volume; string cellMaterial; asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume); if (volume > 0) { byte existingVolume; string existingCellMaterial; newAsteroid.GetVoxelMaterialContent(ref newCoord, out existingCellMaterial, out existingVolume); if (existingVolume - volume < 0) { volume = 0; } else { volume = (byte)(existingVolume - volume); } newAsteroid.SetVoxelContent(volume, ref newCoord); } } } } } }
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); } } } } } }
private void MergeAsteroidVolumeInto(ref MyVoxelMap newAsteroid, Vector3D min, StructureVoxelModel modelPrimary, StructureVoxelModel modelSecondary, Vector3D minPrimary, Vector3D minSecondary) { var filenameSecondary = modelSecondary.SourceVoxelFilepath ?? modelSecondary.VoxelFilepath; var filenamePrimary = modelPrimary.SourceVoxelFilepath ?? modelPrimary.VoxelFilepath; Vector3I coords; var asteroid = new MyVoxelMap(); asteroid.Load(filenameSecondary); for (coords.Z = (int)modelSecondary.ContentBounds.Min.Z; coords.Z <= modelSecondary.ContentBounds.Max.Z; coords.Z++) { for (coords.Y = (int)modelSecondary.ContentBounds.Min.Y; coords.Y <= modelSecondary.ContentBounds.Max.Y; coords.Y++) { for (coords.X = (int)modelSecondary.ContentBounds.Min.X; coords.X <= modelSecondary.ContentBounds.Max.X; coords.X++) { byte volume; string cellMaterial; asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume); var newCoord = ((minSecondary - min) + ((Vector3D)coords - modelSecondary.ContentBounds.Min)).RoundToVector3I(); newAsteroid.SetVoxelContent(volume, ref newCoord); newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord); } } } asteroid.Load(filenamePrimary); for (coords.Z = (int)modelPrimary.ContentBounds.Min.Z; coords.Z <= modelPrimary.ContentBounds.Max.Z; coords.Z++) { for (coords.Y = (int)modelPrimary.ContentBounds.Min.Y; coords.Y <= modelPrimary.ContentBounds.Max.Y; coords.Y++) { for (coords.X = (int)modelPrimary.ContentBounds.Min.X; coords.X <= modelPrimary.ContentBounds.Max.X; coords.X++) { byte volume; string cellMaterial; asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume); if (volume > 0) { byte existingVolume; string existingCellMaterial; var newCoord = ((minPrimary - min) + ((Vector3D)coords - modelPrimary.ContentBounds.Min)).RoundToVector3I(); newAsteroid.GetVoxelMaterialContent(ref newCoord, out existingCellMaterial, out existingVolume); if (volume > existingVolume) { newAsteroid.SetVoxelContent(volume, ref newCoord); } // Overwrites secondary material with primary. newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord); } } } } }