分散文件结构,添加了枚举类型的一个辅助类

This commit is contained in:
2023-09-20 11:04:11 +08:00
parent 8fec9bbc3a
commit a024cf600b
84 changed files with 3267 additions and 221 deletions

View File

@@ -0,0 +1,754 @@
using XericLibrary.Runtime.MacroLibrary;
using XericLibrary.Runtime.Type;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEngine.UIElements;
namespace XericLibrary.Runtime.MacroLibrary
{
public class NeighborGrid<T> : WeaklyObject,
IEnumerable<KeyValuePair<int, List<T>>>
{
#region <EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private Vector3 position;
private Vector3 cellSize;
private Vector3Int numCells;
private int maxNeighbor = 8;
public Vector3 Position
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => position;
}
public Vector3 CellSize
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => cellSize;
}
public Vector3Int NumCells
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => numCells;
}
internal System.Random random = new System.Random();
private int NeighborRandomIndex
{
get => random.Next(maxNeighbor);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><EFBFBD><E6B4A2>
/// </summary>
private Dictionary<int, List<T>> grid = new Dictionary<int, List<T>>();
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳߴ<DCB3>
/// </summary>
public Vector3 Fullsize
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => cellSize.Mul(numCells);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϵͳתΪ<D7AA><CEAA><EFBFBD>Χ
/// </summary>
public Bounds GridBounds
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new Bounds(position, Fullsize / 2);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
position = value.center;
cellSize = (value.size * 2).Div(numCells);
}
}
#endregion
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <summary>
/// <20>ٽ<EFBFBD><D9BD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="position"><3E><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="cellSize"><3E><><EFBFBD>񾧸<EFBFBD><F1BEA7B8>ߴ<EFBFBD></param>
/// <param name="fullSize"><3E><><EFBFBD><EFBFBD><EFBFBD>ܳߴ<DCB3></param>
/// <param name="maxNeighbor"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ھ<EFBFBD><DABE><EFBFBD><EFBFBD><EFBFBD></param>
public NeighborGrid(Vector3 position, Vector3 cellSize, Vector3 fullSize, int maxNeighbor = 8)
{
this.position = position;
this.cellSize = cellSize;
this.numCells = fullSize.Div(cellSize).FloorToInt().Max(Vector3Int.one);
this.maxNeighbor = maxNeighbor;
Debug.Log($"ԭ<>㣺{position}<7D><> <20><><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD>{cellSize}<7D><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>{numCells}");
}
#endregion
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public struct NeighborGridIndex
{
#region <EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
private NeighborGrid<T> grid;
private NeighborGridSpace drivenSpace;
private object drivenIndex;
#endregion
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
public NeighborGridIndex(NeighborGrid<T> grid)
{
this.grid = grid;
drivenSpace = (NeighborGridSpace)(-1);
drivenIndex = null;
}
#endregion
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <summary>
/// <20><>ȡΪ <20><><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="world"></param>
public Vector3 GetDrivenAsWorld()
{
DrivenTransformTo(NeighborGridSpace.World);
return (Vector3)drivenIndex;
}
/// <summary>
/// <20><>ȡΪ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="simulation"></param>
public Vector3 GetDrivenAsSimulation()
{
DrivenTransformTo(NeighborGridSpace.Simulation);
return (Vector3)drivenIndex;
}
/// <summary>
/// <20><>ȡΪ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="unit"></param>
public Vector3 GetDrivenAsUnit()
{
DrivenTransformTo(NeighborGridSpace.Unit);
return (Vector3)drivenIndex;
}
/// <summary>
/// <20><>ȡΪ <20><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>
/// </summary>
/// <param name="world"></param>
public Vector3Int GetDrivenAsIndex()
{
DrivenTransformTo(NeighborGridSpace.Index);
return (Vector3Int)drivenIndex;
}
/// <summary>
/// <20><>ȡΪ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="world"></param>
public int GetDrivenAsLinear()
{
DrivenTransformTo(NeighborGridSpace.Linear);
return (int)drivenIndex;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>Ϊ <20><><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="world"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public NeighborGridIndex SetDrivenAsWorld(Vector3 world)
{
drivenIndex = world;
drivenSpace = NeighborGridSpace.World;
return this;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>Ϊ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="simulation"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public NeighborGridIndex SetDrivenAsSimulation(Vector3 simulation)
{
drivenIndex = simulation;
drivenSpace = NeighborGridSpace.Simulation;
return this;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>Ϊ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="unit"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public NeighborGridIndex SetDrivenAsUnit(Vector3 unit)
{
drivenIndex = unit;
drivenSpace = NeighborGridSpace.Unit;
return this;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>Ϊ <20><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>
/// </summary>
/// <param name="world"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public NeighborGridIndex SetDrivenAsIndex(Vector3Int index)
{
drivenIndex = index;
drivenSpace = NeighborGridSpace.Index;
return this;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>Ϊ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="world"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public NeighborGridIndex SetDrivenAsLinear(int linear)
{
drivenIndex = linear;
drivenSpace = NeighborGridSpace.Linear;
return this;
}
/// <summary>
/// ת<><D7AA><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="targetSpace"></param>
public NeighborGridIndex DrivenTransformTo(NeighborGridSpace targetSpace)
{
switch(targetSpace)
{
case NeighborGridSpace.World:
TransformToWorld();
break;
case NeighborGridSpace.Simulation:
TransformToSimulation();
break;
case NeighborGridSpace.Unit:
TransformToUnit();
break;
case NeighborGridSpace.Index:
TransformToIndex();
break;
case NeighborGridSpace.Linear:
TransformToLiear();
break;
default:
throw new System.Exception(<><D7AA><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>");
}
return this;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>Ŀ<EFBFBD><C4BF>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
/// </summary>
private void TransformToWorld()
{
switch(drivenSpace)
{
case NeighborGridSpace.World:
drivenSpace = NeighborGridSpace.World;
break;
case NeighborGridSpace.Simulation:
drivenIndex = grid.SimulationToWorld((Vector3)drivenIndex);
goto case NeighborGridSpace.World;
case NeighborGridSpace.Unit:
drivenIndex = grid.UnitToSimulation((Vector3)drivenIndex);
goto case NeighborGridSpace.Simulation;
case NeighborGridSpace.Index:
drivenIndex = grid.IndexToUnit((Vector3Int)drivenIndex);
goto case NeighborGridSpace.Unit;
case NeighborGridSpace.Linear:
drivenIndex = grid.LinearToIndex((int)drivenIndex);
goto case NeighborGridSpace.Index;
default:
throw new System.Exception(<><D7AA><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>");
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>Ŀ<EFBFBD><C4BF>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ؿռ<D8BF>
/// </summary>
private void TransformToSimulation()
{
switch(drivenSpace)
{
case NeighborGridSpace.World:
drivenIndex = grid.WorldToSimulation((Vector3)drivenIndex);
goto case NeighborGridSpace.Simulation;
case NeighborGridSpace.Simulation:
drivenSpace = NeighborGridSpace.Simulation;
break;
case NeighborGridSpace.Unit:
drivenIndex = grid.UnitToSimulation((Vector3)drivenIndex);
goto case NeighborGridSpace.Simulation;
case NeighborGridSpace.Index:
drivenIndex = grid.IndexToUnit((Vector3Int)drivenIndex);
goto case NeighborGridSpace.Unit;
case NeighborGridSpace.Linear:
drivenIndex = grid.LinearToIndex((int)drivenIndex);
goto case NeighborGridSpace.Index;
default:
throw new System.Exception(<><D7AA><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>");
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>Ŀ<EFBFBD><C4BF>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD>ռ<EFBFBD>
/// </summary>
private void TransformToUnit()
{
switch(drivenSpace)
{
case NeighborGridSpace.World:
drivenIndex = grid.WorldToSimulation((Vector3)drivenIndex);
goto case NeighborGridSpace.Simulation;
case NeighborGridSpace.Simulation:
drivenIndex = grid.SimulationToUnit((Vector3)drivenIndex);
goto case NeighborGridSpace.Unit;
case NeighborGridSpace.Unit:
drivenSpace = NeighborGridSpace.Unit;
break;
case NeighborGridSpace.Index:
drivenIndex = grid.IndexToUnit((Vector3Int)drivenIndex);
goto case NeighborGridSpace.Unit;
case NeighborGridSpace.Linear:
drivenIndex = grid.LinearToIndex((int)drivenIndex);
goto case NeighborGridSpace.Index;
default:
throw new System.Exception(<><D7AA><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>");
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>Ŀ<EFBFBD><C4BF>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>
/// </summary>
private void TransformToIndex()
{
switch(drivenSpace)
{
case NeighborGridSpace.World:
drivenIndex = grid.WorldToSimulation((Vector3)drivenIndex);
goto case NeighborGridSpace.Simulation;
case NeighborGridSpace.Simulation:
drivenIndex = grid.SimulationToUnit((Vector3)drivenIndex);
goto case NeighborGridSpace.Unit;
case NeighborGridSpace.Unit:
drivenIndex = grid.UnitToIndex((Vector3)drivenIndex);
goto case NeighborGridSpace.Index;
case NeighborGridSpace.Index:
drivenSpace = NeighborGridSpace.Index;
break;
case NeighborGridSpace.Linear:
drivenIndex = grid.LinearToIndex((int)drivenIndex);
goto case NeighborGridSpace.Index;
default:
throw new System.Exception(<><D7AA><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>");
}
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>Ŀ<EFBFBD><C4BF>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
private void TransformToLiear()
{
switch(drivenSpace)
{
case NeighborGridSpace.World:
drivenIndex = grid.WorldToSimulation((Vector3)drivenIndex);
goto case NeighborGridSpace.Simulation;
case NeighborGridSpace.Simulation:
drivenIndex = grid.SimulationToUnit((Vector3)drivenIndex);
goto case NeighborGridSpace.Unit;
case NeighborGridSpace.Unit:
drivenIndex = grid.UnitToIndex((Vector3)drivenIndex);
goto case NeighborGridSpace.Index;
case NeighborGridSpace.Index:
drivenIndex = grid.IndexToLinear((Vector3Int)drivenIndex);
break;
case NeighborGridSpace.Linear:
drivenSpace = NeighborGridSpace.Linear;
break;
default:
throw new System.Exception(<><D7AA><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>");
}
}
#endregion
}
/// <summary>
/// <20>ٽ<EFBFBD><D9BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>ö<EFBFBD><C3B6>
/// </summary>
public enum NeighborGridSpace
{
World,
Simulation,
Unit,
Index,
Linear
}
#endregion
#region <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD> <20>任Ϊ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="world"><3E><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 WorldToSimulation(Vector3 world)
=> world - position - (-Fullsize / 2);
/// <summary>
/// <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD> <20>任Ϊ <20><><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="world"><3E><>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 SimulationToWorld(Vector3 simulation)
=> simulation + position + (-Fullsize / 2);
/// <summary>
/// <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD> <20>任Ϊ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="simulation"><3E><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 SimulationToUnit(Vector3 simulation)
=> simulation.Div(Fullsize);
/// <summary>
/// <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD> <20>任Ϊ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="simulation"><3E><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 UnitToSimulation(Vector3 unit)
=> unit.Mul(Fullsize);
/// <summary>
/// <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD> <20>任Ϊ <20><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>
/// </summary>
/// <param name="unit"><3E><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3Int UnitToIndex(Vector3 unit)
=> unit.IsInUnit() ? unit.Mul(numCells).FloorToInt() : MacroMath.Vector3Int_Negate;
/// <summary>
/// <20><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD> <20>任Ϊ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="index"><3E><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 IndexToUnit(Vector3Int index)
{
if(index.IsValid())
{
Vector3 unit = ((Vector3)index).Div(numCells);
unit.x = numCells.x == 1 && unit.x <= 0 ? .5f : unit.x;
unit.y = numCells.y == 1 && unit.y <= 0 ? .5f : unit.y;
unit.z = numCells.z == 1 && unit.z <= 0 ? .5f : unit.z;
return unit;
}
return MacroMath.Vector3Int_Negate;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD> <20>任Ϊ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="unit"><3E><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int UnitToLinear(Vector3 unit)
{
if(unit.IsInUnit())
{
return IndexToLinear(UnitToIndex(unit));
}
return -1;
}
/// <summary>
/// <20><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD> <20>任Ϊ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <param name="index"><3E><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int IndexToLinear(Vector3Int index)
{
if(index.IsValid() && index.IsInIndexRange(numCells))
{
return (int)(index.x +
(index.y * numCells.x) +
(index.z * numCells.y * numCells.x));
}
return -1;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="side"><3E>߳<EFBFBD></param>
/// <returns></returns>
public Vector3Int LinearToGridIndex(int linear, int side)
{
return new Vector3Int(linear % side, linear / side, linear / side.Quad());
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>任Ϊ <20><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3Int LinearToIndex(int linear)
{
int z = linear / (numCells.x * numCells.y);
int y = (linear - (z * numCells.x * numCells.y)) / numCells.x;
int x = linear - (z * numCells.x * numCells.y) - (y * numCells.x);
return new Vector3Int(x, y, z);
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>任Ϊ <20><><EFBFBD><EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ص<EFBFBD>λ<EFBFBD>ռ<EFBFBD>
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Vector3 LinearToUnit(int linear)
{
Debug.Log($"<22><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>{LinearToIndex(linear)}<7D><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>λ");
return IndexToUnit(LinearToIndex(linear));
}
#endregion
#region <EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD>
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
public void Clean()
{
grid.Clear();
}
/// <summary>
/// <20>ڸ<EFBFBD><DAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>Ŀ
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD></param>
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ӳɹ<D3B3></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Insert(int linear, T obj)
{
if(linear < 0)
return false;
if(grid.ContainsKey(linear))
{
int index = grid[linear].IndexOf(obj);
if(index < 0)
{
grid[linear].Add(obj);
return true;
}
return false;
}
else
{
grid.Add(linear, new List<T> { obj });
return true;
}
}
/// <summary>
/// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD></param>
/// <param name="obj"><3E><>Ŀ</param>
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>Ƴ<EFBFBD><C6B3>ɹ<EFBFBD></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Remove(int linear, T obj)
{
if(grid.ContainsKey(linear))
{
bool resualt = grid[linear].Remove(obj);
if(grid[linear].Count <= 0)
grid.Remove(linear);
return resualt;
}
return false;
}
/// <summary>
/// <20>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD></param>
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7>Ƴ<EFBFBD><C6B3>ɹ<EFBFBD></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Remove(int linear)
{
if(grid[linear] is not null)
{
grid[linear].Clear();
}
}
/// <summary>
/// <20><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD></param>
/// <param name="obj"><3E><>Ŀ</param>
/// <returns><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Contains(int linear, T obj)
{
if(grid[linear] is not null)
{
return grid[linear].Contains(obj);
}
return false;
}
/// <summary>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƻ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD>е<EFBFBD><D0B5>ھ<EFBFBD>
/// <code>
/// <20><><EFBFBD>棺DZ<E6A3BA>ڵĸ<DAB5><C4B8><EFBFBD><EFBFBD>ܿ<EFBFBD><DCBF><EFBFBD>
/// </code>
/// </summary>
/// <param name="linear"></param>
/// <returns></returns>
public bool GetAllNeighbor(int linear, out List<T> values)
{
return grid.TryGetValue(linear, out values);
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD>ڵ<EFBFBD><DAB5>ھ<EFBFBD>
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD>λ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD></param>
/// <returns></returns>
public IEnumerable<T> GetNeighbor(int linear)
{
int startIndex = NeighborRandomIndex;
int count = grid[linear].Count;
for(int i = 0; i < maxNeighbor; i++)
{
yield return grid[linear][(startIndex + i) % count];
}
}
/// <summary>
/// <20><>ȡ<EFBFBD><EFBFBD><EBBEB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ھ<EFBFBD>
/// </summary>
/// <param name="linear"><3E><><EFBFBD><EFBFBD>λ<EFBFBD>õ<EFBFBD><C3B5><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="range"><3E><><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD>Χ</param>
/// <returns></returns>
public IEnumerable<T> GetNeighbor(int linear, int radius)
{
int side = radius * 2 + 1;
int length = side.Cubic();
Vector3Int index = LinearToIndex(linear);
index = index.Sub(radius);
for(int i = 0; i < length; i++)
{
var neighbor = GetNeighbor(IndexToLinear(index +
LinearToGridIndex(i, side)))
.GetEnumerator();
while(neighbor.MoveNext())
{
yield return neighbor.Current;
}
}
}
#endregion
#region ʵ<EFBFBD><EFBFBD>
public IEnumerator<KeyValuePair<int, List<T>>> GetEnumerator()
{
foreach(var list in grid)
{
yield return list;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
}
}