public void DoKernelOperation(ActionType action, float intensity, Vector3 position, float radius, bool cutDetails, int textureIndex) { Utils.Profiler.BeginSample("[Dig] VoxelChunk.DoKernelOperation"); voxelArrayBeforeSmooth = new Voxel[voxelArray.Length]; Array.Copy(voxelArray, voxelArrayBeforeSmooth, voxelArray.Length); var voxels = new NativeArray <Voxel>(voxelArray, Allocator.TempJob); var voxelsOut = new NativeArray <Voxel>(voxelArray, Allocator.TempJob); var heights = new NativeArray <float>(heightArray, Allocator.TempJob); #if UNITY_2019_3_OR_NEWER var chunkHoles = new NativeArray <int>(sizeOfMesh * sizeOfMesh, Allocator.TempJob); #else var toCut = new NativeCollections.NativeQueue <CutEntry>(Allocator.TempJob); var toTriggerBounds = new NativeCollections.NativeQueue <float3>(Allocator.TempJob); #endif var tData = digger.Terrain.terrainData; var hScale = digger.HeightmapScale; var holeScale = digger.HoleMapScale; var cutSizeX = Math.Max(1, (int)(hScale.x / holeScale.x)); var cutSizeZ = Math.Max(1, (int)(hScale.z / holeScale.z)); var jobData = new VoxelKernelModificationJob { SizeVox = sizeVox, SizeVox2 = sizeVox * sizeVox, SizeOfMesh = sizeOfMesh, LowInd = sizeVox - 3, Action = action, HeightmapScale = digger.HeightmapScale, Voxels = voxels, VoxelsOut = voxelsOut, Intensity = intensity, Center = position, Radius = radius, RadiusWithMargin = radius + Math.Max(Math.Max(digger.CutMargin.x, digger.CutMargin.y), digger.CutMargin.z), ChunkAltitude = voxelPosition.y, Heights = heights, CutSize = new int2(cutSizeX, cutSizeZ), #if UNITY_2019_3_OR_NEWER Holes = chunkHoles, #else WorldPosition = worldPosition, ToCut = toCut.ToConcurrent(), TerrainRelativePositionToHolePosition = new float2(1f / tData.size.x * tData.alphamapWidth, 1f / tData.size.z * tData.alphamapHeight), ToTriggerBounds = toTriggerBounds.ToConcurrent(), #endif NeighborVoxelsLBB = LoadVoxels(digger, chunkPosition + new Vector3i(-1, -1, -1)), NeighborVoxelsLBF = LoadVoxels(digger, chunkPosition + new Vector3i(-1, -1, +1)), NeighborVoxelsLB_ = LoadVoxels(digger, chunkPosition + new Vector3i(-1, -1, +0)), NeighborVoxels_BB = LoadVoxels(digger, chunkPosition + new Vector3i(+0, -1, -1)), NeighborVoxels_BF = LoadVoxels(digger, chunkPosition + new Vector3i(+0, -1, +1)), NeighborVoxels_B_ = LoadVoxels(digger, chunkPosition + new Vector3i(+0, -1, +0)), NeighborVoxelsRBB = LoadVoxels(digger, chunkPosition + new Vector3i(+1, -1, -1)), NeighborVoxelsRBF = LoadVoxels(digger, chunkPosition + new Vector3i(+1, -1, +1)), NeighborVoxelsRB_ = LoadVoxels(digger, chunkPosition + new Vector3i(+1, -1, +0)), NeighborVoxelsL_B = LoadVoxels(digger, chunkPosition + new Vector3i(-1, +0, -1)), NeighborVoxelsL_F = LoadVoxels(digger, chunkPosition + new Vector3i(-1, +0, +1)), NeighborVoxelsL__ = LoadVoxels(digger, chunkPosition + new Vector3i(-1, +0, +0)), NeighborVoxels__B = LoadVoxels(digger, chunkPosition + new Vector3i(+0, +0, -1)), NeighborVoxels__F = LoadVoxels(digger, chunkPosition + new Vector3i(+0, +0, +1)), NeighborVoxelsR_B = LoadVoxels(digger, chunkPosition + new Vector3i(+1, +0, -1)), NeighborVoxelsR_F = LoadVoxels(digger, chunkPosition + new Vector3i(+1, +0, +1)), NeighborVoxelsR__ = LoadVoxels(digger, chunkPosition + new Vector3i(+1, +0, +0)), NeighborVoxelsLUB = LoadVoxels(digger, chunkPosition + new Vector3i(-1, +1, -1)), NeighborVoxelsLUF = LoadVoxels(digger, chunkPosition + new Vector3i(-1, +1, +1)), NeighborVoxelsLU_ = LoadVoxels(digger, chunkPosition + new Vector3i(-1, +1, +0)), NeighborVoxels_UB = LoadVoxels(digger, chunkPosition + new Vector3i(+0, +1, -1)), NeighborVoxels_UF = LoadVoxels(digger, chunkPosition + new Vector3i(+0, +1, +1)), NeighborVoxels_U_ = LoadVoxels(digger, chunkPosition + new Vector3i(+0, +1, +0)), NeighborVoxelsRUB = LoadVoxels(digger, chunkPosition + new Vector3i(+1, +1, -1)), NeighborVoxelsRUF = LoadVoxels(digger, chunkPosition + new Vector3i(+1, +1, +1)), NeighborVoxelsRU_ = LoadVoxels(digger, chunkPosition + new Vector3i(+1, +1, +0)), }; // Schedule the job var handle = jobData.Schedule(voxels.Length, 64); // Wait for the job to complete handle.Complete(); jobData.DisposeNeighbors(); voxels.Dispose(); voxelsOut.CopyTo(voxelArray); voxelsOut.Dispose(); heights.Dispose(); #if UNITY_2019_3_OR_NEWER var cutter = (TerrainCutter20193)digger.Cutter; cutter.Cut(chunkHoles, voxelPosition, chunkPosition); chunkHoles.Dispose(); #else UpdateCut(cutDetails, toCut); var triggerBounds = new ChunkTriggerBounds(digger.HeightmapScale, digger.SizeOfMesh); while (toTriggerBounds.Count > 0) { triggerBounds.ExtendIfNeeded(toTriggerBounds.Dequeue()); } toTriggerBounds.Dispose(); bounds = triggerBounds; #endif #if UNITY_EDITOR RecordUndoIfNeeded(); #endif digger.EnsureChunkWillBePersisted(this); Utils.Profiler.EndSample(); }
public void DoOperation(BrushType brush, ActionType action, float intensity, Vector3 position, float radius, float coneHeight, bool upsideDown, int textureIndex, bool cutDetails, bool isTargetIntensity) { if (action == ActionType.Smooth || action == ActionType.BETA_Sharpen) { DoKernelOperation(action, intensity, position, radius, cutDetails, textureIndex); return; } Utils.Profiler.BeginSample("[Dig] VoxelChunk.DoOperation"); var heights = new NativeArray <float>(heightArray, Allocator.TempJob); var voxels = new NativeArray <Voxel>(voxelArray, Allocator.TempJob); #if UNITY_2019_3_OR_NEWER var chunkHoles = new NativeArray <int>(sizeOfMesh * sizeOfMesh, Allocator.TempJob); #else var toCut = new NativeCollections.NativeQueue <CutEntry>(Allocator.TempJob); var toTriggerBounds = new NativeCollections.NativeQueue <float3>(Allocator.TempJob); #endif var tData = digger.Terrain.terrainData; var hScale = digger.HeightmapScale; var holeScale = digger.HoleMapScale; var cutSizeX = Math.Max(1, (int)(hScale.x / holeScale.x)); var cutSizeZ = Math.Max(1, (int)(hScale.z / holeScale.z)); var jobData = new VoxelModificationJob { SizeVox = sizeVox, SizeVox2 = sizeVox * sizeVox, SizeOfMesh = sizeOfMesh, Brush = brush, Action = action, HeightmapScale = digger.HeightmapScale, ChunkAltitude = voxelPosition.y, Voxels = voxels, Heights = heights, Intensity = intensity, IsTargetIntensity = isTargetIntensity, Center = position, Radius = radius, ConeHeight = coneHeight, UpsideDown = upsideDown, RadiusWithMargin = radius + Math.Max(Math.Max(digger.CutMargin.x, digger.CutMargin.y), digger.CutMargin.z), TextureIndex = (uint)textureIndex, CutSize = new int2(cutSizeX, cutSizeZ), #if UNITY_2019_3_OR_NEWER Holes = chunkHoles #else ToCut = toCut.ToConcurrent(), WorldPosition = worldPosition, TerrainRelativePositionToHolePosition = new float2(1f / tData.size.x * tData.alphamapWidth, 1f / tData.size.z * tData.alphamapHeight), ToTriggerBounds = toTriggerBounds.ToConcurrent(), #endif }; jobData.PostConstruct(); // Schedule the job var handle = jobData.Schedule(voxels.Length, 64); // Wait for the job to complete handle.Complete(); voxels.CopyTo(voxelArray); voxels.Dispose(); heights.Dispose(); #if UNITY_2019_3_OR_NEWER var cutter = (TerrainCutter20193)digger.Cutter; if (action != ActionType.Reset) { cutter.Cut(chunkHoles, voxelPosition, chunkPosition); } else { cutter.UnCut(chunkHoles, voxelPosition, chunkPosition); } chunkHoles.Dispose(); #else UpdateCut(cutDetails, toCut); var triggerBounds = new ChunkTriggerBounds(digger.HeightmapScale, digger.SizeOfMesh); while (toTriggerBounds.Count > 0) { triggerBounds.ExtendIfNeeded(toTriggerBounds.Dequeue()); } toTriggerBounds.Dispose(); bounds = triggerBounds; #endif #if UNITY_EDITOR RecordUndoIfNeeded(); #endif digger.EnsureChunkWillBePersisted(this); Utils.Profiler.EndSample(); }