Untitled
unknown
plain_text
a year ago
4.0 kB
16
Indexable
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]++;
}
}
if (queue.Length > 0)
{
int2 startPoint = InitialPoints[colorId];
for (int angle = 0; angle < 360; angle++)
{
float rad = math.radians(angle);
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;
}
}
}
Editor is loading...
Leave a Comment