Archived
分散文件结构,添加了枚举类型的一个辅助类
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
public static partial class MacroMath
|
||||
{
|
||||
#region 常量
|
||||
|
||||
/// <summary>
|
||||
/// 弧度转角度
|
||||
/// </summary>
|
||||
public const float Rad2Ang = 57.295779513082320876798154814105f;
|
||||
/// <summary>
|
||||
/// 弧度转角度
|
||||
/// </summary>
|
||||
public const double Rad2Ang_d = 57.295779513082320876798154814105d;
|
||||
/// <summary>
|
||||
/// 弧度转角度
|
||||
/// </summary>
|
||||
public const decimal Rad2Ang_m = 57.295779513082320876798154814105m;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 角度转弧度
|
||||
/// </summary>
|
||||
public const float Ang2Rad = .01745329251994329576923690768489f;
|
||||
/// <summary>
|
||||
/// 角度转弧度
|
||||
/// </summary>
|
||||
public const double Ang2Rad_d = .01745329251994329576923690768489d;
|
||||
/// <summary>
|
||||
/// 角度转弧度
|
||||
/// </summary>
|
||||
public const decimal Ang2Rad_m = .01745329251994329576923690768489m;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 最大可接受的误差
|
||||
/// </summary>
|
||||
public const float MaxError = .000001f;
|
||||
/// <summary>
|
||||
/// 最大可接受的误差
|
||||
/// </summary>
|
||||
public const double MaxError_d = .0000001d;
|
||||
/// <summary>
|
||||
/// 最大可接受的误差
|
||||
/// </summary>
|
||||
public const decimal MaxError_m = .00000001m;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根号2的一半,用于快速平方根除以二
|
||||
/// </summary>
|
||||
public const float Sqrt22 = 0.70710678118654752440084436210485f;
|
||||
/// <summary>
|
||||
/// 根号2的一半,用于快速平方根除以二
|
||||
/// </summary>
|
||||
public const double Sqrt22_d = 0.70710678118654752440084436210485d;
|
||||
/// <summary>
|
||||
/// 根号2的一半,用于快速平方根除以二
|
||||
/// </summary>
|
||||
public const decimal Sqrt22_m = 0.70710678118654752440084436210485m;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 费根鲍姆常数,是周期分叉及混沌现象的一个比值,可用于人口变化,水滴周期等现象
|
||||
/// </summary>
|
||||
public const float Feigenbaum = 4.669201609102990671853203820466201617258185577475768632745651343004134f;
|
||||
/// <summary>
|
||||
/// 费根鲍姆常数,是周期分叉及混沌现象的一个比值,可用于人口变化,水滴周期等现象
|
||||
/// </summary>
|
||||
public const double Feigenbaum_d = 4.669201609102990671853203820466201617258185577475768632745651343004134d;
|
||||
/// <summary>
|
||||
/// 费根鲍姆常数,是周期分叉及混沌现象的一个比值,可用于人口变化,水滴周期等现象
|
||||
/// </summary>
|
||||
public const decimal Feigenbaum_m = 4.669201609102990671853203820466201617258185577475768632745651343004134m;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 表示无效的三维整数矢量
|
||||
/// </summary>
|
||||
public static readonly Vector3Int Vector3Int_Negate = new Vector3Int(-1, -1, -1);
|
||||
|
||||
/// <summary>
|
||||
/// 表示无效的二维整数矢量
|
||||
/// </summary>
|
||||
public static readonly Vector2Int Vector2Int_Negate = new Vector2Int(-1, -1);
|
||||
|
||||
/// <summary>
|
||||
/// 表示无效的整数
|
||||
/// </summary>
|
||||
public static readonly int Int_Negate = -1;
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc508d99ffe561a488e1a2a002f20871
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Unity.VisualScripting.YamlDotNet.Core.Tokens;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
/// <summary>
|
||||
/// 枚举宏,用于完成枚举项遍历,位操作等
|
||||
/// </summary>
|
||||
public class MacroEnum<T>
|
||||
where T: struct, Enum
|
||||
{
|
||||
/// <summary>
|
||||
/// 反射组值
|
||||
/// </summary>
|
||||
private Array valueArray;
|
||||
|
||||
/// <summary>
|
||||
/// 反射组名称
|
||||
/// </summary>
|
||||
private string[] nameArray;
|
||||
|
||||
/// <summary>
|
||||
/// 构建一个枚举辅助器
|
||||
/// </summary>
|
||||
public MacroEnum()
|
||||
{
|
||||
valueArray = typeof(T).GetEnumValues();
|
||||
nameArray = typeof(T).GetEnumNames();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<T> GetValues()
|
||||
{
|
||||
foreach(var type in valueArray)
|
||||
yield return (T)type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<string> GetNames()
|
||||
{
|
||||
foreach(var type in nameArray)
|
||||
yield return type;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取枚举项目
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<(string, T)> GetEnums()
|
||||
{
|
||||
var output = nameArray
|
||||
.Zip(GetValues(), (name, value) => (name, value));
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置目标的枚举值
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void SetEnum(ref int target, params T[] values)
|
||||
{
|
||||
foreach(var value in values)
|
||||
{
|
||||
target |= Convert.ToInt32(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置目标的枚举值
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void SetEnum(ref int target, T value)
|
||||
{
|
||||
target |= Convert.ToInt32(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复位目标的枚举值
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void ResetEnum(ref int target, params T[] values)
|
||||
{
|
||||
int temp = 0;
|
||||
foreach(var value in values)
|
||||
{
|
||||
temp |= Convert.ToInt32(value);
|
||||
}
|
||||
target &= ~temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复位目标的枚举值
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void ResetEnum(ref int target, T value)
|
||||
{
|
||||
target &= ~Convert.ToInt32(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 翻转目标的枚举值
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void FlipEnum(ref int target, params T[] values)
|
||||
{
|
||||
int temp = 0;
|
||||
foreach(var value in values)
|
||||
{
|
||||
temp |= Convert.ToInt32(value);
|
||||
}
|
||||
target ^= temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 翻转目标的枚举值
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="values"></param>
|
||||
public static void FlipEnum(ref int target, T value)
|
||||
{
|
||||
target ^= Convert.ToInt32(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 94a45cbae926bdb4e9a05c822232c00b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
/// <summary>
|
||||
/// 数学库
|
||||
/// </summary>
|
||||
public static partial class MacroMath
|
||||
{
|
||||
#region 随机
|
||||
|
||||
/// <summary>
|
||||
/// 哈希后处理
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong MurmurFinalize(ulong index)
|
||||
{
|
||||
index ^= index >> 33;
|
||||
index *= 0xff51afd7ed558ccd;
|
||||
index ^= index >> 33;
|
||||
index *= 0xc4ceb9fe1a85ec53;
|
||||
index ^= index >> 33;
|
||||
return index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 大范围随机
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ulong RandomNumber(ulong index)
|
||||
{
|
||||
index *= 1103515245;
|
||||
index += 12345;
|
||||
index *= 6364136223846793005UL;
|
||||
index += 1442695040888963407UL;
|
||||
index %= 18446744073709551615UL;
|
||||
return index;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 数学
|
||||
|
||||
/// <summary>
|
||||
/// pmod
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <param name="b"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static double PMod(double a, double b)
|
||||
{
|
||||
double z = a % b;
|
||||
double w = (z < 0) ? -1 : 1;
|
||||
z = (z < 0) ? -z : z;
|
||||
if(w < 0)
|
||||
return b - z;
|
||||
else
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float MinPositive(float a, float b)
|
||||
=> Math.Min(Math.Max(0, a), Math.Max(0, b));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int MinPositive(int a, int b)
|
||||
=> Math.Min(Math.Max(0, a), Math.Max(0, b));
|
||||
|
||||
#endregion
|
||||
|
||||
#region 字节控制
|
||||
|
||||
/// <summary>
|
||||
/// 设置字
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void SetByteState(ref int target, int site, bool state)
|
||||
{
|
||||
if(state)
|
||||
target |= 1 << site;
|
||||
|
||||
else
|
||||
target &= 0xff - (1 << site);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置字
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void SetByteState(ref int target, Enum site, bool state)
|
||||
{
|
||||
SetByteState(ref target, Convert.ToInt32(site), state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查字
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool GetByteState(int target, int site)
|
||||
{
|
||||
return (target >> site & 0x01) > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查字
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool GetByteState(int target, Enum site)
|
||||
{
|
||||
return GetByteState(target, Convert.ToInt32(site));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 45a81e001aee8594dbc45766fef9dfcd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
public static class MacroObject
|
||||
{
|
||||
#region 对象操作
|
||||
|
||||
/// <summary>
|
||||
/// 无论如何都要获取一个组件
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T GetComponentAnyway<T>(this GameObject obj)
|
||||
where T : Component
|
||||
{
|
||||
var component = obj.GetComponent<T>();
|
||||
if(component is null)
|
||||
component = obj.AddComponent<T>();
|
||||
return component;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 无论如何都要获取一个对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static T GetObjectAnyway<T>(this T obj)
|
||||
where T : new()
|
||||
{
|
||||
if(obj is null)
|
||||
obj = new T();
|
||||
return obj;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ba90139bc3f0a3347afd4673b38919a1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
public static partial class MacroMath
|
||||
{
|
||||
|
||||
#region 文本
|
||||
|
||||
/// <summary>
|
||||
/// 获取此处的物体名称,如果带有(clone)后缀,则省略这个后缀
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static string GetGameObjectNameWithoutClone(GameObject gameObject)
|
||||
{
|
||||
return GetGameObjectNameWithoutClone(gameObject.name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取此处的物体名称,如果带有(clone)后缀,则省略这个后缀
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static string GetGameObjectNameWithoutClone(string gameObjectName)
|
||||
{
|
||||
const string cloneSuffix = "(Clone)";
|
||||
if(gameObjectName.EndsWith(cloneSuffix))
|
||||
{
|
||||
int suffixIndex = gameObjectName.LastIndexOf(cloneSuffix);
|
||||
string nameWithoutClone = gameObjectName.Substring(0, suffixIndex);
|
||||
return nameWithoutClone;
|
||||
}
|
||||
return gameObjectName;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ddcec615e26876649b458ceb73acef9f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Xeric.Runtime.MicroLibrary
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 坐标系统换算库
|
||||
/// </remarks>
|
||||
public static class MacroTransferAxes
|
||||
{
|
||||
#region 坐标系换算
|
||||
|
||||
/**
|
||||
* 像Maya就是Y向上的三维软件,它原来属于Silicon Graphice,Inc.的硬件开发,使用的也是SGI的标准;
|
||||
* 以及DX,OpenGL也是使用Z缓冲区之类的名称来处理屏幕空间渲染。
|
||||
* Unity,Zbrush,DirectX使用的是Y轴向上的左手坐标系
|
||||
* Maya,OpenGL使用的是Y轴向上的右手坐标系
|
||||
*
|
||||
* 像Unreal诞生时Maya还没诞生,大家都用的是3D Max,所以采用了Z轴向上的左手坐标系。
|
||||
* 另外3D Max,source engine,cry engine, blender使用的是Z轴向上的右手坐标系;
|
||||
*
|
||||
* 数学上可能左手会好些
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// 将Y轴向上的坐标系转为Z轴向上的坐标系;
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static Vector3 YupToZupAxes(Vector3 input)
|
||||
{
|
||||
return new Vector3(input.x, input.y, input.z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将Z轴向上的坐标系转为Y轴向上的坐标系;
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
public static Vector3 ZupToYupAxes(Vector3 input)
|
||||
{
|
||||
return new Vector3(input.x, input.y, input.z);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6dfe731c33104d5458aa7cc26ea22e32
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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 字段属性
|
||||
|
||||
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>
|
||||
/// 网格系统存储地
|
||||
/// </summary>
|
||||
private Dictionary<int, List<T>> grid = new Dictionary<int, List<T>>();
|
||||
|
||||
/// <summary>
|
||||
/// 网格的总尺寸
|
||||
/// </summary>
|
||||
public Vector3 Fullsize
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => cellSize.Mul(numCells);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此网格系统转为盒体范围
|
||||
/// </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 构造
|
||||
|
||||
/// <summary>
|
||||
/// 临近网格
|
||||
/// </summary>
|
||||
/// <param name="position">网格原点坐标</param>
|
||||
/// <param name="cellSize">网格晶格尺寸</param>
|
||||
/// <param name="fullSize">网格总尺寸</param>
|
||||
/// <param name="maxNeighbor">单个晶格内最大邻居数量</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}, 晶格尺寸{cellSize}, 数量:{numCells}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 类内类
|
||||
|
||||
/// <summary>
|
||||
/// 网格索引
|
||||
/// </summary>
|
||||
public struct NeighborGridIndex
|
||||
{
|
||||
#region 字段属性
|
||||
|
||||
private NeighborGrid<T> grid;
|
||||
|
||||
private NeighborGridSpace drivenSpace;
|
||||
|
||||
private object drivenIndex;
|
||||
|
||||
#endregion
|
||||
|
||||
#region 构造
|
||||
|
||||
public NeighborGridIndex(NeighborGrid<T> grid)
|
||||
{
|
||||
this.grid = grid;
|
||||
drivenSpace = (NeighborGridSpace)(-1);
|
||||
drivenIndex = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 方法
|
||||
|
||||
/// <summary>
|
||||
/// 获取为 世界空间
|
||||
/// </summary>
|
||||
/// <param name="world"></param>
|
||||
public Vector3 GetDrivenAsWorld()
|
||||
{
|
||||
DrivenTransformTo(NeighborGridSpace.World);
|
||||
return (Vector3)drivenIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取为 网格系统本地坐标空间
|
||||
/// </summary>
|
||||
/// <param name="simulation"></param>
|
||||
public Vector3 GetDrivenAsSimulation()
|
||||
{
|
||||
DrivenTransformTo(NeighborGridSpace.Simulation);
|
||||
return (Vector3)drivenIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取为 网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <param name="unit"></param>
|
||||
public Vector3 GetDrivenAsUnit()
|
||||
{
|
||||
DrivenTransformTo(NeighborGridSpace.Unit);
|
||||
return (Vector3)drivenIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取为 三维索引
|
||||
/// </summary>
|
||||
/// <param name="world"></param>
|
||||
public Vector3Int GetDrivenAsIndex()
|
||||
{
|
||||
DrivenTransformTo(NeighborGridSpace.Index);
|
||||
return (Vector3Int)drivenIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取为 线性索引
|
||||
/// </summary>
|
||||
/// <param name="world"></param>
|
||||
public int GetDrivenAsLinear()
|
||||
{
|
||||
DrivenTransformTo(NeighborGridSpace.Linear);
|
||||
return (int)drivenIndex;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 设置为 世界空间
|
||||
/// </summary>
|
||||
/// <param name="world"></param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public NeighborGridIndex SetDrivenAsWorld(Vector3 world)
|
||||
{
|
||||
drivenIndex = world;
|
||||
drivenSpace = NeighborGridSpace.World;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置为 网格系统本地坐标空间
|
||||
/// </summary>
|
||||
/// <param name="simulation"></param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public NeighborGridIndex SetDrivenAsSimulation(Vector3 simulation)
|
||||
{
|
||||
drivenIndex = simulation;
|
||||
drivenSpace = NeighborGridSpace.Simulation;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置为 网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <param name="unit"></param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public NeighborGridIndex SetDrivenAsUnit(Vector3 unit)
|
||||
{
|
||||
drivenIndex = unit;
|
||||
drivenSpace = NeighborGridSpace.Unit;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置为 三维索引
|
||||
/// </summary>
|
||||
/// <param name="world"></param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public NeighborGridIndex SetDrivenAsIndex(Vector3Int index)
|
||||
{
|
||||
drivenIndex = index;
|
||||
drivenSpace = NeighborGridSpace.Index;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置为 线性索引
|
||||
/// </summary>
|
||||
/// <param name="world"></param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public NeighborGridIndex SetDrivenAsLinear(int linear)
|
||||
{
|
||||
drivenIndex = linear;
|
||||
drivenSpace = NeighborGridSpace.Linear;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 转换当前索引到目标空间
|
||||
/// </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("转换空间是无效的");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将当前的目标转换到世界空间
|
||||
/// </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("转换空间是无效的");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将当前的目标转换到本地空间
|
||||
/// </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("转换空间是无效的");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将当前的目标转换到单位空间
|
||||
/// </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("转换空间是无效的");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将当前的目标转换到三维索引
|
||||
/// </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("转换空间是无效的");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将当前的目标转换到线性索引
|
||||
/// </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("转换空间是无效的");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 临近网络空间枚举
|
||||
/// </summary>
|
||||
public enum NeighborGridSpace
|
||||
{
|
||||
World,
|
||||
Simulation,
|
||||
Unit,
|
||||
Index,
|
||||
Linear
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 索引变换
|
||||
|
||||
/// <summary>
|
||||
/// 世界空间 变换为 网格系统本地坐标空间
|
||||
/// </summary>
|
||||
/// <param name="world">项目的世界空间坐标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Vector3 WorldToSimulation(Vector3 world)
|
||||
=> world - position - (-Fullsize / 2);
|
||||
|
||||
/// <summary>
|
||||
/// 网格系统本地坐标空间 变换为 世界空间
|
||||
/// </summary>
|
||||
/// <param name="world">项目的世界空间坐标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Vector3 SimulationToWorld(Vector3 simulation)
|
||||
=> simulation + position + (-Fullsize / 2);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 网格系统本地坐标空间 变换为 网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <param name="simulation">网格系统本地坐标空间</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Vector3 SimulationToUnit(Vector3 simulation)
|
||||
=> simulation.Div(Fullsize);
|
||||
|
||||
/// <summary>
|
||||
/// 网格系统本地坐标空间 变换为 网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <param name="simulation">网格系统本地坐标空间</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Vector3 UnitToSimulation(Vector3 unit)
|
||||
=> unit.Mul(Fullsize);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 网格系统本地单位空间 变换为 三维索引
|
||||
/// </summary>
|
||||
/// <param name="unit">网格系统本地单位空间</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Vector3Int UnitToIndex(Vector3 unit)
|
||||
=> unit.IsInUnit() ? unit.Mul(numCells).FloorToInt() : MacroMath.Vector3Int_Negate;
|
||||
|
||||
/// <summary>
|
||||
/// 三维索引 变换为 网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <param name="index">三维索引</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>
|
||||
/// 网格系统本地单位空间 变换为 线性索引
|
||||
/// </summary>
|
||||
/// <param name="unit">网格系统本地坐标空间</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int UnitToLinear(Vector3 unit)
|
||||
{
|
||||
if(unit.IsInUnit())
|
||||
{
|
||||
return IndexToLinear(UnitToIndex(unit));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 三维索引 变换为 线性索引
|
||||
/// </summary>
|
||||
/// <param name="index">三维索引</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>
|
||||
/// 根据线性索引获取网格中索引偏移量
|
||||
/// </summary>
|
||||
/// <param name="linear">线性索引</param>
|
||||
/// <param name="side">边长</param>
|
||||
/// <returns></returns>
|
||||
public Vector3Int LinearToGridIndex(int linear, int side)
|
||||
{
|
||||
return new Vector3Int(linear % side, linear / side, linear / side.Quad());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 线性索引 变换为 三维索引
|
||||
/// </summary>
|
||||
/// <param name="linear">线性索引</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>
|
||||
/// 线性索引 变换为 网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <param name="linear">线性索引</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Vector3 LinearToUnit(int linear)
|
||||
{
|
||||
Debug.Log($"线性转索引空间{LinearToIndex(linear)},再转单位");
|
||||
return IndexToUnit(LinearToIndex(linear));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 增删查
|
||||
|
||||
/// <summary>
|
||||
/// 清空网格
|
||||
/// </summary>
|
||||
public void Clean()
|
||||
{
|
||||
grid.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在给定索引处添加一个项目
|
||||
/// </summary>
|
||||
/// <param name="linear">索引</param>
|
||||
/// <returns>返回是否添加成功</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>
|
||||
/// 移除给定索引处的项目
|
||||
/// </summary>
|
||||
/// <param name="linear">索引</param>
|
||||
/// <param name="obj">项目</param>
|
||||
/// <returns>返回是否移除成功</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>
|
||||
/// 移除给定索引下所有项目
|
||||
/// </summary>
|
||||
/// <param name="linear">索引</param>
|
||||
/// <returns>返回是否移除成功</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Remove(int linear)
|
||||
{
|
||||
if(grid[linear] is not null)
|
||||
{
|
||||
grid[linear].Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询给定索引处是否存在项目
|
||||
/// </summary>
|
||||
/// <param name="linear">索引</param>
|
||||
/// <param name="obj">项目</param>
|
||||
/// <returns>返回项目是否存在</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>
|
||||
/// 忽略限制获取所有的邻居
|
||||
/// <code>
|
||||
/// 警告:潜在的高性能开销
|
||||
/// </code>
|
||||
/// </summary>
|
||||
/// <param name="linear"></param>
|
||||
/// <returns></returns>
|
||||
public bool GetAllNeighbor(int linear, out List<T> values)
|
||||
{
|
||||
return grid.TryGetValue(linear, out values);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取允许范围内的邻居
|
||||
/// </summary>
|
||||
/// <param name="linear">所在位置的索引</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>
|
||||
/// 获取半径内所有允许的邻居
|
||||
/// </summary>
|
||||
/// <param name="linear">所在位置的索引</param>
|
||||
/// <param name="range">检查的范围</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 实现
|
||||
|
||||
public IEnumerator<KeyValuePair<int, List<T>>> GetEnumerator()
|
||||
{
|
||||
foreach(var list in grid)
|
||||
{
|
||||
yield return list;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ffd0ac031e48e94990e3501ec6bb5ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,132 @@
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
public static class NeighborGridExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 世界空间变换为网格系统本地坐标空间
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="world"></param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 WorldToSimulation<T>(this Vector3 world, NeighborGrid<T> grid)
|
||||
=> grid.WorldToSimulation(world);
|
||||
/// <summary>
|
||||
/// 网格系统本地坐标空间变换为世界空间
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="simulation"></param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 SimulationToWorld<T>(this Vector3 simulation, NeighborGrid<T> grid)
|
||||
=> grid.SimulationToWorld(simulation);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 网格系统本地坐标空间转为网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="simulation"></param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 SimulationToUnit<T>(this Vector3 simulation, NeighborGrid<T> grid)
|
||||
=> grid.SimulationToUnit(simulation);
|
||||
/// <summary>
|
||||
/// 网格系统本地坐标空间转为网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="unit"></param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 UnitToSimulation<T>(this Vector3 unit, NeighborGrid<T> grid)
|
||||
=> grid.UnitToSimulation(unit);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 网格系统本地单位空间转为三维索引
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="unit"></param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int UnitToIndex<T>(this Vector3 unit, NeighborGrid<T> grid)
|
||||
=> grid.UnitToIndex(unit);
|
||||
/// <summary>
|
||||
/// 三维索引转为网格系统本地单位空间
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="index"></param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 IndexToUnit<T>(this Vector3Int index, NeighborGrid<T> grid)
|
||||
=> grid.IndexToUnit(index);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 网格系统本地单位空间转为线性索引
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="unit">网格系统本地坐标空间</param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int UnitToLinear<T>(this Vector3 unit, NeighborGrid<T> grid)
|
||||
=> grid.UnitToLinear(unit);
|
||||
/// <summary>
|
||||
/// 三维索引转为线性索引
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="index">三维索引</param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int IndexToLinear<T>(this Vector3Int index, NeighborGrid<T> grid)
|
||||
=> grid.IndexToLinear(index);
|
||||
/// <summary>
|
||||
/// 网格系统本地单位空间转为线性索引
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="unit">网格系统本地坐标空间</param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int LinearToIndex<T>(this int Linear, NeighborGrid<T> grid)
|
||||
=> grid.LinearToIndex(Linear);
|
||||
/// <summary>
|
||||
/// 三维索引转为线性索引
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="index">三维索引</param>
|
||||
/// <param name="grid">网格目标</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 LinearToUnit<T>(this int Linear, NeighborGrid<T> grid)
|
||||
=> grid.LinearToUnit(Linear);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 从世界坐标获取到索引
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="Linear"></param>
|
||||
/// <param name="grid"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int WorldToLinear<T>(this Vector3 Linear, NeighborGrid<T> grid)
|
||||
=> Linear.WorldToSimulation(grid).SimulationToUnit(grid).UnitToLinear(grid);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f67516c9f81441149a09742c65b0ffed
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,248 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
using Xorti = XericLibrary.Runtime.MacroLibrary.MacroMath;
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
public static class ExtendType
|
||||
{
|
||||
#region 算法
|
||||
|
||||
/// <summary>
|
||||
/// 检查给定的值是否在范围内[min, max]
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="min"></param>
|
||||
/// <param name="max"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsInRange(this int value, int min, int max)
|
||||
=> value >= min && value <= max;
|
||||
|
||||
/// <summary>
|
||||
/// 检查给定的值是否在索引范围内[min, max)
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="min"></param>
|
||||
/// <param name="max"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsInIndexRange(this int value, int min, int max)
|
||||
=> value >= min && value < max;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 二次方
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int Quad(this int value)
|
||||
{
|
||||
return value * value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 三次方
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int Cubic(this int value)
|
||||
{
|
||||
return value * value * value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 四次方
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int Quart(this int value)
|
||||
{
|
||||
return value * value * value * value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 五次方
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int Quint(this int value)
|
||||
{
|
||||
return value * value * value * value * value;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 二次方
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float Quad(this float value)
|
||||
{
|
||||
return value * value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 三次方
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float Cubic(this float value)
|
||||
{
|
||||
return value * value * value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 四次方
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float Quart(this float value)
|
||||
{
|
||||
return value * value * value * value;
|
||||
}
|
||||
/// <summary>
|
||||
/// 五次方
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float Quint(this float value)
|
||||
{
|
||||
return value * value * value * value * value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 事件
|
||||
|
||||
/// <summary>
|
||||
/// 保守地调用一个事件分发器
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool InvokeConservative(this Action invokedEvent, int sign, ref int register)
|
||||
{
|
||||
if(Xorti.GetByteState(register, sign))
|
||||
return false;
|
||||
Xorti.SetByteState(ref register, sign, true);
|
||||
invokedEvent?.Invoke();
|
||||
Xorti.SetByteState(ref register, sign, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保守地调用一个事件分发器
|
||||
/// </summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool InvokeConservative<PARAM>(this Action<PARAM> invokedEvent, PARAM input, int sign, ref int register)
|
||||
{
|
||||
if(Xorti.GetByteState(register, sign))
|
||||
return false;
|
||||
Xorti.SetByteState(ref register, sign, true);
|
||||
invokedEvent?.Invoke(input);
|
||||
Xorti.SetByteState(ref register, sign, false);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 对象
|
||||
|
||||
/// <summary>
|
||||
/// 获取组件,并适配函数式编程
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="component"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool GetComponent<T>(this GameObject target, out T component)
|
||||
{
|
||||
component = target.GetComponent<T>();
|
||||
return component is not null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此对象的父类是第二者吗
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="other"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool ParentIs(this GameObject target, GameObject other)
|
||||
{
|
||||
return target.transform.parent == other.transform;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此对象是第二者的父类吗
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="other"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsParent(this GameObject target, GameObject other)
|
||||
{
|
||||
return target.transform == other.transform.parent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 此对象与第二者是兄弟吗
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
/// <param name="other"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsBrother(this GameObject target, GameObject other)
|
||||
{
|
||||
return target.transform.parent == other.transform.parent;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region bound
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsInUnit(this Vector3 vec, float align = 1)
|
||||
{
|
||||
float negat = 1 - align;
|
||||
return
|
||||
vec.x <= align &&
|
||||
vec.y <= align &&
|
||||
vec.z <= align &&
|
||||
vec.x >= negat &&
|
||||
vec.y >= negat &&
|
||||
vec.z >= negat;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region string
|
||||
|
||||
private static string ListToString<T>(this List<List<T>> context)
|
||||
{
|
||||
string result = "";
|
||||
Func<List<T>, string> ListFormat = (List<T> list) =>
|
||||
{
|
||||
string result = "";
|
||||
for (int i = 0; i < list.Count; i++, result += ",")
|
||||
result += $"{i}: {list[i]}";
|
||||
return result;
|
||||
};
|
||||
for(int i = 0; i < context.Count; i++)
|
||||
result += $"List{i}: {{{ListFormat(context[i])}}}\r\n";
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5083902ec572f1b449bfe335c374ed4e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
public static class Vector2Extend
|
||||
{
|
||||
/// <summary>
|
||||
/// 李若辰规定的编辑表面坐标转换方法
|
||||
/// </summary>
|
||||
/// <param name="vec"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 ToVector3(this Vector2 vec)
|
||||
=> new Vector3(vec.x, 0, vec.y);
|
||||
|
||||
[Obsolete("unfinished")]
|
||||
public static Vector2 Projection(this Vector2 point, Vector3 start, Vector3 end)
|
||||
{
|
||||
Vector3 vec = end - start;
|
||||
float xx = Mathf.Pow(vec.x, 2f);
|
||||
float yy = Mathf.Pow(vec.y, 2f);
|
||||
float denominator = xx + yy;
|
||||
if(denominator == 0)
|
||||
return point;
|
||||
|
||||
float xy = vec.x * vec.y;
|
||||
//float moleculey = yy *
|
||||
return new Vector2(xx, xy);
|
||||
}
|
||||
|
||||
public static Vector2 Projection(this Vector2 point, Vector2 start, Vector2 end)
|
||||
{
|
||||
Vector2 ab = end - start;
|
||||
Vector2 ap = point - start;
|
||||
return start + ab * Vector2.Dot(ap, ab) / ab.sqrMagnitude;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 矢量正交化
|
||||
/// </summary>
|
||||
/// <param name="vec"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2 Orthogonalization(this Vector2 vec)
|
||||
=> new Vector2(
|
||||
(float)Math.Round(vec.x),
|
||||
(float)Math.Round(vec.y)
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2 Min(this Vector2 a, Vector2 b)
|
||||
{
|
||||
return new Vector2(Math.Min(a.x, b.x), Math.Min(a.y, b.y));
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2 Max(this Vector2 a, Vector2 b)
|
||||
{
|
||||
return new Vector2(Math.Max(a.x, b.x), Math.Max(a.y, b.y));
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float MinElement(this Vector2 a)
|
||||
{
|
||||
return Math.Min(a.x, a.y);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float MaxElement(this Vector2 a)
|
||||
{
|
||||
return Math.Max(a.x, a.y);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2 Abs(this Vector2 a)
|
||||
{
|
||||
return new Vector2(Math.Abs(a.x), Math.Abs(a.y));
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取矢量各轴符号
|
||||
/// </summary>
|
||||
/// <param name="vec"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2 Sign(this Vector2 vec)
|
||||
=> new Vector2(
|
||||
Math.Sign(vec.x),
|
||||
Math.Sign(vec.y)
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float Cross(this Vector2 lhs, Vector2 rhs)
|
||||
=> lhs.x * rhs.y - rhs.x * lhs.y;
|
||||
|
||||
/// <summary>
|
||||
/// 延斜线对齐一个点
|
||||
/// </summary>
|
||||
/// <param name="point"></param>
|
||||
/// <param name=""></param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2 ObliqueAlign(this Vector2 point, Vector2 constPoint, out float exec)
|
||||
{
|
||||
float b1 = point.y - point.x, b2 = constPoint.y - constPoint.x;
|
||||
float dt = b1 + (b2 - b1);
|
||||
exec = dt * MacroMath.Sqrt22;
|
||||
Vector2 ab = constPoint - point;
|
||||
bool cool = ab.x * ab.y < 0;
|
||||
return exec * (cool ? Vector2.one : new Vector2(-1, 1));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93b81a983491c7a4791024a82c310d26
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,446 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace XericLibrary.Runtime.MacroLibrary
|
||||
{
|
||||
public static class Vector3Extend
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Add(this Vector3 a, Vector3 b)
|
||||
=> new Vector3(
|
||||
a.x + b.x,
|
||||
a.y + b.y,
|
||||
a.z + b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Add(this Vector3 a, Vector3Int b)
|
||||
=> new Vector3(
|
||||
a.x + b.x,
|
||||
a.y + b.y,
|
||||
a.z + b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Add(this Vector3 a, float b)
|
||||
=> new Vector3(
|
||||
a.x + b,
|
||||
a.y + b,
|
||||
a.z + b
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Sub(this Vector3 a, Vector3 b)
|
||||
=> new Vector3(
|
||||
a.x - b.x,
|
||||
a.y - b.y,
|
||||
a.z - b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Sub(this Vector3 a, Vector3Int b)
|
||||
=> new Vector3(
|
||||
a.x - b.x,
|
||||
a.y - b.y,
|
||||
a.z - b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Sub(this Vector3 a, float b)
|
||||
=> new Vector3(
|
||||
a.x - b,
|
||||
a.y - b,
|
||||
a.z - b
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Mul(this Vector3 a, Vector3 b)
|
||||
=> new Vector3(
|
||||
a.x * b.x,
|
||||
a.y * b.y,
|
||||
a.z * b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Mul(this Vector3 a, Vector3Int b)
|
||||
=> new Vector3(
|
||||
a.x * b.x,
|
||||
a.y * b.y,
|
||||
a.z * b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Mul(this Vector3 a, float b)
|
||||
=> new Vector3(
|
||||
a.x * b,
|
||||
a.y * b,
|
||||
a.z * b
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Div(this Vector3 a, Vector3 b)
|
||||
=> new Vector3(
|
||||
a.x / b.x,
|
||||
a.y / b.y,
|
||||
a.z / b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Div(this Vector3 a, Vector3Int b)
|
||||
=> new Vector3(
|
||||
a.x / b.x,
|
||||
a.y / b.y,
|
||||
a.z / b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Div(this Vector3 a, float b)
|
||||
=> new Vector3(
|
||||
a.x / b,
|
||||
a.y / b,
|
||||
a.z / b
|
||||
);
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Xonly(this Vector3 a)
|
||||
=> new Vector3(
|
||||
a.x,
|
||||
0f,
|
||||
0f
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Yonly(this Vector3 a)
|
||||
=> new Vector3(
|
||||
0f,
|
||||
a.y,
|
||||
0f
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Zonly(this Vector3 a)
|
||||
=> new Vector3(
|
||||
0f,
|
||||
0f,
|
||||
a.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Mode(this Vector3 a, Vector3 b)
|
||||
{
|
||||
return new Vector3(a.x % b.x, a.y % b.y, a.z % b.z);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Mode(this Vector3 a, float b)
|
||||
{
|
||||
return new Vector3(a.x % b, a.y % b, a.z % b);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Sign(this Vector3 vec)
|
||||
=> new Vector3(
|
||||
Math.Sign(vec.x),
|
||||
Math.Sign(vec.y),
|
||||
Math.Sign(vec.z)
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int CeilToInt(this Vector3 vec)
|
||||
=> new Vector3Int((int)Mathf.Ceil(vec.x), (int)Mathf.Ceil(vec.y), (int)Mathf.Ceil(vec.z));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Ceil(this Vector3 vec)
|
||||
=> new Vector3(Mathf.Ceil(vec.x), Mathf.Ceil(vec.y), Mathf.Ceil(vec.z));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int RoundToInt(this Vector3 vec)
|
||||
=> new Vector3Int((int)Mathf.Round(vec.x), (int)Mathf.Round(vec.y), (int)Mathf.Round(vec.z));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Round(this Vector3 vec)
|
||||
=> new Vector3(Mathf.Round(vec.x), Mathf.Round(vec.y), Mathf.Round(vec.z));
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int FloorToInt(this Vector3 vec)
|
||||
=> new Vector3Int((int)vec.x, (int)vec.y, (int)vec.z);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Floor(this Vector3 vec)
|
||||
=> new Vector3((int)vec.x, (int)vec.y, (int)vec.z);
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Min(this Vector3 a, Vector3 b)
|
||||
{
|
||||
return new Vector3(Math.Min(a.x, b.x), Math.Min(a.y, b.y), Math.Min(a.z, b.z));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Max(this Vector3 a, Vector3 b)
|
||||
{
|
||||
return new Vector3(Math.Max(a.x, b.x), Math.Max(a.y, b.y), Math.Max(a.z, b.z));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float MinElement(this Vector3 a)
|
||||
{
|
||||
return Math.Min(Math.Min(a.x, a.y), a.z);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static float MaxElement(this Vector3 a)
|
||||
{
|
||||
return Math.Max(Math.Max(a.x, a.y), a.z);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Abs(this Vector3 a)
|
||||
{
|
||||
return new Vector3(Mathf.Abs(a.x), Mathf.Abs(a.y), Mathf.Abs(a.z));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Negative(this Vector3 a)
|
||||
=> new Vector3(-a.x, -a.y, -a.z);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 李若辰规定的编辑表面坐标转换方法
|
||||
/// </summary>
|
||||
/// <param name="vec"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector2 ToVector2(this Vector3 vec)
|
||||
=> new Vector2(vec.x, vec.z);
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static Vector2 ToVector2(this Vector3 vec, string format)
|
||||
{
|
||||
Vector2 result = new Vector2();
|
||||
for(int i = 0; i < format.Length && i < 2; i++)
|
||||
{
|
||||
int index = MacroMath.MinPositive(format[i] - 'X', format[i] - 'x');
|
||||
result[index] = format[i] switch
|
||||
{
|
||||
'x' => vec.x,
|
||||
'X' => vec.x,
|
||||
'y' => vec.y,
|
||||
'Y' => vec.y,
|
||||
'z' => vec.z,
|
||||
'Z' => vec.z,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
public static Vector3 AxisZero(this Vector3 vec, string format)
|
||||
{
|
||||
Vector3 result = vec;
|
||||
for(int i = 0; i < format.Length && i < 2; i++)
|
||||
{
|
||||
int index = MacroMath.MinPositive(format[i] - 'X', format[i] - 'x');
|
||||
result[index] = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将这个向量投影到一个给定坐标的向上的平面上,同时变换到平面坐标
|
||||
/// </summary>
|
||||
/// <param name="vec">矢量或坐标</param>
|
||||
/// <param name="planeOrigin">平面原点</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 ProjectToUpPlane(this Vector3 vec, Vector3 planeOrigin)
|
||||
=> vec - new Vector3(0, (vec - planeOrigin).y, 0);
|
||||
|
||||
/// <summary>
|
||||
/// 向量吸附到网格上,在比例中央不进行吸附
|
||||
/// </summary>
|
||||
/// <param name="vec">矢量或坐标</param>
|
||||
/// <param name="offset">偏移量</param>
|
||||
/// <param name="unit">网格单位</param>
|
||||
/// <param name="thresholdPorp">阈值比例[0-1]</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 CoordinateGridAdsorb(this Vector3 vec, Vector3 offset, float unit, float thresholdPorp)
|
||||
{
|
||||
Vector3 vecInUnit = (vec + offset).Mode(unit);
|
||||
Vector3 sig = vecInUnit.Sign() * unit / 2;
|
||||
Vector3 dis = sig - vecInUnit;
|
||||
Vector3 drive = dis.Abs().Sub(unit * thresholdPorp).Sign();
|
||||
Vector3 ofs = (dis - sig).Mul(drive * 2) + vecInUnit;
|
||||
return ofs;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向量吸附到网格上
|
||||
/// </summary>
|
||||
/// <param name="vec">矢量或坐标</param>
|
||||
/// <param name="offset">偏移量</param>
|
||||
/// <param name="unit">网格单位</param>
|
||||
/// <param name="thresholdPorp">阈值比例[0-1]</param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 CoordinateGridAdsorbRound(this Vector3 vec, Vector3 offset, float unit)
|
||||
{
|
||||
return ((vec + offset) / unit).Round() * unit;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 矢量正交化
|
||||
/// </summary>
|
||||
/// <param name="vec"></param>
|
||||
/// <returns></returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3 Orthogonalization(this Vector3 vec)
|
||||
=> new Vector3(
|
||||
(float)Math.Round(vec.x),
|
||||
(float)Math.Round(vec.y),
|
||||
(float)Math.Round(vec.z)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class Vector3IntExtend
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Add(this Vector3Int a, Vector3Int b)
|
||||
=> new Vector3Int(
|
||||
a.x + b.x,
|
||||
a.y + b.y,
|
||||
a.z + b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Add(this Vector3Int a, Vector3 b)
|
||||
=> new Vector3Int(
|
||||
(int)(a.x + b.x),
|
||||
(int)(a.y + b.y),
|
||||
(int)(a.z + b.z)
|
||||
);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Add(this Vector3Int a, int b)
|
||||
=> new Vector3Int(
|
||||
a.x + b,
|
||||
a.y + b,
|
||||
a.z + b
|
||||
);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Sub(this Vector3Int a, Vector3Int b)
|
||||
=> new Vector3Int(
|
||||
a.x - b.x,
|
||||
a.y - b.y,
|
||||
a.z - b.z
|
||||
);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Sub(this Vector3Int a, Vector3 b)
|
||||
=> new Vector3Int(
|
||||
(int)(a.x - b.x),
|
||||
(int)(a.y - b.y),
|
||||
(int)(a.z - b.z)
|
||||
);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Sub(this Vector3Int a, int b)
|
||||
=> new Vector3Int(
|
||||
a.x - b,
|
||||
a.y - b,
|
||||
a.z - b
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Mul(this Vector3Int a, Vector3Int b)
|
||||
=> new Vector3Int(
|
||||
a.x * b.x,
|
||||
a.y * b.y,
|
||||
a.z * b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Mul(this Vector3Int a, Vector3 b)
|
||||
=> new Vector3Int(
|
||||
(int)(a.x * b.x),
|
||||
(int)(a.y * b.y),
|
||||
(int)(a.z * b.z)
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Mul(this Vector3Int a, int b)
|
||||
=> new Vector3Int(
|
||||
a.x * b,
|
||||
a.y * b,
|
||||
a.z * b
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Div(this Vector3Int a, Vector3Int b)
|
||||
=> new Vector3Int(
|
||||
a.x / b.x,
|
||||
a.y / b.y,
|
||||
a.z / b.z
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Div(this Vector3Int a, Vector3 b)
|
||||
=> new Vector3Int(
|
||||
(int)(a.x / b.x),
|
||||
(int)(a.y / b.y),
|
||||
(int)(a.z / b.z)
|
||||
);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Div(this Vector3Int a, int b)
|
||||
=> new Vector3Int(
|
||||
a.x / b,
|
||||
a.y / b,
|
||||
a.z / b
|
||||
);
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Negative(this Vector3Int a)
|
||||
=> new Vector3Int(-a.x, -a.y, -a.z);
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Min(this Vector3Int a, Vector3Int b)
|
||||
{
|
||||
return new Vector3Int(Math.Min(a.x, b.x), Math.Min(a.y, b.y), Math.Min(a.z, b.z));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Vector3Int Max(this Vector3Int a, Vector3Int b)
|
||||
{
|
||||
return new Vector3Int(Math.Max(a.x, b.x), Math.Max(a.y, b.y), Math.Max(a.z, b.z));
|
||||
}
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsValid(this Vector3Int lhs)
|
||||
{
|
||||
return lhs.x >= 0 && lhs.y >= 0 && lhs.z >= 0;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsInIndexRange(this Vector3Int lhs, Vector3Int max)
|
||||
{
|
||||
return
|
||||
lhs.x.IsInIndexRange(0, max.x) &&
|
||||
lhs.y.IsInIndexRange(0, max.y) &&
|
||||
lhs.z.IsInIndexRange(0, max.z);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61faf554d3acd9b49ad13a6b5697336b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user