public static void AddToQueue( MyLodTypeEnum type, MyVoxelMap voxelMap, MyVoxelGeometry.CellData cache, int voxelStartX, int voxelStartY, int voxelStartZ) { Debug.Assert(Thread.CurrentThread == MySandboxGame.Static.UpdateThread, "Only update thread should queue voxel precalc."); MyVoxelPrecalcTaskItem a = new MyVoxelPrecalcTaskItem(type, voxelMap, cache, new Vector3I(voxelStartX, voxelStartY, voxelStartZ)); Tasks.Enqueue(a); }
// Precalculate voxel cell into cache (makes triangles and vertex buffer from voxels) public void Precalc(MyVoxelPrecalcTaskItem task) { Profiler.Begin("MyVoxelPrecalcTask.Precalc"); m_precalcType = task.Type; m_resultVerticesCounter = 0; m_resultTrianglesCounter = 0; m_edgeVertexCalcCounter++; m_voxelMap = task.VoxelMap; m_voxelStart = task.VoxelStart; int lodIdx = MyVoxelGeometry.GetLodIndex(m_precalcType); CalcPolygCubeSize(lodIdx); // Copy voxels into temp array //using (Stats.Timing.Measure("NewPrecalc.CopyVoxelContents", MyStatTypeEnum.Sum, clearRateMs: TIMEOUT)) Profiler.Begin("NewPrecalc.CopyVoxelContents"); bool isMixed = CopyVoxelContents() == MyVoxelRangeType.MIXED; Profiler.End(); //using (Stats.Timing.Measure("Precalc.Geometry generation", MyStatTypeEnum.Sum, clearRateMs: TIMEOUT)) Profiler.Begin("Precalc.Geometry generation"); { if (isMixed) { var cache = ThreadLocalCache; // Size of voxel or cell (in meters) and size of voxel map / voxel cells ComputeSizeAndOrigin(lodIdx); var start = Vector3I.One; var end = m_polygCubes - 1; Vector3I coord0 = start; for (var it = new Vector3I.RangeIterator(ref start, ref end); it.IsValid(); it.GetNext(out coord0)) { // We can get this voxel content right from cache (not using GetVoxelContent method), because after CopyVoxelContents these array must be filled. But only content, not material, normal, etc. int cubeIndex = 0; if (cache.Content(coord0.X + 0, coord0.Y + 0, coord0.Z + 0) < MyVoxelConstants.VOXEL_ISO_LEVEL) { cubeIndex |= 1; } if (cache.Content(coord0.X + 1, coord0.Y + 0, coord0.Z + 0) < MyVoxelConstants.VOXEL_ISO_LEVEL) { cubeIndex |= 2; } if (cache.Content(coord0.X + 1, coord0.Y + 0, coord0.Z + 1) < MyVoxelConstants.VOXEL_ISO_LEVEL) { cubeIndex |= 4; } if (cache.Content(coord0.X + 0, coord0.Y + 0, coord0.Z + 1) < MyVoxelConstants.VOXEL_ISO_LEVEL) { cubeIndex |= 8; } if (cache.Content(coord0.X + 0, coord0.Y + 1, coord0.Z + 0) < MyVoxelConstants.VOXEL_ISO_LEVEL) { cubeIndex |= 16; } if (cache.Content(coord0.X + 1, coord0.Y + 1, coord0.Z + 0) < MyVoxelConstants.VOXEL_ISO_LEVEL) { cubeIndex |= 32; } if (cache.Content(coord0.X + 1, coord0.Y + 1, coord0.Z + 1) < MyVoxelConstants.VOXEL_ISO_LEVEL) { cubeIndex |= 64; } if (cache.Content(coord0.X + 0, coord0.Y + 1, coord0.Z + 1) < MyVoxelConstants.VOXEL_ISO_LEVEL) { cubeIndex |= 128; } // Cube is entirely in/out of the surface if (MyMarchingCubesConstants.EdgeTable[cubeIndex] == 0) { continue; } // We can get this voxel content right from cache (not using GetVoxelContent method), because after CopyVoxelContents these array must be filled. But only content, not material, normal, etc. Vector3I tempVoxelCoord0 = ComputeTemporaryVoxelData(cache, ref coord0, cubeIndex); // Create the triangles CreateTriangles(ref coord0, cubeIndex, ref tempVoxelCoord0); } } } Profiler.End(); //using (Stats.Timing.Measure("Precalc.PrepareCache", MyStatTypeEnum.Sum, clearRateMs: TIMEOUT)) Profiler.Begin("Precalc.PrepareCache"); { // Cache the vertices and triangles and precalculate the octree task.Cache.PrepareCache(m_resultVertices, m_resultVerticesCounter, m_resultTriangles, m_resultTrianglesCounter, m_positionScale, m_originPosition, task.Type == MyLodTypeEnum.LOD0); } Profiler.End(); Profiler.End(); }
// Precalculate voxel cell into cache (makes triangles and vertex buffer from voxels) public void Precalc(MyVoxelPrecalcTaskItem task) { Profiler.Begin("MyVoxelPrecalcTask.Precalc"); m_precalcType = task.Type; m_resultVerticesCounter = 0; m_resultTrianglesCounter = 0; m_edgeVertexCalcCounter++; m_voxelMap = task.VoxelMap; m_voxelStart = task.VoxelStart; int lodIdx = MyVoxelGeometry.GetLodIndex(m_precalcType); CalcPolygCubeSize(lodIdx); // Copy voxels into temp array //using (Stats.Timing.Measure("NewPrecalc.CopyVoxelContents", MyStatTypeEnum.Sum, clearRateMs: TIMEOUT)) Profiler.Begin("NewPrecalc.CopyVoxelContents"); bool isMixed = CopyVoxelContents() == MyVoxelRangeType.MIXED; Profiler.End(); //using (Stats.Timing.Measure("Precalc.Geometry generation", MyStatTypeEnum.Sum, clearRateMs: TIMEOUT)) Profiler.Begin("Precalc.Geometry generation"); { if (isMixed) { var cache = ThreadLocalCache; // Size of voxel or cell (in meters) and size of voxel map / voxel cells ComputeSizeAndOrigin(lodIdx); var start = Vector3I.One; var end = m_polygCubes - 1; Vector3I coord0 = start; for (var it = new Vector3I.RangeIterator(ref start, ref end); it.IsValid(); it.GetNext(out coord0)) { // We can get this voxel content right from cache (not using GetVoxelContent method), because after CopyVoxelContents these array must be filled. But only content, not material, normal, etc. int cubeIndex = 0; if (cache.Content(coord0.X + 0, coord0.Y + 0, coord0.Z + 0) < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 1; if (cache.Content(coord0.X + 1, coord0.Y + 0, coord0.Z + 0) < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 2; if (cache.Content(coord0.X + 1, coord0.Y + 0, coord0.Z + 1) < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 4; if (cache.Content(coord0.X + 0, coord0.Y + 0, coord0.Z + 1) < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 8; if (cache.Content(coord0.X + 0, coord0.Y + 1, coord0.Z + 0) < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 16; if (cache.Content(coord0.X + 1, coord0.Y + 1, coord0.Z + 0) < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 32; if (cache.Content(coord0.X + 1, coord0.Y + 1, coord0.Z + 1) < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 64; if (cache.Content(coord0.X + 0, coord0.Y + 1, coord0.Z + 1) < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 128; // Cube is entirely in/out of the surface if (MyMarchingCubesConstants.EdgeTable[cubeIndex] == 0) { continue; } // We can get this voxel content right from cache (not using GetVoxelContent method), because after CopyVoxelContents these array must be filled. But only content, not material, normal, etc. Vector3I tempVoxelCoord0 = ComputeTemporaryVoxelData(cache, ref coord0, cubeIndex); // Create the triangles CreateTriangles(ref coord0, cubeIndex, ref tempVoxelCoord0); } } } Profiler.End(); //using (Stats.Timing.Measure("Precalc.PrepareCache", MyStatTypeEnum.Sum, clearRateMs: TIMEOUT)) Profiler.Begin("Precalc.PrepareCache"); { // Cache the vertices and triangles and precalculate the octree task.Cache.PrepareCache(m_resultVertices, m_resultVerticesCounter, m_resultTriangles, m_resultTrianglesCounter, m_positionScale, m_originPosition, task.Type == MyLodTypeEnum.LOD0); } Profiler.End(); Profiler.End(); }
// Precalculate voxel cell into cache (makes triangles and vertex buffer from voxels) // Doesn't use threads, just main thread. Use when you don't want to precalculate many cells in parallel. public static void PrecalcImmediatelly(MyVoxelPrecalcTaskItem task) { m_singleCoreTask.Precalc(task); }