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 GetAllIndexSide(int index, int howFar = 1) { var coordinate = GetCorrdinate(index); const int NUMBER_OF_SIDES = 8; NativeArray sides = new NativeArray(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; /// Convenience overload (tiny extra cost of constructing int2). [MethodImpl(MethodImplOptions.AggressiveInlining)] public float2 GetWorldPosition(int x, int y) => Center - HalfGridDimensions + (new float2(x + 0.5f, y + 0.5f)) * CellSize; /// Slowest: takes a 1-D index, converts to coord, then to world. [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 } }