187 lines
4.3 KiB
C#
187 lines
4.3 KiB
C#
using System;
|
|
using UnityEngine;
|
|
|
|
namespace RootMotion
|
|
{
|
|
public static class QuaTools
|
|
{
|
|
public static Quaternion Lerp(Quaternion fromRotation, Quaternion toRotation, float weight)
|
|
{
|
|
if (weight <= 0f)
|
|
{
|
|
return fromRotation;
|
|
}
|
|
if (weight >= 1f)
|
|
{
|
|
return toRotation;
|
|
}
|
|
return Quaternion.Lerp(fromRotation, toRotation, weight);
|
|
}
|
|
|
|
public static Quaternion Slerp(Quaternion fromRotation, Quaternion toRotation, float weight)
|
|
{
|
|
if (weight <= 0f)
|
|
{
|
|
return fromRotation;
|
|
}
|
|
if (weight >= 1f)
|
|
{
|
|
return toRotation;
|
|
}
|
|
return Quaternion.Slerp(fromRotation, toRotation, weight);
|
|
}
|
|
|
|
public static Quaternion LinearBlend(Quaternion q, float weight)
|
|
{
|
|
if (weight <= 0f)
|
|
{
|
|
return Quaternion.identity;
|
|
}
|
|
if (weight >= 1f)
|
|
{
|
|
return q;
|
|
}
|
|
return Quaternion.Lerp(Quaternion.identity, q, weight);
|
|
}
|
|
|
|
public static Quaternion SphericalBlend(Quaternion q, float weight)
|
|
{
|
|
if (weight <= 0f)
|
|
{
|
|
return Quaternion.identity;
|
|
}
|
|
if (weight >= 1f)
|
|
{
|
|
return q;
|
|
}
|
|
return Quaternion.Slerp(Quaternion.identity, q, weight);
|
|
}
|
|
|
|
public static Quaternion FromToAroundAxis(Vector3 fromDirection, Vector3 toDirection, Vector3 axis)
|
|
{
|
|
Quaternion quaternion = Quaternion.FromToRotation(fromDirection, toDirection);
|
|
float angle = 0f;
|
|
Vector3 axis2 = Vector3.zero;
|
|
quaternion.ToAngleAxis(out angle, out axis2);
|
|
if (Vector3.Dot(axis2, axis) < 0f)
|
|
{
|
|
angle = 0f - angle;
|
|
}
|
|
return Quaternion.AngleAxis(angle, axis);
|
|
}
|
|
|
|
public static Quaternion RotationToLocalSpace(Quaternion space, Quaternion rotation)
|
|
{
|
|
return Quaternion.Inverse(Quaternion.Inverse(space) * rotation);
|
|
}
|
|
|
|
public static Quaternion FromToRotation(Quaternion from, Quaternion to)
|
|
{
|
|
if (to == from)
|
|
{
|
|
return Quaternion.identity;
|
|
}
|
|
return to * Quaternion.Inverse(from);
|
|
}
|
|
|
|
public static Vector3 GetAxis(Vector3 v)
|
|
{
|
|
Vector3 vector = Vector3.right;
|
|
bool flag = false;
|
|
float num = Vector3.Dot(v, Vector3.right);
|
|
float num2 = Mathf.Abs(num);
|
|
if (num < 0f)
|
|
{
|
|
flag = true;
|
|
}
|
|
float num3 = Vector3.Dot(v, Vector3.up);
|
|
float num4 = Mathf.Abs(num3);
|
|
if (num4 > num2)
|
|
{
|
|
num2 = num4;
|
|
vector = Vector3.up;
|
|
flag = num3 < 0f;
|
|
}
|
|
float num5 = Vector3.Dot(v, Vector3.forward);
|
|
num4 = Mathf.Abs(num5);
|
|
if (num4 > num2)
|
|
{
|
|
vector = Vector3.forward;
|
|
flag = num5 < 0f;
|
|
}
|
|
if (flag)
|
|
{
|
|
vector = -vector;
|
|
}
|
|
return vector;
|
|
}
|
|
|
|
public static Quaternion ClampRotation(Quaternion rotation, float clampWeight, int clampSmoothing)
|
|
{
|
|
if (clampWeight >= 1f)
|
|
{
|
|
return Quaternion.identity;
|
|
}
|
|
if (clampWeight <= 0f)
|
|
{
|
|
return rotation;
|
|
}
|
|
float num = Quaternion.Angle(Quaternion.identity, rotation);
|
|
float num2 = 1f - num / 180f;
|
|
float num3 = Mathf.Clamp(1f - (clampWeight - num2) / (1f - num2), 0f, 1f);
|
|
float num4 = Mathf.Clamp(num2 / clampWeight, 0f, 1f);
|
|
for (int i = 0; i < clampSmoothing; i++)
|
|
{
|
|
num4 = Mathf.Sin(num4 * MathF.PI * 0.5f);
|
|
}
|
|
return Quaternion.Slerp(Quaternion.identity, rotation, num4 * num3);
|
|
}
|
|
|
|
public static float ClampAngle(float angle, float clampWeight, int clampSmoothing)
|
|
{
|
|
if (clampWeight >= 1f)
|
|
{
|
|
return 0f;
|
|
}
|
|
if (clampWeight <= 0f)
|
|
{
|
|
return angle;
|
|
}
|
|
float num = 1f - Mathf.Abs(angle) / 180f;
|
|
float num2 = Mathf.Clamp(1f - (clampWeight - num) / (1f - num), 0f, 1f);
|
|
float num3 = Mathf.Clamp(num / clampWeight, 0f, 1f);
|
|
for (int i = 0; i < clampSmoothing; i++)
|
|
{
|
|
num3 = Mathf.Sin(num3 * MathF.PI * 0.5f);
|
|
}
|
|
return Mathf.Lerp(0f, angle, num3 * num2);
|
|
}
|
|
|
|
public static Quaternion MatchRotation(Quaternion targetRotation, Vector3 targetforwardAxis, Vector3 targetUpAxis, Vector3 forwardAxis, Vector3 upAxis)
|
|
{
|
|
Quaternion rotation = Quaternion.LookRotation(forwardAxis, upAxis);
|
|
Quaternion quaternion = Quaternion.LookRotation(targetforwardAxis, targetUpAxis);
|
|
return targetRotation * quaternion * Quaternion.Inverse(rotation);
|
|
}
|
|
|
|
public static Vector3 ToBiPolar(Vector3 euler)
|
|
{
|
|
return new Vector3(ToBiPolar(euler.x), ToBiPolar(euler.y), ToBiPolar(euler.z));
|
|
}
|
|
|
|
public static float ToBiPolar(float angle)
|
|
{
|
|
angle %= 360f;
|
|
if (angle >= 180f)
|
|
{
|
|
return angle - 360f;
|
|
}
|
|
if (angle <= -180f)
|
|
{
|
|
return angle + 360f;
|
|
}
|
|
return angle;
|
|
}
|
|
}
|
|
}
|