Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
2.9 kB
2
Indexable
Never
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 NativeArray<bool> Filled;

        private int _pixelsPerColor;

        public void Execute()
        {
            int totalPixels = Width * Height;
            _pixelsPerColor = totalPixels / Gradations;

            Unity.Mathematics.Random random = new Unity.Mathematics.Random((uint)Environment.TickCount);

            for (int colorId = 0; colorId < Gradations; colorId++)
            {
                int pixelsFilled = 0;

                while (pixelsFilled < _pixelsPerColor)
                {
                    int startX = random.NextInt(0, Width);
                    int startY = random.NextInt(0, Height);

                    // Запускаємо заливку з нової випадкової позиції
                    pixelsFilled += Fill(startX, startY, colorId);
                }
            }
        }

        private int Fill(int startX, int startY, int colorId)
        {
            // Визначаємо кількість заповнених пікселів
            int pixelsFilled = 0;

            // Використовується стек для трекінгу пікселів, які потрібно заповнити
            NativeList<int> stack = new NativeList<int>(Allocator.Temp);
            stack.Add(startY * Width + startX);

            while (stack.Length > 0)
            {
                // Беремо останній піксель зі стека
                int currentIndex = stack[stack.Length - 1];
                stack.RemoveAt(stack.Length - 1);

                int x = currentIndex % Width;
                int y = currentIndex / Width;

                // Перевірка меж і вже заповнених значень
                if (x < 0 || x >= Width || y < 0 || y >= Height || Filled[currentIndex])
                    continue;

                // Заповнюємо піксель
                Filled[currentIndex] = true;
                GradationMap[currentIndex] = colorId;
                pixelsFilled++;

                // Додаємо сусідні пікселі до стека для заповнення
                stack.Add((y + 1) * Width + x); // down
                stack.Add((y - 1) * Width + x); // up
                stack.Add(y * Width + (x + 1)); // right
                stack.Add(y * Width + (x - 1)); // left
            }

            stack.Dispose(); // Вивільняємо пам'ять

            return pixelsFilled;
        }
    }
}
Leave a Comment