Esempio n. 1
0
        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();
        }
Esempio n. 2
0
        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();
        }