796 lines
18 KiB
C#
796 lines
18 KiB
C#
using System;
|
|
|
|
using Int8 = System.SByte;
|
|
using UInt8 = System.Byte;
|
|
|
|
public static class ViMathDefine
|
|
{
|
|
public static readonly float PI = 3.141593f;
|
|
public static readonly float PI_X2 = PI * 2;
|
|
public static readonly float PI_X3 = PI * 3;
|
|
public static readonly float PI_X4 = PI * 4;
|
|
public static readonly float PI_HALF = PI * 0.5f;
|
|
public static readonly float Infinity = float.PositiveInfinity;
|
|
public static readonly float NegativeInfinity = float.NegativeInfinity;
|
|
public static readonly float Deg2Rad = 0.01745329f;
|
|
public static readonly float Rad2Deg = 57.29578f;
|
|
public static readonly float Epsilon = float.Epsilon;
|
|
public static float Sin(float f)
|
|
{
|
|
return (float)Math.Sin((double)f);
|
|
}
|
|
|
|
public static float Cos(float f)
|
|
{
|
|
return (float)Math.Cos((double)f);
|
|
}
|
|
|
|
public static float Tan(float f)
|
|
{
|
|
return (float)Math.Tan((double)f);
|
|
}
|
|
|
|
public static float Asin(float f)
|
|
{
|
|
return (float)Math.Asin((double)f);
|
|
}
|
|
|
|
public static float Acos(float f)
|
|
{
|
|
return (float)Math.Acos((double)f);
|
|
}
|
|
|
|
public static float Atan(float f)
|
|
{
|
|
return (float)Math.Atan((double)f);
|
|
}
|
|
|
|
public static float Atan2(float y, float x)
|
|
{
|
|
return (float)Math.Atan2((double)y, (double)x);
|
|
}
|
|
|
|
public static float Sqrt(float f)
|
|
{
|
|
return (float)Math.Sqrt((double)f);
|
|
}
|
|
|
|
public static Int32 IntInf(float value)
|
|
{
|
|
if (value >= 0)
|
|
{
|
|
return (Int32)value;
|
|
}
|
|
else
|
|
{
|
|
return (Int32)(value - 0.999f);
|
|
}
|
|
}
|
|
public static Int32 IntSup(float value)
|
|
{
|
|
if (value >= 0)
|
|
{
|
|
return (Int32)(value + 0.999f);
|
|
}
|
|
else
|
|
{
|
|
return (Int32)value;
|
|
}
|
|
}
|
|
public static UInt32 IntSup(Int32 total, Int32 span)
|
|
{
|
|
if (span <= 0 || total < 0)
|
|
{
|
|
return 0;
|
|
}
|
|
return (UInt32)((total + span - 1) / span);
|
|
}
|
|
public static UInt32 IntSup(UInt32 total, UInt32 span)
|
|
{
|
|
if (span == 0)
|
|
{
|
|
return total;
|
|
}
|
|
return (total + span - 1) / span;
|
|
}
|
|
public static Int32 IntNear(float value)
|
|
{
|
|
if (value >= 0)
|
|
{
|
|
return (Int32)(value + 0.5f);
|
|
}
|
|
else
|
|
{
|
|
return (Int32)(value - 0.5f);
|
|
}
|
|
}
|
|
|
|
public static float Abs(float value)
|
|
{
|
|
return Math.Abs(value);
|
|
}
|
|
public static Int8 Abs(Int8 value)
|
|
{
|
|
return Math.Abs(value);
|
|
}
|
|
public static Int16 Abs(Int16 value)
|
|
{
|
|
return Math.Abs(value);
|
|
}
|
|
public static Int32 Abs(Int32 value)
|
|
{
|
|
return Math.Abs(value);
|
|
}
|
|
public static Int64 Abs(Int64 value)
|
|
{
|
|
return Math.Abs(value);
|
|
}
|
|
public static float Min(float a, float b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static double Min(double a, double b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static Int8 Min(Int8 a, Int8 b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static UInt8 Min(UInt8 a, UInt8 b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static Int16 Min(Int16 a, Int16 b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static UInt16 Min(UInt16 a, UInt16 b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static Int32 Min(Int32 a, Int32 b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static UInt32 Min(UInt32 a, UInt32 b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static Int64 Min(Int64 a, Int64 b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static UInt64 Min(UInt64 a, UInt64 b)
|
|
{
|
|
return ((a >= b) ? b : a);
|
|
}
|
|
public static float Min(params float[] values)
|
|
{
|
|
int length = values.Length;
|
|
if (length == 0)
|
|
{
|
|
return 0f;
|
|
}
|
|
float num2 = values[0];
|
|
for (int i = 1; i < length; i++)
|
|
{
|
|
if (values[i] < num2)
|
|
{
|
|
num2 = values[i];
|
|
}
|
|
}
|
|
return num2;
|
|
}
|
|
public static int Min(params int[] values)
|
|
{
|
|
int length = values.Length;
|
|
if (length == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
int num2 = values[0];
|
|
for (int i = 1; i < length; i++)
|
|
{
|
|
if (values[i] < num2)
|
|
{
|
|
num2 = values[i];
|
|
}
|
|
}
|
|
return num2;
|
|
}
|
|
public static float Max(float a, float b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static double Max(double a, double b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static Int8 Max(Int8 a, Int8 b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static UInt8 Max(UInt8 a, UInt8 b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static Int16 Max(Int16 a, Int16 b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static UInt16 Max(UInt16 a, UInt16 b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static Int32 Max(Int32 a, Int32 b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static UInt32 Max(UInt32 a, UInt32 b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static Int64 Max(Int64 a, Int64 b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static UInt64 Max(UInt64 a, UInt64 b)
|
|
{
|
|
return ((a <= b) ? b : a);
|
|
}
|
|
public static float Max(params float[] values)
|
|
{
|
|
int length = values.Length;
|
|
if (length == 0)
|
|
{
|
|
return 0f;
|
|
}
|
|
float num2 = values[0];
|
|
for (int i = 1; i < length; i++)
|
|
{
|
|
if (values[i] > num2)
|
|
{
|
|
num2 = values[i];
|
|
}
|
|
}
|
|
return num2;
|
|
}
|
|
public static int Max(params int[] values)
|
|
{
|
|
int length = values.Length;
|
|
if (length == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
int num2 = values[0];
|
|
for (int i = 1; i < length; i++)
|
|
{
|
|
if (values[i] > num2)
|
|
{
|
|
num2 = values[i];
|
|
}
|
|
}
|
|
return num2;
|
|
}
|
|
|
|
public static bool InRange(Int8 value, Int8 inf, Int8 sup)
|
|
{
|
|
return inf <= value && value <= sup;
|
|
}
|
|
public static bool InRange(Int16 value, Int16 inf, Int16 sup)
|
|
{
|
|
return inf <= value && value <= sup;
|
|
}
|
|
public static bool InRange(Int32 value, Int32 inf, Int32 sup)
|
|
{
|
|
return inf <= value && value <= sup;
|
|
}
|
|
public static bool InRange(Int64 value, Int64 inf, Int64 sup)
|
|
{
|
|
return inf <= value && value <= sup;
|
|
}
|
|
public static bool InRange(float value, float inf, float sup)
|
|
{
|
|
return inf <= value && value <= sup;
|
|
}
|
|
|
|
public static float Pow(float f, float p)
|
|
{
|
|
return (float)Math.Pow((double)f, (double)p);
|
|
}
|
|
|
|
public static float Exp(float power)
|
|
{
|
|
return (float)Math.Exp((double)power);
|
|
}
|
|
|
|
public static float Log(float f, float p)
|
|
{
|
|
return (float)Math.Log((double)f, (double)p);
|
|
}
|
|
|
|
public static float Log(float f)
|
|
{
|
|
return (float)Math.Log((double)f);
|
|
}
|
|
|
|
public static float Log10(float f)
|
|
{
|
|
return (float)Math.Log10((double)f);
|
|
}
|
|
|
|
public static float Ceil(float f)
|
|
{
|
|
return (float)Math.Ceiling((double)f);
|
|
}
|
|
|
|
public static float Floor(float f)
|
|
{
|
|
return (float)Math.Floor((double)f);
|
|
}
|
|
|
|
public static float Round(float f)
|
|
{
|
|
return (float)Math.Round((double)f);
|
|
}
|
|
|
|
public static int CeilToInt(float f)
|
|
{
|
|
return (int)Math.Ceiling((double)f);
|
|
}
|
|
|
|
public static int FloorToInt(float f)
|
|
{
|
|
return (int)Math.Floor((double)f);
|
|
}
|
|
|
|
public static int RoundToInt(float f)
|
|
{
|
|
return (int)Math.Round((double)f);
|
|
}
|
|
|
|
public static float Float(Int32 numerator, Int32 denominator)
|
|
{
|
|
return (float)(((double)numerator) / ((double)denominator));
|
|
}
|
|
|
|
public static float Sign(float f)
|
|
{
|
|
return ((f < 0f) ? -1f : 1f);
|
|
}
|
|
public static float Radius2Degree(float radius)
|
|
{
|
|
return 180.0f - radius * Rad2Deg;
|
|
}
|
|
public static float Clamp(float value, float min, float max)
|
|
{
|
|
if (value < min)
|
|
{
|
|
value = min;
|
|
return value;
|
|
}
|
|
if (value > max)
|
|
{
|
|
value = max;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public static int Clamp(int value, int min, int max)
|
|
{
|
|
if (value < min)
|
|
{
|
|
value = min;
|
|
return value;
|
|
}
|
|
if (value > max)
|
|
{
|
|
value = max;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public static Int64 Clamp(Int64 value, Int64 min, Int64 max)
|
|
{
|
|
if (value < min)
|
|
{
|
|
value = min;
|
|
return value;
|
|
}
|
|
if (value > max)
|
|
{
|
|
value = max;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public static float Clamp01(float value)
|
|
{
|
|
if (value < 0f)
|
|
{
|
|
return 0f;
|
|
}
|
|
if (value > 1f)
|
|
{
|
|
return 1f;
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public static float Lerp(float from, float to, float t)
|
|
{
|
|
return (from + ((to - from) * Clamp01(t)));
|
|
}
|
|
|
|
public static float Wrap(float val, float low, float high)// 取值范围[low, high)
|
|
{
|
|
float ret = (val);
|
|
float rang = (high - low);
|
|
|
|
while (ret >= high)
|
|
{
|
|
ret -= rang;
|
|
}
|
|
while (ret < low)
|
|
{
|
|
ret += rang;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
public static int Wrap(int val, int low, int high)// 取值范围[low, high)
|
|
{
|
|
int ret = (val);
|
|
int rang = (high - low);
|
|
|
|
while (ret >= high)
|
|
{
|
|
ret -= rang;
|
|
}
|
|
while (ret < low)
|
|
{
|
|
ret += rang;
|
|
}
|
|
return ret;
|
|
}
|
|
public static float MoveTowards(float current, float target, float maxDelta)
|
|
{
|
|
if (Abs((float)(target - current)) <= maxDelta)
|
|
{
|
|
return target;
|
|
}
|
|
return (current + (Sign(target - current) * maxDelta));
|
|
}
|
|
|
|
//public static float MoveTowardsAngle(float current, float target, float maxDelta)
|
|
//{
|
|
// target = current + DeltaAngle(current, target);
|
|
// return MoveTowards(current, target, maxDelta);
|
|
//}
|
|
|
|
public static float SmoothStep(float from, float to, float t)
|
|
{
|
|
t = Clamp01(t);
|
|
t = (((-2f * t) * t) * t) + ((3f * t) * t);
|
|
return ((to * t) + (from * (1f - t)));
|
|
}
|
|
|
|
public static float Gamma(float value, float absmax, float gamma)
|
|
{
|
|
bool flag = false;
|
|
if (value < 0f)
|
|
{
|
|
flag = true;
|
|
}
|
|
float num = Abs(value);
|
|
if (num > absmax)
|
|
{
|
|
return (!flag ? num : -num);
|
|
}
|
|
float num2 = Pow(num / absmax, gamma) * absmax;
|
|
return (!flag ? num2 : -num2);
|
|
}
|
|
|
|
public static bool Approximately(float a, float b)
|
|
{
|
|
return (Abs((float)(b - a)) < Max((float)(1E-06f * Max(Abs(a), Abs(b))), (float)1.121039E-44f));
|
|
}
|
|
|
|
//public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed)
|
|
//{
|
|
// float deltaTime = Time.deltaTime;
|
|
// return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
|
|
//}
|
|
|
|
//public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime)
|
|
//{
|
|
// float deltaTime = Time.deltaTime;
|
|
// float positiveInfinity = float.PositiveInfinity;
|
|
// return SmoothDamp(current, target, ref currentVelocity, smoothTime, positiveInfinity, deltaTime);
|
|
//}
|
|
|
|
//public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed, float deltaTime)
|
|
//{
|
|
// smoothTime = Max(0.0001f, smoothTime);
|
|
// float num = 2f / smoothTime;
|
|
// float num2 = num * deltaTime;
|
|
// float num3 = 1f / (((1f + num2) + ((0.48f * num2) * num2)) + (((0.235f * num2) * num2) * num2));
|
|
// float num4 = current - target;
|
|
// float num5 = target;
|
|
// float max = maxSpeed * smoothTime;
|
|
// num4 = Clamp(num4, -max, max);
|
|
// target = current - num4;
|
|
// float num7 = (currentVelocity + (num * num4)) * deltaTime;
|
|
// currentVelocity = (currentVelocity - (num * num7)) * num3;
|
|
// float num8 = target + ((num4 + num7) * num3);
|
|
// if (((num5 - current) > 0f) == (num8 > num5))
|
|
// {
|
|
// num8 = num5;
|
|
// currentVelocity = (num8 - num5) / deltaTime;
|
|
// }
|
|
// return num8;
|
|
//}
|
|
|
|
//public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed)
|
|
//{
|
|
// float deltaTime = Time.deltaTime;
|
|
// return SmoothDampAngle(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
|
|
//}
|
|
|
|
//public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime)
|
|
//{
|
|
// float deltaTime = Time.deltaTime;
|
|
// float positiveInfinity = float.PositiveInfinity;
|
|
// return SmoothDampAngle(current, target, ref currentVelocity, smoothTime, positiveInfinity, deltaTime);
|
|
//}
|
|
|
|
//public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed, float deltaTime)
|
|
//{
|
|
// target = current + DeltaAngle(current, target);
|
|
// return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
|
|
//}
|
|
|
|
public static float Repeat(float t, float length)
|
|
{
|
|
return (t - (Floor(t / length) * length));
|
|
}
|
|
|
|
public static float PingPong(float t, float length)
|
|
{
|
|
t = Repeat(t, length * 2f);
|
|
return (length - Abs((float)(t - length)));
|
|
}
|
|
|
|
public static float InverseLerp(float from, float to, float value)
|
|
{
|
|
if (from < to)
|
|
{
|
|
if (value < from)
|
|
{
|
|
return 0f;
|
|
}
|
|
if (value > to)
|
|
{
|
|
return 1f;
|
|
}
|
|
value -= from;
|
|
value /= to - from;
|
|
return value;
|
|
}
|
|
if (from <= to)
|
|
{
|
|
return 0f;
|
|
}
|
|
if (value < to)
|
|
{
|
|
return 1f;
|
|
}
|
|
if (value > from)
|
|
{
|
|
return 0f;
|
|
}
|
|
return (1f - ((value - to) / (from - to)));
|
|
}
|
|
}
|
|
|
|
public class ViMath2D
|
|
{
|
|
public static readonly float FRONT_X = 0.0f;
|
|
public static readonly float FRONT_Y = -1.0f;
|
|
|
|
public static float Length(float x, float y)
|
|
{
|
|
return (float)Math.Sqrt(x * x + y * y);
|
|
}
|
|
|
|
public static float Length2(float x, float y)
|
|
{
|
|
return (x * x + y * y);
|
|
}
|
|
public static float Length(float fSrcX, float fSrcY, float fDesX, float fDesY)
|
|
{
|
|
float deltaX = fDesX - fSrcX;
|
|
float deltaY = fDesY - fSrcY;
|
|
return (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
|
|
}
|
|
|
|
public static float Length2(float fSrcX, float fSrcY, float fDesX, float fDesY)
|
|
{
|
|
float deltaX = fDesX - fSrcX;
|
|
float deltaY = fDesY - fSrcY;
|
|
return (deltaX * deltaX + deltaY * deltaY);
|
|
}
|
|
|
|
public static float GetAngle(float fX, float fY)
|
|
{
|
|
float angle = (float)Math.Atan2(fX, -fY);
|
|
return angle;
|
|
}
|
|
public static void CaculateAngle(float fAngle, ref float fX, ref float fY)
|
|
{
|
|
fY = -(float)Math.Cos(fAngle);
|
|
fX = (float)Math.Sin(fAngle);
|
|
}
|
|
public static float GetRotateAngle(float fSrcX, float fSrcy, float fDesX, float fDesY)
|
|
{
|
|
//if(abs(fSrcX) <= 0.001f && abs(fSrcy) <= 0.001f
|
|
// || abs(fDesX) <= 0.001f && abs(fDesY) <= 0.001f)
|
|
//{
|
|
// return 0.0f;
|
|
//}
|
|
float fDesAngle = GetAngle(fDesX, fDesY);
|
|
float fSrcAngle = GetAngle(fSrcX, fSrcy);
|
|
float fRotateAngle = fDesAngle - fSrcAngle;
|
|
// 映射到(-M_PI, M_PI)区间上来
|
|
if (fRotateAngle > ViMathDefine.PI)
|
|
fRotateAngle -= ViMathDefine.PI_X2;
|
|
else if (fRotateAngle < -ViMathDefine.PI)
|
|
fRotateAngle += ViMathDefine.PI_X2;
|
|
return fRotateAngle;
|
|
}
|
|
|
|
public static void Rotate(float fSrcX, float fSrcy, float fRotateAngle, ref float fDesX, ref float fDesY)
|
|
{
|
|
//! 逆时针旋转
|
|
float fSin = (float)Math.Sin(fRotateAngle);
|
|
float fCon = (float)Math.Cos(fRotateAngle);
|
|
//! 顺时针旋转
|
|
//float fSin = sin(-fRotateAngle);
|
|
//float fCon = cos(-fRotateAngle);
|
|
fDesX = fCon * fSrcX - fSin * fSrcy;
|
|
fDesY = fSin * fSrcX + fCon * fSrcy;
|
|
}
|
|
|
|
public static void Rotate(ref float fX, ref float fY, float fRotateAngle)
|
|
{
|
|
float fSin = (float)Math.Sin(fRotateAngle);
|
|
float fCon = (float)Math.Cos(fRotateAngle);
|
|
//! 顺时针旋转
|
|
//float fSin = sin(-fRotateAngle);
|
|
//float fCon = cos(-fRotateAngle);
|
|
float fDesX = fCon * fX - fSin * fY;
|
|
float fDesY = fSin * fX + fCon * fY;
|
|
fX = fDesX;
|
|
fY = fDesY;
|
|
}
|
|
|
|
public static void RotateRight90(ref float x, ref float y)
|
|
{
|
|
float temp = x;
|
|
x = y;
|
|
y = -temp;
|
|
}
|
|
public static void RotateLeft90(ref float x, ref float y)
|
|
{
|
|
float temp = x;
|
|
x = -y;
|
|
y = temp;
|
|
}
|
|
public static int GetSide(float fromX, float fromY, float toX, float toY, float x, float y)
|
|
{
|
|
float s = (fromX - x) * (toY - y) - (fromY - y) * (toX - x);
|
|
if (s == 0)
|
|
{
|
|
return 0;
|
|
}
|
|
else if (s < 0)//! 右侧
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
public static bool GetCross(ViVector3 from, float speed, ViVector3 targetPos, ViVector3 targetVelocity, out float time, out ViVector3 direction)
|
|
{
|
|
float deltaX = targetPos.x - from.x;
|
|
float deltaY = targetPos.y - from.y;
|
|
float sqrValue = (deltaX * deltaX + deltaY * deltaY) * speed * speed + 2 * deltaX * deltaY * targetVelocity.x * targetVelocity.x - deltaX * deltaX * targetVelocity.y * targetVelocity.y - deltaY * deltaY * targetVelocity.x * targetVelocity.x;
|
|
if (sqrValue >= 0)
|
|
{
|
|
float temp1 = -deltaX * targetVelocity.x - deltaY * targetVelocity.y + ViMathDefine.Sqrt(sqrValue);
|
|
float temp2 = -deltaX * targetVelocity.x - deltaY * targetVelocity.y - ViMathDefine.Sqrt(sqrValue);
|
|
if (temp1 == 0f && temp2 == 0f)
|
|
{
|
|
time = 0f;
|
|
direction = ViVector3.ZERO;
|
|
return false;
|
|
}
|
|
else if (temp1 == 0f)
|
|
{
|
|
time = (deltaX * deltaX + deltaY * deltaY) / temp2;
|
|
}
|
|
else if (temp2 == 0f)
|
|
{
|
|
time = (deltaX * deltaX + deltaY * deltaY) / temp1;
|
|
}
|
|
else
|
|
{
|
|
time = (deltaX * deltaX + deltaY * deltaY) / ViMathDefine.Max(temp1, temp2);
|
|
}
|
|
direction = new ViVector3(targetVelocity.x + deltaX / time, targetVelocity.y + deltaY / time, 0);
|
|
direction.Normalize();
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
time = 0f;
|
|
direction = ViVector3.ZERO;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public class ViMath3D
|
|
{
|
|
public static void Convert(ViVector3 diretion, float roll, out ViVector3 horizDir, out ViVector3 normal)
|
|
{
|
|
horizDir = diretion;
|
|
horizDir.z = 0.0f;
|
|
horizDir.Normalize();
|
|
diretion.Normalize();
|
|
ViVector3 rotateAxis = ViVector3.Cross(diretion, ViVector3.UNIT_Z);
|
|
rotateAxis.Normalize();
|
|
ViQuaternion verticalRotateQuat = ViQuaternion.FromAxisAngle(rotateAxis, ViMathDefine.PI_HALF);
|
|
normal = verticalRotateQuat * diretion;
|
|
ViQuaternion rollRotateQuat = ViQuaternion.FromAxisAngle(diretion, roll);
|
|
normal = rollRotateQuat * normal;
|
|
}
|
|
|
|
//public static void Convert(ViVector3 horizDir, ViVector3 normal, out ViVector3 diretion, out float roll)
|
|
//{
|
|
// normal.Normalize();
|
|
// ViVector3 rotateAxis = ViVector3.Cross(horizDir, ViVector3.UNIT_Z);
|
|
// if (rotateAxis == normal)
|
|
// {
|
|
// diretion = horizDir;
|
|
// roll = 0.0f;
|
|
// }
|
|
// diretion = ViVector3.Cross(rotateAxis, normal);
|
|
// if (ViVector3.Angle(horizDir, diretion) < ViMathDefine.PI_HALF)
|
|
// {
|
|
|
|
// }
|
|
// else
|
|
// {
|
|
// diretion = -diretion;
|
|
// rotateAxis = -rotateAxis;
|
|
// }
|
|
// ViQuaternion verticalRotateQuat = ViQuaternion.FromAxisAngle(rotateAxis, ViMathDefine.PI_HALF);
|
|
// ViVector3 normal1 = verticalRotateQuat * diretion;
|
|
// ViVector3 normalRotAxisDir = ViVector3.Cross(normal1, normal);
|
|
// if (ViVector3.Angle(horizDir, diretion) < ViMathDefine.PI_HALF)
|
|
// {
|
|
// roll = ViVector3.Angle(normal1, normal);
|
|
// }
|
|
// else
|
|
// {
|
|
// roll = -ViVector3.Angle(normal1, normal);
|
|
// }
|
|
|
|
//}
|
|
} |