Untitled
unknown
plain_text
a month ago
3.8 kB
2
Indexable
Never
using System; using System.Collections.Generic; using Unity.Burst; using Unity.Collections; using Unity.Jobs; 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 NativeList<int> CurrentGradationPoints; public NativeList<int> PointQueue; public NativeArray<bool> Filled; private int _pixelsCount; private int _remaining; private int _filledCount; private int _colorId; private int _currentGradation; private int _pixelsPerColor; public void Execute() { Unity.Mathematics.Random random = new Unity.Mathematics.Random((uint)Environment.TickCount); _pixelsCount = Width * Height; _pixelsPerColor = _pixelsCount / Gradations; int expectedCount = _pixelsPerColor * Gradations; _filledCount = 0; _remaining = 0; _colorId = -1; int currentX = random.NextInt(0, Width); int currentY = random.NextInt(0, Height); _currentGradation = 0; Fill(currentX, currentY); while (_filledCount < expectedCount) { if (PointQueue.Length > 0) { int currentPoint = PointQueue[0]; PointQueue.RemoveAtSwapBack(0); int x = currentPoint % Width; int y = currentPoint / Width; TryFillCircle(x, y); } else { break; } } } private void TryFillCircle(int x, int y) { int radius = 1; while (_remaining > 0 && _filledCount < _pixelsCount) { for (int dx = -radius; dx <= radius; dx++) { for (int dy = -radius; dy <= radius; dy++) { if (dx * dx + dy * dy <= radius * radius) { Fill(x + dx, y + dy); } } } radius++; } } private void Fill(int x, int y) { if (x < 0 || x >= Width || y < 0 || y >= Height || GetFilledValue(x, y)) { return; } if (_remaining == 0) { if (_colorId == Gradations - 1) { return; } _colorId++; _currentGradation = (int)((_colorId / (float)Gradations) * Gradations); _remaining = _pixelsPerColor; } int index = x + y * Width; PointQueue.Add(index); SetFilledValue(x, y, true); _filledCount++; GradationMap[index] = _currentGradation; _remaining--; } private bool GetFilledValue(int x, int y) { if (x < 0 || x >= Width || y < 0 || y >= Height) { throw new ArgumentOutOfRangeException("Error 0"); } int index = y * Width + x; bool result = Filled[index]; return result; } private void SetFilledValue(int x, int y, bool value) { if (x < 0 || x >= Width || y < 0 || y >= Height) { throw new ArgumentOutOfRangeException("Error 1"); } int index = y * Width + x; Filled[index] = value; } } }
Leave a Comment