Ejemplo n.º 1
0
        public override void InitializeAsync()
        {
            _asyncWorker = new BackgroundWorker {
                WorkerSupportsCancellation = true
            };
            _asyncWorker.DoWork += delegate
            {
                if (!_isLoadingAsync)
                {
                    _isLoadingAsync = true;

                    IsBusy = true;


                    // TODO: planet details

                    _voxelMap.RefreshAssets();
                    _contentCenter = _voxelMap.ContentCenter;
                    Center         = new Vector3D(_contentCenter.X + 0.5f + PositionX, _contentCenter.Y + 0.5f + PositionY, _contentCenter.Z + 0.5f + PositionZ);

                    IsBusy = false;

                    _isLoadingAsync = false;
                }
            };

            _asyncWorker.RunWorkerAsync();
        }
Ejemplo n.º 2
0
        public void LoadDetailsSync()
        {
            ReadVoxelDetails(SourceVoxelFilepath ?? VoxelFilepath);

            if (_voxelMap != null && (MaterialAssets == null || MaterialAssets.Count == 0))
            {
                Dictionary <string, long> details = _voxelMap.RefreshAssets();
                _contentBounds         = _voxelMap.BoundingContent;
                _inflatedContentBounds = _voxelMap.InflatedBoundingContent;
                _voxCells = _voxelMap.VoxCells;
                Center    = new Vector3D(_voxelMap.ContentCenter.X + 0.5f + PositionX, _voxelMap.ContentCenter.Y + 0.5f + PositionY, _voxelMap.ContentCenter.Z + 0.5f + PositionZ);

                var sum  = details.Values.ToList().Sum();
                var list = new List <VoxelMaterialAssetModel>();

                foreach (var kvp in details)
                {
                    list.Add(new VoxelMaterialAssetModel {
                        MaterialName = kvp.Key, Volume = (double)kvp.Value / 255, Percent = (double)kvp.Value / (double)sum
                    });
                }

                MaterialAssets = list;
            }
        }
Ejemplo n.º 3
0
        public override void InitializeAsync()
        {
            _asyncWorker = new BackgroundWorker {
                WorkerSupportsCancellation = true
            };
            _asyncWorker.DoWork += delegate
            {
                if (!_isLoadingAsync && (MaterialAssets == null || MaterialAssets.Count == 0))
                {
                    _isLoadingAsync = true;

                    IsBusy = true;

                    Dictionary <string, long> details;

                    details        = _voxelMap.RefreshAssets();
                    _contentBounds = _voxelMap.BoundingContent;
                    _voxCells      = _voxelMap.VoxCells;
                    Center         = new Vector3D(_contentBounds.Center.X + 0.5f + PositionX, _contentBounds.Center.Y + 0.5f + PositionY, _contentBounds.Center.Z + 0.5f + PositionZ);

                    var sum  = details.Values.ToList().Sum();
                    var list = new List <VoxelMaterialAssetModel>();

                    foreach (var kvp in details)
                    {
                        list.Add(new VoxelMaterialAssetModel {
                            MaterialName = kvp.Key, Volume = (double)kvp.Value / 255, Percent = (double)kvp.Value / (double)sum
                        });
                    }

                    MaterialAssets = list;
                    IsBusy         = false;

                    _isLoadingAsync = false;
                }
            };
            _asyncWorker.RunWorkerCompleted += delegate
            {
                RaisePropertyChanged(() => Size);
                RaisePropertyChanged(() => ContentSize);
                RaisePropertyChanged(() => ContentBounds);
                RaisePropertyChanged(() => Center);
                RaisePropertyChanged(() => VoxCells);
                RaisePropertyChanged(() => Volume);
            };

            _asyncWorker.RunWorkerAsync();
        }
Ejemplo n.º 4
0
        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;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Processes an asteroid Voxel using function callbacks.
        /// This allows for muti-threading, and generating content via algorithims.
        /// </summary>
        public static void ProcessAsteroid(MyVoxelMap voxelMap, bool multiThread, byte materialIndex, Action <MyVoxelBuilderArgs> func, bool readWrite = true)
        {
            long    counterTotal = (long)voxelMap.Size.X * voxelMap.Size.Y * voxelMap.Size.Z;
            long    counter      = 0;
            decimal progress     = 0;
            var     timer        = new Stopwatch();

            Debug.Write($"Building Asteroid : {progress:000},");
            Console.Write($"Building Asteroid : {progress:000},");
            Exception threadException = null;

            timer.Start();

            if (!multiThread)
            {
                #region single thread processing

                Vector3I  block;
                const int cellSize  = 64;
                var       cacheSize = Vector3I.Min(new Vector3I(cellSize), voxelMap.Storage.Size);
                var       oldCache  = new MyStorageData();

                // read the asteroid in chunks of 64 to avoid the Arithmetic overflow issue.
                for (block.Z = 0; block.Z < voxelMap.Storage.Size.Z; block.Z += cellSize)
                {
                    for (block.Y = 0; block.Y < voxelMap.Storage.Size.Y; block.Y += cellSize)
                    {
                        for (block.X = 0; block.X < voxelMap.Storage.Size.X; block.X += cellSize)
                        {
                            oldCache.Resize(cacheSize);
                            // LOD0 is required to read if you intend to write back to the voxel storage.
                            Vector3I maxRange = block + cacheSize - 1;
                            voxelMap.Storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, maxRange);

                            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)
                                    {
                                        var coords = block + p;

                                        byte volume       = 0x0;
                                        byte cellMaterial = materialIndex;

                                        if (readWrite)
                                        {
                                            volume       = oldCache.Content(ref p);
                                            cellMaterial = oldCache.Material(ref p);
                                        }

                                        var args = new MyVoxelBuilderArgs(voxelMap.Size, coords, cellMaterial, volume);

                                        try
                                        {
                                            func(args);
                                        }
                                        catch (Exception ex)
                                        {
                                            threadException = ex;
                                            break;
                                        }

                                        if (args.Volume != volume)
                                        {
                                            oldCache.Set(MyStorageDataTypeEnum.Content, ref p, args.Volume);
                                        }

                                        if (args.MaterialIndex != cellMaterial)
                                        {
                                            oldCache.Set(MyStorageDataTypeEnum.Material, ref p, args.MaterialIndex);
                                        }

                                        counter++;
                                        var prog = Math.Floor(counter / (decimal)counterTotal * 100);
                                        if (prog != progress)
                                        {
                                            progress = prog;
                                            Debug.Write($"{progress:000},");
                                        }
                                    }
                                }
                            }

                            voxelMap.Storage.WriteRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, block, maxRange);
                        }
                    }
                }

                #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.

                Vector3I  block;
                const int cellSize      = 64;
                var       cacheSize     = Vector3I.Min(new Vector3I(cellSize), voxelMap.Storage.Size);
                long      threadCounter = counterTotal / cellSize / cellSize / cellSize;

                for (block.Z = 0; block.Z < voxelMap.Storage.Size.Z; block.Z += cellSize)
                {
                    for (block.Y = 0; block.Y < voxelMap.Storage.Size.Y; block.Y += cellSize)
                    {
                        for (block.X = 0; block.X < voxelMap.Storage.Size.X; block.X += cellSize)
                        {
                            var oldCache = new MyStorageData();
                            oldCache.Resize(cacheSize);
                            // LOD1 is not detailed enough for content information on asteroids.
                            Vector3I maxRange = block + cacheSize - 1;
                            voxelMap.Storage.ReadRange(oldCache, MyStorageDataTypeFlags.ContentAndMaterial, 0, block, maxRange);

                            var task = new Task(obj =>
                            {
                                var bgw = (MyVoxelTaskWorker)obj;

                                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)
                                        {
                                            var coords = bgw.BaseCoords + p;

                                            byte volume       = 0x0;
                                            byte cellMaterial = materialIndex;

                                            if (readWrite)
                                            {
                                                // read the existing material and volume into the arguments before passing the to args for processing.
                                                volume       = bgw.VoxelCache.Content(ref p);
                                                cellMaterial = bgw.VoxelCache.Material(ref p);
                                            }

                                            var args = new MyVoxelBuilderArgs(voxelMap.Size, coords, cellMaterial, volume);

                                            try
                                            {
                                                func(args);
                                            }
                                            catch (Exception ex)
                                            {
                                                threadException = ex;
                                                threadCounter   = 0;
                                                break;
                                            }

                                            if (args.Volume != volume)
                                            {
                                                bgw.VoxelCache.Set(MyStorageDataTypeEnum.Content, ref p, args.Volume);
                                            }

                                            if (args.MaterialIndex != cellMaterial)
                                            {
                                                bgw.VoxelCache.Set(MyStorageDataTypeEnum.Material, ref p, args.MaterialIndex);
                                            }

                                            counter++;
                                            var prog = Math.Floor(counter / (decimal)counterTotal * 100);
                                            if (prog != progress)
                                            {
                                                progress = prog;
                                                Debug.Write($"{progress:000},");
                                            }
                                        }
                                    }
                                }

                                lock (Locker)
                                {
                                    var b       = bgw.BaseCoords;
                                    Vector3I mr = bgw.BaseCoords + cacheSize - 1;
                                    voxelMap.Storage.WriteRange(bgw.VoxelCache, MyStorageDataTypeFlags.ContentAndMaterial, b, mr);

                                    counter += (long)cellSize * cellSize * cellSize;
                                    var prog = Math.Floor(counter / (decimal)counterTotal * 100);
                                    if (prog != progress)
                                    {
                                        progress = prog;
                                        Debug.Write($"{progress:000},");
                                        Console.Write($"{progress:000},");
                                        GC.Collect();
                                    }
                                    threadCounter--;
                                }
                            }, new MyVoxelTaskWorker(block, oldCache));

                            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.RefreshAssets();

            //voxelMap.UpdateContentBounds();

            Debug.WriteLine($" Done. | {timer.Elapsed}  | VoxCells {voxelMap.VoxCells:#,##0}");
            Console.WriteLine($" Done. | {timer.Elapsed}  | VoxCells {voxelMap.VoxCells:#,##0}");
        }