SEToolbox.Interop.Asteroids.MyVoxelMap.UpdateContentBounds C# (CSharp) Method

UpdateContentBounds() public method

public UpdateContentBounds ( ) : void
return void
        public void UpdateContentBounds()
        {
            _boundingContent = new BoundingBoxD(new Vector3I(Size.X, Size.Y, Size.Z), new Vector3I(0, 0, 0));
            Vector3I cellCoord;

            for (cellCoord.X = 0; cellCoord.X < _dataCellsCount.X; cellCoord.X++)
            {
                for (cellCoord.Y = 0; cellCoord.Y < _dataCellsCount.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = 0; cellCoord.Z < _dataCellsCount.Z; cellCoord.Z++)
                    {
                        var voxelCell = _voxelContentCells[cellCoord.X][cellCoord.Y][cellCoord.Z];

                        if (voxelCell == null)
                        {
                            _boundingContent.Min = Vector3D.Min(_boundingContent.Min, new Vector3D(cellCoord.X << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS, cellCoord.Y << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS, cellCoord.Z << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS));
                            _boundingContent.Max = Vector3D.Max(_boundingContent.Max, new Vector3D((cellCoord.X + 1 << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) - 1, (cellCoord.Y + 1 << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) - 1, (cellCoord.Z + 1 << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) - 1));
                        }
                        //  Cell's are FULL by default, therefore we don't need to change them
                        else if (voxelCell.CellType == MyVoxelCellType.MIXED)
                        {

                            Vector3I voxelCoordInCell;
                            for (voxelCoordInCell.X = 0; voxelCoordInCell.X < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.X++)
                            {
                                for (voxelCoordInCell.Y = 0; voxelCoordInCell.Y < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Y++)
                                {
                                    for (voxelCoordInCell.Z = 0; voxelCoordInCell.Z < MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS; voxelCoordInCell.Z++)
                                    {
                                        var content = voxelCell.GetVoxelContent(ref voxelCoordInCell);
                                        if (content > 0)
                                        {
                                            _boundingContent.Min = Vector3D.Min(_boundingContent.Min, new Vector3D((cellCoord.X << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + voxelCoordInCell.X, (cellCoord.Y << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + voxelCoordInCell.Y, (cellCoord.Z << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + voxelCoordInCell.Z));
                                            _boundingContent.Max = Vector3D.Max(_boundingContent.Max, new Vector3D((cellCoord.X << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + voxelCoordInCell.X, (cellCoord.Y << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + voxelCoordInCell.Y, (cellCoord.Z << MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_VOXELS_BITS) + voxelCoordInCell.Z));
                                        }

                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

Usage Example

Ejemplo n.º 1
0
        /// <summary>
        /// Processes an asteroid Voxel using function callbacks.
        /// This allows for muti-threading, and generating content via algorithims.
        /// </summary>
        /// <param name="voxelMap"></param>
        /// <param name="multiThread"></param>
        /// <param name="material"></param>
        /// <param name="func"></param>
        /// <param name="readWrite"></param>
        /// <returns></returns>
        public static void ProcessAsteroid(MyVoxelMap voxelMap, bool multiThread, string material, Action<MyVoxelBuilderArgs> func, bool readWrite = true)
        {
            long counterTotal = (long)voxelMap.Size.X * (long)voxelMap.Size.Y * (long)voxelMap.Size.Z;
            long counter = 0;
            decimal progress = 0;
            var timer = new Stopwatch();
            Debug.Write(string.Format("Building Asteroid : {0:000},", progress));
            Console.Write(string.Format("Building Asteroid : {0:000},", progress));
            Exception threadException = null;

            timer.Start();

            if (!multiThread)
            {
                #region single thread processing

                for (var x = 0; x < voxelMap.Size.X; x++)
                {
                    for (var y = 0; y < voxelMap.Size.Y; y++)
                    {
                        for (var z = 0; z < voxelMap.Size.Z; z++)
                        {
                            var coords = new Vector3I(x, y, z);

                            byte volume = 0xff;
                            var cellMaterial = material;

                            if (readWrite)
                                voxelMap.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

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

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

                            if (args.Volume != MyVoxelConstants.VOXEL_CONTENT_FULL)
                            {
                                voxelMap.SetVoxelContent(args.Volume, ref coords);
                            }

                            if (material != args.Material)
                            {
                                voxelMap.SetVoxelMaterialAndIndestructibleContent(args.Material, args.Indestructible, ref coords);
                            }

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

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

                long threadCounter = counterTotal / MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE / MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE / MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE;

                var baseCoords = new Vector3I(0, 0, 0);
                for (baseCoords.X = 0; baseCoords.X < voxelMap.Size.X; baseCoords.X += MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE)
                {
                    for (baseCoords.Y = 0; baseCoords.Y < voxelMap.Size.Y; baseCoords.Y += MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE)
                    {
                        for (baseCoords.Z = 0; baseCoords.Z < voxelMap.Size.Z; baseCoords.Z += MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE)
                        {
                            var task = new Task(obj =>
                            {
                                var bgw = (MyVoxelTaskWorker)obj;

                                var coords = new Vector3I(0, 0, 0);
                                for (coords.X = bgw.BaseCoords.X; coords.X < bgw.BaseCoords.X + MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE; coords.X++)
                                {
                                    for (coords.Y = bgw.BaseCoords.Y; coords.Y < bgw.BaseCoords.Y + MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE; coords.Y++)
                                    {
                                        for (coords.Z = bgw.BaseCoords.Z; coords.Z < bgw.BaseCoords.Z + MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE; coords.Z++)
                                        {
                                            byte volume = 0xff;
                                            var cellMaterial = material;

                                            if (readWrite)
                                                voxelMap.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                                            var args = new MyVoxelBuilderArgs(voxelMap.Size, coords, cellMaterial, volume, 0xff);
                                            try
                                            {
                                                func(args);
                                            }
                                            catch (Exception ex)
                                            {
                                                threadException = ex;
                                                threadCounter = 0;
                                                break;
                                            }

                                            if (args.Volume != MyVoxelConstants.VOXEL_CONTENT_FULL)
                                            {
                                                voxelMap.SetVoxelContent(args.Volume, ref coords);
                                            }

                                            if (material != args.Material)
                                            {
                                                voxelMap.SetVoxelMaterialAndIndestructibleContent(args.Material, args.Indestructible, ref coords);
                                            }
                                        }
                                    }
                                }

                                lock (Locker)
                                {
                                    counter += (long)MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE *
                                            MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE *
                                            MyVoxelConstants.VOXEL_DATA_CELLS_IN_RENDER_CELL_SIZE;
                                    var prog = Math.Floor(counter / (decimal)counterTotal * 100);
                                    if (prog != progress)
                                    {
                                        progress = prog;
                                        Debug.Write(string.Format("{0:000},", progress));
                                        Console.Write(string.Format("{0:000},", progress));
                                        GC.Collect();
                                    }
                                    threadCounter--;
                                }

                            }, new MyVoxelTaskWorker(baseCoords));

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

            var count = voxelMap.SumVoxelCells();

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