987 lines
24 KiB
C#
987 lines
24 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Runtime.CompilerServices;
|
||
|
||
using UnityEngine;
|
||
|
||
namespace XericLibrary.Runtime.MacroLibrary
|
||
{
|
||
public static class Vector3Extend
|
||
{
|
||
#region ËÄÔòÔËËã
|
||
|
||
[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 OneMinus(this Vector3 a)
|
||
=> new Vector3(1 - a.x, 1 - a.y, 1 - a.z);
|
||
|
||
#endregion
|
||
|
||
#region ÆÆ»µÔËËã
|
||
|
||
[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);
|
||
|
||
[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;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region À©Õ¹ÔËËã
|
||
|
||
[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);
|
||
|
||
/// <summary>
|
||
/// Pows each element of the vector.
|
||
/// </summary>
|
||
/// <param name="v"></param>
|
||
/// <param name="p"></param>
|
||
/// <returns></returns>
|
||
public static Vector3 Pow(this Vector3 v, float p)
|
||
{
|
||
v.x = Mathf.Pow(v.x, p);
|
||
v.y = Mathf.Pow(v.y, p);
|
||
v.z = Mathf.Pow(v.z, p);
|
||
return v;
|
||
}
|
||
|
||
|
||
|
||
public static float Distance(this Vector3 a, Vector3 b)
|
||
=> Vector3.Distance(a, b);
|
||
|
||
#endregion
|
||
|
||
#region ÌØÊâÔËËã
|
||
|
||
/// <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)
|
||
{
|
||
Vector3[] axes = { Vector3.right, Vector3.up, Vector3.forward };
|
||
float minAngle = float.MaxValue;
|
||
Vector3 minAngleAxis = Vector3.zero;
|
||
|
||
foreach(Vector3 axis in axes)
|
||
{
|
||
float dot = Vector3.Dot(vec, axis);
|
||
float angle = Mathf.Abs(dot);
|
||
if(angle < minAngle)
|
||
{
|
||
minAngle = angle;
|
||
minAngleAxis = axis * Mathf.Sign(dot);
|
||
}
|
||
}
|
||
|
||
return minAngleAxis;
|
||
}
|
||
|
||
/// <summary>
|
||
/// »ñÈ¡ÓëÊÀ½çÕý½»Öá×î½üµÄÒ»ÌõÖáÏß
|
||
/// </summary>
|
||
/// <param name="vector"></param>
|
||
/// <returns></returns>
|
||
[Obsolete("¿ÉÒÔʹÓÃOrthogonalization´úÌæ")]
|
||
public static Vector3 GetWorldNormalAxis(this Vector3 vec)
|
||
{
|
||
return vec.Orthogonalization();
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region δÕûÀí
|
||
|
||
private const float ZERO_TOLERANCE = 1E-06f;
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Distance from a point to a line.
|
||
public static float PointDistanceToLine(Vector3 point, Vector3 a, Vector3 b)
|
||
{
|
||
return Mathf.Abs((b.x - a.x) * (a.y - point.y) - (a.x - point.x) * (b.y - a.y)) / Mathf.Sqrt(Mathf.Pow(b.x - a.x, 2f) + Mathf.Pow(b.y - a.y, 2f));
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a smooth value between start and end based on t.
|
||
//
|
||
// ²ÎÊý:
|
||
// start:
|
||
// First point.
|
||
//
|
||
// end:
|
||
// Second point.
|
||
//
|
||
// t:
|
||
// Position between 0 and 1.
|
||
public static float Hermite(float start, float end, float t)
|
||
{
|
||
return Mathf.Lerp(start, end, t * t * (3f - 2f * t));
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a smooth value between start and end based on t.
|
||
//
|
||
// ²ÎÊý:
|
||
// start:
|
||
// First point.
|
||
//
|
||
// end:
|
||
// Second point.
|
||
//
|
||
// t:
|
||
// Position between 0 and 1.
|
||
//
|
||
// count:
|
||
// Number of interpolations to make.
|
||
public static float StackHermite(float start, float end, float t, int count)
|
||
{
|
||
for(int i = 0; i < count; i++)
|
||
{
|
||
t = Hermite(start, end, t);
|
||
}
|
||
|
||
return t;
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns the fractional of the value.
|
||
//
|
||
// ²ÎÊý:
|
||
// value:
|
||
// The value to get the fractional of.
|
||
public static float Fract(float value)
|
||
{
|
||
return value - (float)Math.Truncate(value);
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns the fractional of the value.
|
||
//
|
||
// ²ÎÊý:
|
||
// value:
|
||
// The value to get the fractional of.
|
||
public static Vector2 Fract(Vector2 value)
|
||
{
|
||
return new Vector3(Fract(value.x), Fract(value.y));
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns the fractional of the value.
|
||
//
|
||
// ²ÎÊý:
|
||
// value:
|
||
// The value to get the fractional of.
|
||
public static Vector3 Fract(Vector3 value)
|
||
{
|
||
return new Vector3(Fract(value.x), Fract(value.y), Fract(value.z));
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a value based on t, that bounces faster and faster.
|
||
//
|
||
// ²ÎÊý:
|
||
// t:
|
||
// The value to bounce.
|
||
public static float BounceEaseInFastOut(float t)
|
||
{
|
||
return Mathf.Cos(t * t * (float)Math.PI * 2f) * -0.5f + 0.5f;
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a smooth value between 0 and 1 based on t.
|
||
//
|
||
// ²ÎÊý:
|
||
// t:
|
||
// Position between 0 and 1.
|
||
public static float Hermite01(float t)
|
||
{
|
||
return Mathf.Lerp(0f, 1f, t * t * (3f - 2f * t));
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a smooth value between 0 and 1 based on t.
|
||
//
|
||
// ²ÎÊý:
|
||
// t:
|
||
// Position between 0 and 1.
|
||
//
|
||
// count:
|
||
// Number of interpolations to make.
|
||
public static float StackHermite01(float t, int count)
|
||
{
|
||
for(int i = 0; i < count; i++)
|
||
{
|
||
t = Hermite01(t);
|
||
}
|
||
|
||
return t;
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns an unclamped linear interpolation of two vectors.
|
||
//
|
||
// ²ÎÊý:
|
||
// from:
|
||
// The first vector.
|
||
//
|
||
// to:
|
||
// The second vector.
|
||
//
|
||
// amount:
|
||
// The interpolation factor.
|
||
public static Vector3 LerpUnclamped(Vector3 from, Vector3 to, float amount)
|
||
{
|
||
return from + (to - from) * amount;
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns an unclamped linear interpolation of two vectors.
|
||
//
|
||
// ²ÎÊý:
|
||
// from:
|
||
// The first vector.
|
||
//
|
||
// to:
|
||
// The second vector.
|
||
//
|
||
// amount:
|
||
// The interpolation factor.
|
||
public static Vector2 LerpUnclamped(Vector2 from, Vector2 to, float amount)
|
||
{
|
||
return from + (to - from) * amount;
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a value that bounces between 0 and 1 based on value.
|
||
//
|
||
// ²ÎÊý:
|
||
// value:
|
||
// The value to bounce.
|
||
public static float Bounce(float value)
|
||
{
|
||
return Mathf.Abs(Mathf.Sin(value % 1f * (float)Math.PI));
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a value that eases in elasticly.
|
||
//
|
||
// ²ÎÊý:
|
||
// value:
|
||
// The value to ease in elasticly.
|
||
//
|
||
// amplitude:
|
||
// The amplitude.
|
||
//
|
||
// length:
|
||
// The length.
|
||
public static float EaseInElastic(float value, float amplitude = 0.25f, float length = 0.6f)
|
||
{
|
||
value = Mathf.Clamp01(value);
|
||
float num = Mathf.Clamp01(value * 7.5f);
|
||
float num2 = 1f - num * num * (3f - 2f * num);
|
||
float num3 = Mathf.Pow(1f - Mathf.Sin(Mathf.Min(value * (1f - length), 0.5f) * (float)Math.PI), 2f);
|
||
float num4 = Mathf.Cos((float)Math.PI + value * 23f) * amplitude + num2 * (0f - (1f - amplitude));
|
||
return 1f + num4 * num3;
|
||
}
|
||
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a value that eases out elasticly.
|
||
//
|
||
// ²ÎÊý:
|
||
// value:
|
||
// The value to ease out elasticly.
|
||
//
|
||
// amplitude:
|
||
// The amplitude.
|
||
//
|
||
// length:
|
||
// The length.
|
||
public static float EaseOutElastic(float value, float amplitude = 0.25f, float length = 0.6f)
|
||
{
|
||
return 1f - EaseInElastic(1f - value, amplitude, length);
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns a smooth value betweeen that peaks at t=0.5 and then comes back down
|
||
// again.
|
||
//
|
||
// ²ÎÊý:
|
||
// t:
|
||
// A value between 0 and 1.
|
||
public static float EaseInOut(float t)
|
||
{
|
||
t = 1f - Mathf.Abs(Mathf.Clamp01(t) * 2f - 1f);
|
||
t = t * t * (3f - 2f * t);
|
||
return t;
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Clamps the value of a Vector3.
|
||
//
|
||
// ²ÎÊý:
|
||
// value:
|
||
// The vector to clamp.
|
||
//
|
||
// min:
|
||
// The min value.
|
||
//
|
||
// max:
|
||
// The max value.
|
||
public static Vector3 Clamp(this Vector3 value, Vector3 min, Vector3 max)
|
||
{
|
||
return new Vector3(Mathf.Clamp(value.x, min.x, max.x), Mathf.Clamp(value.y, min.y, max.y), Mathf.Clamp(value.z, min.z, max.z));
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Clamps the value of a Vector2.
|
||
//
|
||
// ²ÎÊý:
|
||
// value:
|
||
// The vector to clamp.
|
||
//
|
||
// min:
|
||
// The min value.
|
||
//
|
||
// max:
|
||
// The max value.
|
||
public static Vector2 Clamp(this Vector2 value, Vector2 min, Vector2 max)
|
||
{
|
||
return new Vector2(Mathf.Clamp(value.x, min.x, max.x), Mathf.Clamp(value.y, min.y, max.y));
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Computes a hash for a byte array.
|
||
//
|
||
// ²ÎÊý:
|
||
// data:
|
||
// The byte array.
|
||
public static int ComputeByteArrayHash(byte[] data)
|
||
{
|
||
int num = -2128831035;
|
||
for(int i = 0; i < data.Length; i++)
|
||
{
|
||
num = (num ^ data[i]) * 16777619;
|
||
}
|
||
|
||
num += num << 13;
|
||
num ^= num >> 7;
|
||
num += num << 3;
|
||
num ^= num >> 17;
|
||
return num + (num << 5);
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Gives a smooth path between a collection of points.
|
||
//
|
||
// ²ÎÊý:
|
||
// path:
|
||
// The collection of point.
|
||
//
|
||
// t:
|
||
// The current position in the path. 0 is at the start of the path, 1 is at the
|
||
// end of the path.
|
||
public static Vector3 InterpolatePoints(Vector3[] path, float t)
|
||
{
|
||
t = Mathf.Clamp01(t * (1f - 1f / (float)path.Length));
|
||
int b = path.Length - 1;
|
||
int num = Mathf.FloorToInt(t * (float)path.Length);
|
||
float num2 = t * (float)path.Length - (float)num;
|
||
Vector3 vector = path[Mathf.Max(0, --num)];
|
||
Vector3 vector2 = path[Mathf.Min(num + 1, b)];
|
||
Vector3 vector3 = path[Mathf.Min(num + 2, b)];
|
||
Vector3 vector4 = path[Mathf.Min(num + 3, b)];
|
||
return 0.5f * ((-vector + 3f * vector2 - 3f * vector3 + vector4) * (num2 * num2 * num2) + (2f * vector - 5f * vector2 + 4f * vector3 - vector4) * (num2 * num2) + (-vector + vector3) * num2 + 2f * vector2);
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Checks if two given lines intersect with one another and returns the intersection
|
||
// point (if any) in an out parameter. Source: http://stackoverflow.com/questions/3746274/line-intersection-with-aabb-rectangle.
|
||
// Edited to implement Cohen-Sutherland type pruning for efficiency.
|
||
//
|
||
// ²ÎÊý:
|
||
// a1:
|
||
// Starting point of line a.
|
||
//
|
||
// a2:
|
||
// Ending point of line a.
|
||
//
|
||
// b1:
|
||
// Starting point of line b.
|
||
//
|
||
// b2:
|
||
// Ending point of line b.
|
||
//
|
||
// intersection:
|
||
// The out parameter which contains the intersection point if there was any.
|
||
//
|
||
// ·µ»Ø½á¹û:
|
||
// True if the two lines intersect, otherwise false.
|
||
public static bool LineIntersectsLine(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2, out Vector2 intersection)
|
||
{
|
||
intersection = Vector2.zero;
|
||
Vector2 vector = new Vector2((b1.x < b2.x) ? b1.x : b2.x, (b1.y > b2.y) ? b1.y : b2.y);
|
||
Vector2 vector2 = new Vector2((b1.x > b2.x) ? b1.x : b2.x, (b1.y < b2.y) ? b1.y : b2.y);
|
||
if((a1.x < vector.x && a2.x < vector.x) || (a1.y > vector.y && a2.y > vector.y) || (a1.x > vector2.x && a2.x > vector2.x) || (a1.y < vector2.y && a2.y < vector2.y))
|
||
{
|
||
return false;
|
||
}
|
||
|
||
Vector2 vector3 = a2 - a1;
|
||
Vector2 vector4 = b2 - b1;
|
||
float num = vector3.x * vector4.y - vector3.y * vector4.x;
|
||
if(num == 0f)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
Vector2 vector5 = b1 - a1;
|
||
float num2 = (vector5.x * vector4.y - vector5.y * vector4.x) / num;
|
||
if(num2 < 0f || num2 > 1f)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
float num3 = (vector5.x * vector3.y - vector5.y * vector3.x) / num;
|
||
if(num3 < 0f || num3 > 1f)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
intersection = a1 + num2 * vector3;
|
||
return true;
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Returns the collision point between two infinite lines.
|
||
public static Vector2 InfiniteLineIntersect(Vector2 ps1, Vector2 pe1, Vector2 ps2, Vector2 pe2)
|
||
{
|
||
float num = pe1.y - ps1.y;
|
||
float num2 = ps1.x - pe1.x;
|
||
float num3 = num * ps1.x + num2 * ps1.y;
|
||
float num4 = pe2.y - ps2.y;
|
||
float num5 = ps2.x - pe2.x;
|
||
float num6 = num4 * ps2.x + num5 * ps2.y;
|
||
float num7 = num * num5 - num4 * num2;
|
||
if(num7 == 0f)
|
||
{
|
||
throw new Exception("Lines are parallel");
|
||
}
|
||
|
||
return new Vector2((num5 * num3 - num2 * num6) / num7, (num * num6 - num4 * num3) / num7);
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Distance from line to plane.
|
||
//
|
||
// ²ÎÊý:
|
||
// planeOrigin:
|
||
// Position of the plane.
|
||
//
|
||
// planeNormal:
|
||
// Surface normal of the plane.
|
||
//
|
||
// lineOrigin:
|
||
// Origin of the line.
|
||
//
|
||
// lineDirectionNormalized:
|
||
// Line direction normal.
|
||
public static float LineDistToPlane(Vector3 planeOrigin, Vector3 planeNormal, Vector3 lineOrigin, Vector3 lineDirectionNormalized)
|
||
{
|
||
return Vector3.Dot(lineDirectionNormalized, planeNormal) * Vector3.Distance(planeOrigin, lineOrigin);
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Distance from ray to plane.
|
||
//
|
||
// ²ÎÊý:
|
||
// ray:
|
||
// The ray.
|
||
//
|
||
// plane:
|
||
// The plane.
|
||
public static float RayDistToPlane(Ray ray, Plane plane)
|
||
{
|
||
float num = Vector3.Dot(plane.normal, ray.direction);
|
||
if(Mathf.Abs(num) < 1E-06f)
|
||
{
|
||
return 0f;
|
||
}
|
||
|
||
float num2 = Vector3.Dot(plane.normal, ray.origin);
|
||
return (0f - plane.distance - num2) / num;
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Rotates a Vector2 by an angle.
|
||
//
|
||
// ²ÎÊý:
|
||
// point:
|
||
// The point to rotate.
|
||
//
|
||
// degrees:
|
||
// The angle to rotate.
|
||
public static Vector2 RotatePoint(Vector2 point, float degrees)
|
||
{
|
||
float f = degrees * ((float)Math.PI / 180f);
|
||
float num = Mathf.Cos(f);
|
||
float num2 = Mathf.Sin(f);
|
||
return new Vector2(num * point.x - num2 * point.y, num2 * point.x + num * point.y);
|
||
}
|
||
|
||
//
|
||
// ÕªÒª:
|
||
// Rotates a Vector2 around a point by an angle..
|
||
//
|
||
// ²ÎÊý:
|
||
// point:
|
||
// The point to rotate.
|
||
//
|
||
// around:
|
||
// The point to rotate around.
|
||
//
|
||
// degrees:
|
||
// The angle to rotate.
|
||
public static Vector2 RotatePoint(Vector2 point, Vector2 around, float degrees)
|
||
{
|
||
float f = degrees * ((float)Math.PI / 180f);
|
||
float num = Mathf.Cos(f);
|
||
float num2 = Mathf.Sin(f);
|
||
return new Vector2(num * (point.x - around.x) - num2 * (point.y - around.y) + around.x, num2 * (point.x - around.x) + num * (point.y - around.y) + around.y);
|
||
}
|
||
|
||
#endregion
|
||
|
||
}
|
||
|
||
|
||
|
||
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);
|
||
}
|
||
|
||
}
|
||
}
|