SetVoxelContent() private method

private SetVoxelContent ( byte content, Vector3I &voxelCoord, bool needLock = true ) : void
content byte
voxelCoord Vector3I
needLock bool
return void
        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);
                            }
                        }
                    }
                }
            }
        }
        public void RotateAsteroid(VRageMath.Quaternion quaternion)
        {
            var sourceFile = SourceVoxelFilepath ?? VoxelFilepath;

            var asteroid = new MyVoxelMap();
            asteroid.Load(sourceFile, SpaceEngineersCore.Resources.GetDefaultMaterialName(), true);

            var newAsteroid = new MyVoxelMap();
            var transSize = Vector3I.Transform(asteroid.Size, quaternion);
            var newSize = Vector3I.Abs(transSize);
            newAsteroid.Init(Vector3D.Zero, newSize, SpaceEngineersCore.Resources.GetDefaultMaterialName());

            Vector3I coords;
            for (coords.Z = 0; coords.Z < asteroid.Size.Z; coords.Z++)
            {
                for (coords.Y = 0; coords.Y < asteroid.Size.Y; coords.Y++)
                {
                    for (coords.X = 0; coords.X < asteroid.Size.X; coords.X++)
                    {
                        byte volume = 0xff;
                        string cellMaterial;

                        asteroid.GetVoxelMaterialContent(ref coords, out cellMaterial, out volume);

                        var newCoord = Vector3I.Transform(coords, quaternion);
                        // readjust the points, as rotation occurs arround 0,0,0.
                        newCoord.X = newCoord.X < 0 ? newCoord.X - transSize.X : newCoord.X;
                        newCoord.Y = newCoord.Y < 0 ? newCoord.Y - transSize.Y : newCoord.Y;
                        newCoord.Z = newCoord.Z < 0 ? newCoord.Z - transSize.Z : newCoord.Z;
                        newAsteroid.SetVoxelContent(volume, ref newCoord);
                        newAsteroid.SetVoxelMaterialAndIndestructibleContent(cellMaterial, 0xff, ref newCoord);
                    }
                }
            }
            
            var tempfilename = TempfileUtil.NewFilename(MyVoxelMap.V2FileExtension);
            newAsteroid.Save(tempfilename);

            SourceVoxelFilepath = tempfilename;
        }
Beispiel #3
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);
        }