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