예제 #1
0
        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;
        }
        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.Value, InsideStockMaterial.Value));

            #region handle dialogs and process the conversion

            var doCancel = false;

            var progressModel = new ProgressCancelModel { Title = "Processing...", SubTitle = "Processing...", DialogText = "Time remaining: Calculating..." };
            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();
                    VRageMath.Vector3D? boundingIntersectPoint = voxelMap.BoundingContent.IntersectsRayAt(voxelMap.BoundingContent.Center, -lookVector * 5000d);

                    if (!boundingIntersectPoint.HasValue)
                    {
                        boundingIntersectPoint = voxelMap.BoundingContent.Center;
                    }

                    var distance = VRageMath.Vector3D.Distance(boundingIntersectPoint.Value, voxelMap.BoundingContent.Center) + (float)BuildDistance;
                    VRageMath.Vector3D vector = lookVector * distance;
                    position = VRageMath.Vector3D.Add(_dataModel.CharacterPosition.Position, vector) - voxelMap.BoundingContent.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 > 0f;

                NewEntity = entity;

                if (BeepWhenFinished)
                    System.Media.SystemSounds.Asterisk.Play();
            }

            return !doCancel;
        }
예제 #3
0
        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 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();
        }
예제 #5
0
        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.Value, baseMaterial.Id.SubtypeName, InsideStockMaterial.Value != null, InsideStockMaterial.Value, 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 > 0f;

            return entity;
        }