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; for (int colorId = 0; colorId < Gradations; colorId++) { int2 startPoint = InitialPoints[colorId]; int startX = startPoint.x; int startY = startPoint.y; if (startX >= 0 && startX < Width && startY >= 0 && startY < Height) { NativeList<int2> queue = new NativeList<int2>(Allocator.Temp); queue.Add(new int2(startX, startY)); int filledCount = 0; int radius = 0; while (filledCount < _pixelsPerColor) { NativeList<int2> newPoints = new NativeList<int2>(Allocator.Temp); 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)) { filledCount++; } } radius++; queue.Clear(); for (int angle = 0; angle < 360; angle++) { float rad = math.radians(angle); int newX = startX + (int)(radius * math.cos(rad)); int newY = startY + (int)(radius * math.sin(rad)); if (newX >= 0 && newX < Width && newY >= 0 && newY < Height && !GetFilledValue(newX, newY)) { newPoints.Add(new int2(newX, newY)); } } queue.AddRange(newPoints); newPoints.Dispose(); } queue.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