Untitled
using System; using Unity.Burst; using Unity.Collections; using Unity.Jobs; using Unity.Mathematics; using UnityEngine; namespace Game.World.Views.Spreads.Jobs { [BurstCompile] public struct CreateGradationMapJob : IJob { public NativeArray<int> GradationMap; public int Gradations; public int Width; public int Height; public NativeArray<int2> InitialPoints; public NativeArray<bool> Filled; private int _pixelsCount; private int _pixelsPerColor; public void Execute() { _pixelsCount = Width * Height; _pixelsPerColor = _pixelsCount / Gradations; NativeArray<NativeList<int2>> queues = new NativeArray<NativeList<int2>>(Gradations, Allocator.Temp); for (int colorId = 0; colorId < Gradations; colorId++) { queues[colorId] = new NativeList<int2>(Allocator.Temp); int2 startPoint = InitialPoints[colorId]; if (startPoint.x >= 0 && startPoint.x < Width && startPoint.y >= 0 && startPoint.y < Height) { queues[colorId].Add(startPoint); } } int radius = 0; int[] filledCounts = new int[Gradations]; while (true) { bool anyQueueHasPoints = false; for (int colorId = 0; colorId < Gradations; colorId++) { if (filledCounts[colorId] >= _pixelsPerColor) continue; NativeList<int2> newPoints = new NativeList<int2>(Allocator.Temp); NativeList<int2> queue = queues[colorId]; if (queue.Length > 0) anyQueueHasPoints = true; for (int i = 0; i < queue.Length; i++) { int2 point = queue[i]; int x = point.x; int y = point.y; if (Fill(x, y, colorId)) { filledCounts[colorId]++; } } for (int angle = 0; angle < 360; angle++) { float rad = math.radians(angle); int2 startPoint = InitialPoints[colorId]; int newX = startPoint.x + (int)(radius * math.cos(rad)); int newY = startPoint.y + (int)(radius * math.sin(rad)); if (newX >= 0 && newX < Width && newY >= 0 && newY < Height && !GetFilledValue(newX, newY)) { newPoints.Add(new int2(newX, newY)); } } queue.Clear(); queue.AddRange(newPoints); newPoints.Dispose(); } if (!anyQueueHasPoints) break; radius++; } for (int colorId = 0; colorId < Gradations; colorId++) { queues[colorId].Dispose(); } queues.Dispose(); } private bool Fill(int x, int y, int colorId) { if (x < 0 || x >= Width || y < 0 || y >= Height || GetFilledValue(x, y)) { return false; } int index = x + y * Width; SetFilledValue(x, y, true); GradationMap[index] = colorId; return true; } private bool GetFilledValue(int x, int y) { int index = y * Width + x; return Filled[index]; } private void SetFilledValue(int x, int y, bool value) { int index = y * Width + x; Filled[index] = value; } } }
Leave a Comment