Protfolio-Emanuel-Polsky / Assets / _Project / Code / FlatenArrayUtillity / FlatenFloatArray2D.cs
FlatenFloatArray2D.cs
Raw
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Unity.Collections;
using Unity.Mathematics;
using UnityEngine;

namespace GarmentButton.FlatenArray
{
    public struct FlatenFloatArray2D
    {
        public int2 GridSize;
        public float CellSize;
        public float2 Center;

        public FlatenFloatArray2D(int2 gridSize, float cellSize, float2 center)
        {
            GridSize = gridSize;
            CellSize = cellSize;
            Center = center;
        }

        private float2 HalfGridDimensions => new(GridSize.x * CellSize * 0.5f, GridSize.y * CellSize * 0.5f);

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int GetCellAtPosition(float2 position)
        {
            var normalizedPosition = position - Center + HalfGridDimensions;
            var cellCoordinates = new int2
            {
                x = (int)math.floor(normalizedPosition.x / CellSize),
                y = (int)math.floor(normalizedPosition.y / CellSize),
            };
            cellCoordinates.x = math.clamp(cellCoordinates.x, 0, GridSize.x - 1);
            cellCoordinates.y = math.clamp(cellCoordinates.y, 0, GridSize.y - 1);

            return GridSize.x * cellCoordinates.y + cellCoordinates.x;
        }
        public int GetIndexSide(int index, Direction direction)
        {
            var coordinate = GetCorrdinate(index);
            return GetIndexByCorredinate(direction, coordinate);
        }

        public NativeArray<int> GetAllIndexSide(int index, int howFar = 1)
        {
            var coordinate = GetCorrdinate(index);
            const int NUMBER_OF_SIDES = 8;
            NativeArray<int> sides = new NativeArray<int>(NUMBER_OF_SIDES * howFar, Allocator.Temp);

            for (int distance = 1; distance <= howFar; distance++)
            {
                for (int direction = 0; direction < NUMBER_OF_SIDES; direction++)
                {
                    int sideIndex = (distance - 1) * NUMBER_OF_SIDES + direction;
                    int valueSideIndex = GetIndexByCorredinate((Direction)direction, coordinate, distance);
                    if (valueSideIndex > GridSize.x * GridSize.y)
                        valueSideIndex = -1;
                    sides[sideIndex] = valueSideIndex;
                }
            }

            return sides;
        }

        private int GetIndexByCorredinate(Direction direction, int2 coordinate, int howFar = 1)
        {
            switch (direction)
            {
                case Direction.Up_Left:
                    coordinate.x-= howFar;
                    coordinate.y+= howFar;
                    break;
                case Direction.Up:
                    coordinate.y += howFar;
                    break;
                case Direction.Up_Right:
                    coordinate.x += howFar;
                    coordinate.y += howFar;
                    break;
                case Direction.Down_Left:
                    coordinate.x -= howFar;
                    coordinate.y -= howFar;
                    break;
                case Direction.Down:
                    coordinate.y -= howFar;
                    break;
                case Direction.Down_Right:
                    coordinate.y -= howFar;
                    coordinate.x += howFar;
                    break;
                case Direction.Left:
                    coordinate.x -= howFar;
                    break;
                case Direction.Right:
                    coordinate.x += howFar;
                    break;
            }

            return GridSize.x * coordinate.y + coordinate.x;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int GetIndexFromCoordinate(int x, int y)
        {
            return GridSize.x * y + x;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public int2 GetCorrdinate(int result)
        {
            var y = result / GridSize.x;  // Changed to GridSize.x
            var x = result % GridSize.x;
            return new int2(x, y);
        }


        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public float2 GetWorldPosition(int2 coord) =>
    Center - HalfGridDimensions + ((float2)coord + 0.5f) * CellSize;

        /// <summary>Convenience overload (tiny extra cost of constructing int2).</summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public float2 GetWorldPosition(int x, int y) =>
            Center - HalfGridDimensions + (new float2(x + 0.5f, y + 0.5f)) * CellSize;

        /// <summary>Slowest: takes a 1-D index, converts to coord, then to world.</summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public float2 GetWorldPosition(int index) =>
            GetWorldPosition(GetCorrdinate(index));
    }
    public enum Direction : byte
    {
        Up_Left,Up, Up_Right,Down_Left, Down,Down_Right, Left, Right
    }
}