use crate::*;
#[inline]
pub fn XMQuaternionEqual(
Q1: FXMVECTOR,
Q2: FXMVECTOR,
) -> bool
{
return XMVector4Equal(Q1, Q2);
}
#[inline]
pub fn XMQuaternionNotEqual(
Q1: FXMVECTOR,
Q2: FXMVECTOR,
) -> bool
{
return XMVector4NotEqual(Q1, Q2);
}
#[inline]
pub fn XMQuaternionIsNaN(
Q: FXMVECTOR,
) -> bool
{
return XMVector4IsNaN(Q);
}
#[inline]
pub fn XMQuaternionIsInfinite(
Q: FXMVECTOR,
) -> bool
{
return XMVector4IsInfinite(Q);
}
#[inline]
pub fn XMQuaternionIsIdentity(
Q: FXMVECTOR,
) -> bool
{
unsafe {
return XMVector4Equal(Q, g_XMIdentityR3.v);
}
}
#[inline]
pub fn XMQuaternionDot(
Q1: FXMVECTOR,
Q2: FXMVECTOR,
) -> FXMVECTOR
{
return XMVector4Dot(Q1, Q2);
}
#[inline]
pub fn XMQuaternionMultiply(
Q1: FXMVECTOR,
Q2: FXMVECTOR,
) -> FXMVECTOR
{
#[cfg(_XM_NO_INTRINSICS_)]
unsafe {
let Result = XMVECTORF32 {
f: [
(Q2.vector4_f32[3] * Q1.vector4_f32[0]) + (Q2.vector4_f32[0] * Q1.vector4_f32[3]) + (Q2.vector4_f32[1] * Q1.vector4_f32[2]) - (Q2.vector4_f32[2] * Q1.vector4_f32[1]),
(Q2.vector4_f32[3] * Q1.vector4_f32[1]) - (Q2.vector4_f32[0] * Q1.vector4_f32[2]) + (Q2.vector4_f32[1] * Q1.vector4_f32[3]) + (Q2.vector4_f32[2] * Q1.vector4_f32[0]),
(Q2.vector4_f32[3] * Q1.vector4_f32[2]) + (Q2.vector4_f32[0] * Q1.vector4_f32[1]) - (Q2.vector4_f32[1] * Q1.vector4_f32[0]) + (Q2.vector4_f32[2] * Q1.vector4_f32[3]),
(Q2.vector4_f32[3] * Q1.vector4_f32[3]) - (Q2.vector4_f32[0] * Q1.vector4_f32[0]) - (Q2.vector4_f32[1] * Q1.vector4_f32[1]) - (Q2.vector4_f32[2] * Q1.vector4_f32[2])
]
};
return Result.v;
}
#[cfg(_XM_ARM_NEON_INTRINSICS_)]
{
unimplemented!()
}
#[cfg(_XM_SSE_INTRINSICS_)]
unsafe {
const ControlWZYX: XMVECTORF32 = XMVECTORF32 { f: [ 1.0, -1.0, 1.0, -1.0 ] };
const ControlZWXY: XMVECTORF32 = XMVECTORF32 { f: [ 1.0, 1.0, -1.0, -1.0 ] };
const ControlYXWZ: XMVECTORF32 = XMVECTORF32 { f: [ -1.0, 1.0, 1.0, -1.0 ] };
let mut Q2X: XMVECTOR = Q2;
let mut Q2Y: XMVECTOR = Q2;
let mut Q2Z: XMVECTOR = Q2;
let mut vResult: XMVECTOR = Q2;
vResult = XM_PERMUTE_PS!(vResult, _MM_SHUFFLE(3, 3, 3, 3));
Q2X = XM_PERMUTE_PS!(Q2X, _MM_SHUFFLE(0, 0, 0, 0));
Q2Y = XM_PERMUTE_PS!(Q2Y, _MM_SHUFFLE(1, 1, 1, 1));
Q2Z = XM_PERMUTE_PS!(Q2Z, _MM_SHUFFLE(2, 2, 2, 2));
vResult = _mm_mul_ps(vResult, Q1);
let mut Q1Shuffle: XMVECTOR = Q1;
Q1Shuffle = XM_PERMUTE_PS!(Q1Shuffle, _MM_SHUFFLE(0, 1, 2, 3));
Q2X = _mm_mul_ps(Q2X, Q1Shuffle);
Q1Shuffle = XM_PERMUTE_PS!(Q1Shuffle, _MM_SHUFFLE(2, 3, 0, 1));
vResult = XM_FMADD_PS!(Q2X, ControlWZYX.v, vResult);
Q2Y = _mm_mul_ps(Q2Y, Q1Shuffle);
Q1Shuffle = XM_PERMUTE_PS!(Q1Shuffle, _MM_SHUFFLE(0, 1, 2, 3));
Q2Y = _mm_mul_ps(Q2Y, ControlZWXY.v);
Q2Z = _mm_mul_ps(Q2Z, Q1Shuffle);
Q2Y = XM_FMADD_PS!(Q2Z, ControlYXWZ.v, Q2Y);
vResult = _mm_add_ps(vResult, Q2Y);
return vResult;
}
}
#[inline]
pub fn XMQuaternionLengthSq(
Q: FXMVECTOR,
) -> FXMVECTOR
{
return XMVector4LengthSq(Q);
}
#[inline]
pub fn XMQuaternionReciprocalLength(
Q: FXMVECTOR,
) -> FXMVECTOR
{
return XMVector4ReciprocalLength(Q);
}
#[inline]
pub fn XMQuaternionLength(
Q: FXMVECTOR,
) -> FXMVECTOR
{
return XMVector4Length(Q);
}
#[inline]
pub fn XMQuaternionNormalizeEst(
Q: FXMVECTOR,
) -> FXMVECTOR
{
return XMVector4NormalizeEst(Q);
}
#[inline]
pub fn XMQuaternionNormalize(
Q: FXMVECTOR,
) -> FXMVECTOR
{
return XMVector4Normalize(Q);
}
#[inline]
pub fn XMQuaternionConjugate(
Q: FXMVECTOR,
) -> FXMVECTOR
{
#[cfg(_XM_NO_INTRINSICS_)]
unsafe {
let Result = XMVECTORF32 {
f: [
-Q.vector4_f32[0],
-Q.vector4_f32[1],
-Q.vector4_f32[2],
Q.vector4_f32[3]
]
};
return Result.v;
}
#[cfg(_XM_ARM_NEON_INTRINSICS_)]
{
unimplemented!()
}
#[cfg(_XM_SSE_INTRINSICS_)]
unsafe {
const NegativeOne3: XMVECTORF32 = XMVECTORF32 { f: [-1.0, -1.0, -1.0, 1.0 ] };
return _mm_mul_ps(Q, NegativeOne3.v)
}
}
#[inline]
pub fn XMQuaternionInverse(
Q: FXMVECTOR,
) -> FXMVECTOR
{
unsafe {
const Zero: XMVECTOR = unsafe { g_XMZero.v };
let L: XMVECTOR = XMVector4LengthSq(Q);
let Conjugate: XMVECTOR = XMQuaternionConjugate(Q);
let Control: XMVECTOR = XMVectorLessOrEqual(L, g_XMEpsilon.v);
let mut Result: XMVECTOR = XMVectorDivide(Conjugate, L);
Result = XMVectorSelect(Result, Zero, Control);
return Result;
}
}
#[inline]
pub fn XMQuaternionLn(
Q: FXMVECTOR,
) -> FXMVECTOR
{
unsafe {
const OneMinusEpsilon: XMVECTOR = unsafe { XMVECTORF32 { f: [1.0 - 0.00001, 1.0 - 0.00001, 1.0 - 0.00001, 1.0 - 0.00001] }.v };
let QW: XMVECTOR = XMVectorSplatW(Q);
let Q0: XMVECTOR = XMVectorSelect(g_XMSelect1110.v, Q, g_XMSelect1110.v);
let ControlW: XMVECTOR = XMVectorInBounds(QW, OneMinusEpsilon);
let Theta: XMVECTOR = XMVectorACos(QW);
let SinTheta: XMVECTOR = XMVectorSin(Theta);
let S: XMVECTOR = XMVectorDivide(Theta, SinTheta);
let mut Result: XMVECTOR = XMVectorMultiply(Q0, S);
Result = XMVectorSelect(Q0, Result, ControlW);
return Result;
}
}
#[inline]
pub fn XMQuaternionExp(
Q: FXMVECTOR,
) -> FXMVECTOR
{
unsafe {
let Theta: XMVECTOR = XMVector3Length(Q);
let mut SinTheta: XMVECTOR = mem::MaybeUninit::uninit().assume_init();
let mut CosTheta: XMVECTOR = mem::MaybeUninit::uninit().assume_init();
XMVectorSinCos(&mut SinTheta, &mut CosTheta, Theta);
let S: XMVECTOR = XMVectorDivide(SinTheta, Theta);
let mut Result: XMVECTOR = XMVectorMultiply(Q, S);
const Zero: XMVECTOR = unsafe { g_XMZero.v };
let Control: XMVECTOR = XMVectorNearEqual(Theta, Zero, g_XMEpsilon.v);
Result = XMVectorSelect(Result, Q, Control);
Result = XMVectorSelect(CosTheta, Result, g_XMSelect1110.v);
return Result;
}
}
#[inline]
pub fn XMQuaternionSlerp(
Q0: FXMVECTOR,
Q1: FXMVECTOR,
t: f32,
) -> FXMVECTOR
{
let T: XMVECTOR = XMVectorReplicate(t);
return XMQuaternionSlerpV(Q0, Q1, T);
}
#[inline]
pub fn XMQuaternionSlerpV(
Q0: FXMVECTOR,
Q1: FXMVECTOR,
T: FXMVECTOR,
) -> FXMVECTOR
{
debug_assert!((XMVectorGetY(T) == XMVectorGetX(T)) && (XMVectorGetZ(T) == XMVectorGetX(T)) && (XMVectorGetW(T) == XMVectorGetX(T)));
#[cfg(any(_XM_NO_INTRINSICS_, _XM_ARM_NEON_INTRINSICS_))]
unsafe {
const OneMinusEpsilon: XMVECTORF32 = XMVECTORF32 { f: [ 1.0 - 0.00001, 1.0 - 0.00001, 1.0 - 0.00001, 1.0 - 0.00001 ] };
let mut CosOmega: XMVECTOR = XMQuaternionDot(Q0, Q1);
const Zero: XMVECTOR = unsafe { g_XMZero.v };
let mut Control: XMVECTOR = XMVectorLess(CosOmega, Zero);
let Sign: XMVECTOR = XMVectorSelect(g_XMOne.v, g_XMNegativeOne.v, Control);
CosOmega = XMVectorMultiply(CosOmega, Sign);
Control = XMVectorLess(CosOmega, OneMinusEpsilon.v);
let mut SinOmega: XMVECTOR = XMVectorNegativeMultiplySubtract(CosOmega, CosOmega, g_XMOne.v);
SinOmega = XMVectorSqrt(SinOmega);
let Omega: XMVECTOR = XMVectorATan2(SinOmega, CosOmega);
let mut SignMask: XMVECTOR = XMVectorSplatSignMask();
let mut V01: XMVECTOR = XMVectorShiftLeft(T, Zero, 2);
SignMask = XMVectorShiftLeft(SignMask, Zero, 3);
V01 = XMVectorXorInt(V01, SignMask);
V01 = XMVectorAdd(g_XMIdentityR0.v, V01);
let InvSinOmega: XMVECTOR = XMVectorReciprocal(SinOmega);
let mut S0: XMVECTOR = XMVectorMultiply(V01, Omega);
S0 = XMVectorSin(S0);
S0 = XMVectorMultiply(S0, InvSinOmega);
S0 = XMVectorSelect(V01, S0, Control);
let mut S1: XMVECTOR = XMVectorSplatY(S0);
S0 = XMVectorSplatX(S0);
S1 = XMVectorMultiply(S1, Sign);
let mut Result: XMVECTOR = XMVectorMultiply(Q0, S0);
Result = XMVectorMultiplyAdd(Q1, S1, Result);
return Result;
}
#[cfg(_XM_SSE_INTRINSICS_)]
unsafe {
const OneMinusEpsilon: XMVECTORF32 = XMVECTORF32 { f: [ 1.0 - 0.00001, 1.0 - 0.00001, 1.0 - 0.00001, 1.0 - 0.00001 ] };
const SignMask2: XMVECTORU32 = XMVECTORU32 { u: [ 0x80000000, 0x00000000, 0x00000000, 0x00000000 ] };
let mut CosOmega: XMVECTOR = XMQuaternionDot(Q0, Q1);
const Zero: XMVECTOR = unsafe { g_XMZero.v };
let mut Control: XMVECTOR = XMVectorLess(CosOmega, Zero);
let Sign: XMVECTOR = XMVectorSelect(g_XMOne.v, g_XMNegativeOne.v, Control);
CosOmega = _mm_mul_ps(CosOmega, Sign);
Control = XMVectorLess(CosOmega, OneMinusEpsilon.v);
let mut SinOmega: XMVECTOR = _mm_mul_ps(CosOmega, CosOmega);
SinOmega = _mm_sub_ps(g_XMOne.v, SinOmega);
SinOmega = _mm_sqrt_ps(SinOmega);
let Omega: XMVECTOR = XMVectorATan2(SinOmega, CosOmega);
let mut V01: XMVECTOR = XM_PERMUTE_PS!(T, _MM_SHUFFLE(2, 3, 0, 1));
V01 = _mm_and_ps(V01, g_XMMaskXY.v);
V01 = _mm_xor_ps(V01, SignMask2.v);
V01 = _mm_add_ps(g_XMIdentityR0.v, V01);
let mut S0: XMVECTOR = _mm_mul_ps(V01, Omega);
S0 = XMVectorSin(S0);
S0 = _mm_div_ps(S0, SinOmega);
S0 = XMVectorSelect(V01, S0, Control);
let mut S1: XMVECTOR = XMVectorSplatY(S0);
S0 = XMVectorSplatX(S0);
S1 = _mm_mul_ps(S1, Sign);
let mut Result: XMVECTOR = _mm_mul_ps(Q0, S0);
S1 = _mm_mul_ps(S1, Q1);
Result = _mm_add_ps(Result, S1);
return Result;
}
}
#[inline]
pub fn XMQuaternionSquad(
Q0: FXMVECTOR,
Q1: FXMVECTOR,
Q2: FXMVECTOR,
Q3: GXMVECTOR,
t: f32,
) -> FXMVECTOR
{
let T: XMVECTOR = XMVectorReplicate(t);
return XMQuaternionSquadV(Q0, Q1, Q2, Q3, T);
}
#[inline]
pub fn XMQuaternionSquadV(
Q0: FXMVECTOR,
Q1: FXMVECTOR,
Q2: FXMVECTOR,
Q3: GXMVECTOR,
T: XMVECTOR,
) -> FXMVECTOR
{
debug_assert!((XMVectorGetY(T) == XMVectorGetX(T)) && (XMVectorGetZ(T) == XMVectorGetX(T)) && (XMVectorGetW(T) == XMVectorGetX(T)));
let mut TP: XMVECTOR = T;
let Two: XMVECTOR = XMVectorSplatConstant(2, 0);
let Q03: XMVECTOR = XMQuaternionSlerpV(Q0, Q3, T);
let Q12: XMVECTOR = XMQuaternionSlerpV(Q1, Q2, T);
TP = XMVectorNegativeMultiplySubtract(TP, TP, TP);
TP = XMVectorMultiply(TP, Two);
let Result: XMVECTOR = XMQuaternionSlerpV(Q03, Q12, TP);
return Result;
}
#[inline]
pub fn XMQuaternionSquadSetup(
pA: &mut XMVECTOR,
pB: &mut XMVECTOR,
pC: &mut XMVECTOR,
Q0: FXMVECTOR,
Q1: FXMVECTOR,
Q2: FXMVECTOR,
Q3: GXMVECTOR
)
{
let LS12: XMVECTOR = XMQuaternionLengthSq(XMVectorAdd(Q1, Q2));
let LD12: XMVECTOR = XMQuaternionLengthSq(XMVectorSubtract(Q1, Q2));
let mut SQ2: XMVECTOR = XMVectorNegate(Q2);
let Control1: XMVECTOR = XMVectorLess(LS12, LD12);
SQ2 = XMVectorSelect(Q2, SQ2, Control1);
let LS01: XMVECTOR = XMQuaternionLengthSq(XMVectorAdd(Q0, Q1));
let LD01: XMVECTOR = XMQuaternionLengthSq(XMVectorSubtract(Q0, Q1));
let mut SQ0: XMVECTOR = XMVectorNegate(Q0);
let LS23: XMVECTOR = XMQuaternionLengthSq(XMVectorAdd(SQ2, Q3));
let LD23: XMVECTOR = XMQuaternionLengthSq(XMVectorSubtract(SQ2, Q3));
let mut SQ3: XMVECTOR = XMVectorNegate(Q3);
let Control0: XMVECTOR = XMVectorLess(LS01, LD01);
let Control2: XMVECTOR = XMVectorLess(LS23, LD23);
SQ0 = XMVectorSelect(Q0, SQ0, Control0);
SQ3 = XMVectorSelect(Q3, SQ3, Control2);
let InvQ1: XMVECTOR = XMQuaternionInverse(Q1);
let InvQ2: XMVECTOR = XMQuaternionInverse(SQ2);
let LnQ0: XMVECTOR = XMQuaternionLn(XMQuaternionMultiply(InvQ1, SQ0));
let LnQ2: XMVECTOR = XMQuaternionLn(XMQuaternionMultiply(InvQ1, SQ2));
let LnQ1: XMVECTOR = XMQuaternionLn(XMQuaternionMultiply(InvQ2, Q1));
let LnQ3: XMVECTOR = XMQuaternionLn(XMQuaternionMultiply(InvQ2, SQ3));
let NegativeOneQuarter: XMVECTOR = XMVectorSplatConstant(-1, 2);
let mut ExpQ02: XMVECTOR = XMVectorMultiply(XMVectorAdd(LnQ0, LnQ2), NegativeOneQuarter);
let mut ExpQ13: XMVECTOR = XMVectorMultiply(XMVectorAdd(LnQ1, LnQ3), NegativeOneQuarter);
ExpQ02 = XMQuaternionExp(ExpQ02);
ExpQ13 = XMQuaternionExp(ExpQ13);
*pA = XMQuaternionMultiply(Q1, ExpQ02);
*pB = XMQuaternionMultiply(SQ2, ExpQ13);
*pC = SQ2;
}
#[inline]
pub fn XMQuaternionBaryCentric(
Q0: FXMVECTOR,
Q1: FXMVECTOR,
Q2: FXMVECTOR,
f: f32,
g: f32,
) -> XMVECTOR
{
let s = f + g;
let Result: XMVECTOR;
if ((s < 0.00001) && (s > -0.00001))
{
Result = Q0;
}
else
{
let Q01: XMVECTOR = XMQuaternionSlerp(Q0, Q1, s);
let Q02: XMVECTOR = XMQuaternionSlerp(Q0, Q2, s);
Result = XMQuaternionSlerp(Q01, Q02, g / s);
}
return Result;
}
#[inline]
pub fn XMQuaternionBaryCentricV(
Q0: FXMVECTOR,
Q1: FXMVECTOR,
Q2: FXMVECTOR,
F: FXMVECTOR,
G: FXMVECTOR,
) -> XMVECTOR
{
debug_assert!((XMVectorGetY(F) == XMVectorGetX(F)) && (XMVectorGetZ(F) == XMVectorGetX(F)) && (XMVectorGetW(F) == XMVectorGetX(F)));
debug_assert!((XMVectorGetY(G) == XMVectorGetX(G)) && (XMVectorGetZ(G) == XMVectorGetX(G)) && (XMVectorGetW(G) == XMVectorGetX(G)));
let Epsilon: XMVECTOR = XMVectorSplatConstant(1, 16);
let S: XMVECTOR = XMVectorAdd(F, G);
let Result: XMVECTOR;
if (XMVector4InBounds(S, Epsilon))
{
Result = Q0;
}
else
{
let Q01: XMVECTOR = XMQuaternionSlerpV(Q0, Q1, S);
let Q02: XMVECTOR = XMQuaternionSlerpV(Q0, Q2, S);
let mut GS: XMVECTOR = XMVectorReciprocal(S);
GS = XMVectorMultiply(G, GS);
Result = XMQuaternionSlerpV(Q01, Q02, GS);
}
return Result;
}
#[inline]
pub fn XMQuaternionIdentity() -> FXMVECTOR
{
unsafe {
return g_XMIdentityR3.v;
}
}
#[inline]
pub fn XMQuaternionRotationRollPitchYaw(
Pitch: f32,
Yaw: f32,
Roll: f32,
) -> FXMVECTOR
{
let Angles: XMVECTOR = XMVectorSet(Pitch, Yaw, Roll, 0.0);
let Q: XMVECTOR = XMQuaternionRotationRollPitchYawFromVector(Angles);
return Q;
}
#[inline]
pub fn XMQuaternionRotationRollPitchYawFromVector(
Angles: XMVECTOR, ) -> FXMVECTOR
{
unsafe {
const Sign: XMVECTORF32 = XMVECTORF32 { f: [1.0, -1.0, -1.0, 1.0 ] };
let HalfAngles: XMVECTOR = XMVectorMultiply(Angles, g_XMOneHalf.v);
let mut SinAngles: XMVECTOR = mem::MaybeUninit::uninit().assume_init();
let mut CosAngles: XMVECTOR = mem::MaybeUninit::uninit().assume_init();
XMVectorSinCos(&mut SinAngles, &mut CosAngles, HalfAngles);
let P0: XMVECTOR = <(XM_PERMUTE_0X, XM_PERMUTE_1X, XM_PERMUTE_1X, XM_PERMUTE_1X)>::XMVectorPermute(SinAngles, CosAngles);
let Y0: XMVECTOR = <(XM_PERMUTE_1Y, XM_PERMUTE_0Y, XM_PERMUTE_1Y, XM_PERMUTE_1Y)>::XMVectorPermute(SinAngles, CosAngles);
let R0: XMVECTOR = <(XM_PERMUTE_1Z, XM_PERMUTE_1Z, XM_PERMUTE_0Z, XM_PERMUTE_1Z)>::XMVectorPermute(SinAngles, CosAngles);
let P1: XMVECTOR = <(XM_PERMUTE_0X, XM_PERMUTE_1X, XM_PERMUTE_1X, XM_PERMUTE_1X)>::XMVectorPermute(CosAngles, SinAngles);
let Y1: XMVECTOR = <(XM_PERMUTE_1Y, XM_PERMUTE_0Y, XM_PERMUTE_1Y, XM_PERMUTE_1Y)>::XMVectorPermute(CosAngles, SinAngles);
let R1: XMVECTOR = <(XM_PERMUTE_1Z, XM_PERMUTE_1Z, XM_PERMUTE_0Z, XM_PERMUTE_1Z)>::XMVectorPermute(CosAngles, SinAngles);
let mut Q1: XMVECTOR = XMVectorMultiply(P1, Sign.v);
let mut Q0: XMVECTOR = XMVectorMultiply(P0, Y0);
Q1 = XMVectorMultiply(Q1, Y1);
Q0 = XMVectorMultiply(Q0, R0);
let Q: XMVECTOR = XMVectorMultiplyAdd(Q1, R1, Q0);
return Q;
}
}
#[inline]
pub fn XMQuaternionRotationNormal(
NormalAxis: XMVECTOR,
Angle: f32,
) -> FXMVECTOR
{
#[cfg(any(_XM_NO_INTRINSICS_, _XM_ARM_NEON_INTRINSICS_))]
unsafe {
let N: XMVECTOR = XMVectorSelect(g_XMOne.v, NormalAxis, g_XMSelect1110.v);
let mut SinV: f32 = 0.0;
let mut CosV: f32 = 0.0;
XMScalarSinCos(&mut SinV, &mut CosV, 0.5 * Angle);
let Scale: XMVECTOR = XMVectorSet(SinV, SinV, SinV, CosV);
return XMVectorMultiply(N, Scale);
}
#[cfg(_XM_SSE_INTRINSICS_)]
unsafe {
let mut N: XMVECTOR = _mm_and_ps(NormalAxis, g_XMMask3.v);
N = _mm_or_ps(N, g_XMIdentityR3.v);
let mut Scale: XMVECTOR = _mm_set_ps1(0.5 * Angle);
let mut vSine: XMVECTOR = mem::MaybeUninit::uninit().assume_init();
let mut vCosine: XMVECTOR = mem::MaybeUninit::uninit().assume_init();
XMVectorSinCos(&mut vSine, &mut vCosine, Scale);
Scale = _mm_and_ps(vSine, g_XMMask3.v);
vCosine = _mm_and_ps(vCosine, g_XMMaskW.v);
Scale = _mm_or_ps(Scale, vCosine);
N = _mm_mul_ps(N, Scale);
return N;
}
}
#[inline]
pub fn XMQuaternionRotationAxis(
Axis: XMVECTOR,
Angle: f32,
) -> FXMVECTOR
{
debug_assert!(!XMVector3Equal(Axis, XMVectorZero()));
debug_assert!(!XMVector3IsInfinite(Axis));
let Normal: XMVECTOR = XMVector3Normalize(Axis);
let Q: XMVECTOR = XMQuaternionRotationNormal(Normal, Angle);
return Q;
}
#[inline]
pub fn XMQuaternionRotationMatrix(
M: XMMATRIX,
) -> FXMVECTOR
{
#[cfg(_XM_NO_INTRINSICS_)]
unsafe {
let mut q: XMVECTORF32 = mem::MaybeUninit::uninit().assume_init();
let r22: f32 = M.m[2][2];
if (r22 <= 0.0) {
let dif10: f32 = M.m[1][1] - M.m[0][0];
let omr22: f32 = 1.0 - r22;
if (dif10 <= 0.0) {
let fourXSqr: f32 = omr22 - dif10;
let inv4x: f32 = 0.5 / sqrtf(fourXSqr);
q.f[0] = fourXSqr * inv4x;
q.f[1] = (M.m[0][1] + M.m[1][0]) * inv4x;
q.f[2] = (M.m[0][2] + M.m[2][0]) * inv4x;
q.f[3] = (M.m[1][2] - M.m[2][1]) * inv4x;
}
else {
let fourYSqr: f32 = omr22 + dif10;
let inv4y: f32 = 0.5 / sqrtf(fourYSqr);
q.f[0] = (M.m[0][1] + M.m[1][0]) * inv4y;
q.f[1] = fourYSqr * inv4y;
q.f[2] = (M.m[1][2] + M.m[2][1]) * inv4y;
q.f[3] = (M.m[2][0] - M.m[0][2]) * inv4y;
}
}
else {
let sum10: f32 = M.m[1][1] + M.m[0][0];
let opr22: f32 = 1.0 + r22;
if (sum10 <= 0.0) {
let fourZSqr: f32 = opr22 - sum10;
let inv4z: f32 = 0.5 / sqrtf(fourZSqr);
q.f[0] = (M.m[0][2] + M.m[2][0]) * inv4z;
q.f[1] = (M.m[1][2] + M.m[2][1]) * inv4z;
q.f[2] = fourZSqr * inv4z;
q.f[3] = (M.m[0][1] - M.m[1][0]) * inv4z;
}
else {
let fourWSqr: f32 = opr22 + sum10;
let inv4w: f32 = 0.5 / sqrtf(fourWSqr);
q.f[0] = (M.m[1][2] - M.m[2][1]) * inv4w;
q.f[1] = (M.m[2][0] - M.m[0][2]) * inv4w;
q.f[2] = (M.m[0][1] - M.m[1][0]) * inv4w;
q.f[3] = fourWSqr * inv4w;
}
}
return q.v;
}
#[cfg(_XM_ARM_NEON_INTRINSICS_)]
{
unimplemented!()
}
#[cfg(_XM_SSE_INTRINSICS_)]
unsafe {
const XMPMMP: XMVECTORF32 = XMVECTORF32 { f: [ 1.0, -1.0, -1.0, 1.0 ] };
const XMMPMP: XMVECTORF32 = XMVECTORF32 { f: [ -1.0, 1.0, -1.0, 1.0 ] };
const XMMMPP: XMVECTORF32 = XMVECTORF32 { f: [ -1.0, -1.0, 1.0, 1.0 ] };
let r0: XMVECTOR = M.r[0]; let r1: XMVECTOR = M.r[1]; let r2: XMVECTOR = M.r[2];
let r00: XMVECTOR = XM_PERMUTE_PS!(r0, _MM_SHUFFLE(0, 0, 0, 0));
let r11: XMVECTOR = XM_PERMUTE_PS!(r1, _MM_SHUFFLE(1, 1, 1, 1));
let r22: XMVECTOR = XM_PERMUTE_PS!(r2, _MM_SHUFFLE(2, 2, 2, 2));
let r11mr00: XMVECTOR = _mm_sub_ps(r11, r00);
let x2gey2: XMVECTOR = _mm_cmple_ps(r11mr00, g_XMZero.v);
let r11pr00: XMVECTOR = _mm_add_ps(r11, r00);
let z2gew2: XMVECTOR = _mm_cmple_ps(r11pr00, g_XMZero.v);
let x2py2gez2pw2: XMVECTOR = _mm_cmple_ps(r22, g_XMZero.v);
let mut t0: XMVECTOR = XM_FMADD_PS!(XMPMMP.v, r00, g_XMOne.v);
let mut t1: XMVECTOR = _mm_mul_ps(XMMPMP.v, r11);
let mut t2: XMVECTOR = XM_FMADD_PS!(XMMMPP.v, r22, t0);
let x2y2z2w2: XMVECTOR = _mm_add_ps(t1, t2);
t0 = _mm_shuffle_ps(r0, r1, _MM_SHUFFLE(1, 2, 2, 1));
t1 = _mm_shuffle_ps(r1, r2, _MM_SHUFFLE(1, 0, 0, 0));
t1 = XM_PERMUTE_PS!(t1, _MM_SHUFFLE(1, 3, 2, 0));
let xyxzyz: XMVECTOR = _mm_add_ps(t0, t1);
t0 = _mm_shuffle_ps(r2, r1, _MM_SHUFFLE(0, 0, 0, 1));
t1 = _mm_shuffle_ps(r1, r0, _MM_SHUFFLE(1, 2, 2, 2));
t1 = XM_PERMUTE_PS!(t1, _MM_SHUFFLE(1, 3, 2, 0));
let mut xwywzw: XMVECTOR = _mm_sub_ps(t0, t1);
xwywzw = _mm_mul_ps(XMMPMP.v, xwywzw);
t0 = _mm_shuffle_ps(x2y2z2w2, xyxzyz, _MM_SHUFFLE(0, 0, 1, 0));
t1 = _mm_shuffle_ps(x2y2z2w2, xwywzw, _MM_SHUFFLE(0, 2, 3, 2));
t2 = _mm_shuffle_ps(xyxzyz, xwywzw, _MM_SHUFFLE(1, 0, 2, 1));
let tensor0: XMVECTOR = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(2, 0, 2, 0));
let tensor1: XMVECTOR = _mm_shuffle_ps(t0, t2, _MM_SHUFFLE(3, 1, 1, 2));
let tensor2: XMVECTOR = _mm_shuffle_ps(t2, t1, _MM_SHUFFLE(2, 0, 1, 0));
let tensor3: XMVECTOR = _mm_shuffle_ps(t2, t1, _MM_SHUFFLE(1, 2, 3, 2));
t0 = _mm_and_ps(x2gey2, tensor0);
t1 = _mm_andnot_ps(x2gey2, tensor1);
t0 = _mm_or_ps(t0, t1);
t1 = _mm_and_ps(z2gew2, tensor2);
t2 = _mm_andnot_ps(z2gew2, tensor3);
t1 = _mm_or_ps(t1, t2);
t0 = _mm_and_ps(x2py2gez2pw2, t0);
t1 = _mm_andnot_ps(x2py2gez2pw2, t1);
t2 = _mm_or_ps(t0, t1);
t0 = XMVector4Length(t2);
return _mm_div_ps(t2, t0);
}
}
#[inline]
pub fn XMQuaternionToAxisAngle(
pAxis: &mut FXMVECTOR,
pAngle: &mut f32,
Q: FXMVECTOR,
)
{
*pAxis = Q;
*pAngle = 2.0 * XMScalarACos(XMVectorGetW(Q));
}
#[inline]
pub fn XMPlaneEqual(
P1: FXMVECTOR,
P2: FXMVECTOR,
) -> bool
{
return XMVector4Equal(P1, P2);
}
#[inline]
pub fn XMPlaneNearEqual(
P1: FXMVECTOR,
P2: FXMVECTOR,
Epsilon: FXMVECTOR,
) -> bool
{
let NP1: XMVECTOR = XMPlaneNormalize(P1);
let NP2: XMVECTOR = XMPlaneNormalize(P2);
return XMVector4NearEqual(NP1, NP2, Epsilon);
}
#[inline]
pub fn XMPlaneNotEqual(
P1: FXMVECTOR,
P2: FXMVECTOR,
) -> bool
{
return XMVector4NotEqual(P1, P2);
}
#[inline]
pub fn XMPlaneIsNaN(
P: FXMVECTOR,
) -> bool
{
return XMVector4IsNaN(P);
}
#[inline]
pub fn XMPlaneIsInfinite(
P: FXMVECTOR,
) -> bool
{
return XMVector4IsInfinite(P);
}
#[inline]
pub fn XMPlaneDot(
P: FXMVECTOR,
V: FXMVECTOR,
) -> XMVECTOR
{
return XMVector4Dot(P, V);
}
#[inline]
pub fn XMPlaneDotCoord(
P: FXMVECTOR,
V: FXMVECTOR,
) -> XMVECTOR
{
unsafe {
let V3: XMVECTOR = XMVectorSelect(g_XMOne.v, V, g_XMSelect1110.v);
let Result: XMVECTOR = XMVector4Dot(P, V3);
return Result;
}
}
#[inline]
pub fn XMPlaneDotNormal(
P: FXMVECTOR,
V: FXMVECTOR,
) -> XMVECTOR
{
return XMVector3Dot(P, V);
}
#[inline]
pub fn XMPlaneNormalizeEst(
P: FXMVECTOR,
) -> XMVECTOR
{
#[cfg(_XM_NO_INTRINSICS_)]
{
let Result: XMVECTOR = XMVector3ReciprocalLengthEst(P);
return XMVectorMultiply(P, Result);
}
#[cfg(_XM_ARM_NEON_INTRINSICS_)]
{
unimplemented!()
}
#[cfg(_XM_SSE_INTRINSICS_)]
unsafe {
let mut vDot: XMVECTOR = _mm_mul_ps(P, P);
let mut vTemp: XMVECTOR = XM_PERMUTE_PS!(vDot, _MM_SHUFFLE(2, 1, 2, 1));
vDot = _mm_add_ss(vDot, vTemp);
vTemp = XM_PERMUTE_PS!(vTemp, _MM_SHUFFLE(1, 1, 1, 1));
vDot = _mm_add_ss(vDot, vTemp);
vDot = XM_PERMUTE_PS!(vDot, _MM_SHUFFLE(0, 0, 0, 0));
vDot = _mm_rsqrt_ps(vDot);
vDot = _mm_mul_ps(vDot, P);
return vDot;
}
}
#[inline]
pub fn XMPlaneNormalize(
P: FXMVECTOR,
) -> XMVECTOR
{
#[cfg(_XM_NO_INTRINSICS_)]
unsafe {
let mut fLengthSq: f32 = sqrtf((P.vector4_f32[0] * P.vector4_f32[0]) + (P.vector4_f32[1] * P.vector4_f32[1]) + (P.vector4_f32[2] * P.vector4_f32[2]));
if (fLengthSq > 0.0)
{
fLengthSq = 1.0 / fLengthSq;
}
let vResult = XMVECTORF32 { f: [
P.vector4_f32[0] * fLengthSq,
P.vector4_f32[1] * fLengthSq,
P.vector4_f32[2] * fLengthSq,
P.vector4_f32[3] * fLengthSq
] };
return vResult.v;
}
#[cfg(_XM_ARM_NEON_INTRINSICS_)]
unsafe {
unimplemented!()
}
#[cfg(_XM_SSE4_INTRINSICS_)]
unsafe {
let mut vLengthSq: XMVECTOR = _mm_dp_ps(P, P, 0x7f);
let mut vResult: XMVECTOR = _mm_sqrt_ps(vLengthSq);
vLengthSq = _mm_cmpneq_ps(vLengthSq, g_XMInfinity.v);
vResult = _mm_div_ps(P, vResult);
vResult = _mm_and_ps(vResult, vLengthSq);
return vResult;
}
#[cfg(all(_XM_SSE_INTRINSICS_, not(_XM_SSE4_INTRINSICS_)))]
unsafe {
let mut vLengthSq: XMVECTOR = _mm_dp_ps(P, P, 0x7f);
let mut vResult: XMVECTOR = _mm_sqrt_ps(vLengthSq);
vLengthSq = _mm_cmpneq_ps(vLengthSq, g_XMInfinity.v);
vResult = _mm_div_ps(P, vResult);
vResult = _mm_and_ps(vResult, vLengthSq);
return vResult;
}
}
#[inline]
pub fn XMPlaneIntersectLine(
P: FXMVECTOR,
LinePoint1: FXMVECTOR,
LinePoint2: FXMVECTOR,
) -> XMVECTOR
{
unsafe {
let V1: XMVECTOR = XMVector3Dot(P, LinePoint1);
let V2: XMVECTOR = XMVector3Dot(P, LinePoint2);
let D: XMVECTOR = XMVectorSubtract(V1, V2);
let mut VT: XMVECTOR = XMPlaneDotCoord(P, LinePoint1);
VT = XMVectorDivide(VT, D);
let mut Point: XMVECTOR = XMVectorSubtract(LinePoint2, LinePoint1);
Point = XMVectorMultiplyAdd(Point, VT, LinePoint1);
let Zero: XMVECTOR = XMVectorZero();
let Control: XMVECTOR = XMVectorNearEqual(D, Zero, g_XMEpsilon.v);
return XMVectorSelect(Point, g_XMQNaN.v, Control);
}
}
#[inline]
pub fn XMPlaneIntersectPlane(
pLinePoint1: &mut FXMVECTOR,
pLinePoint2: &mut FXMVECTOR,
P1: FXMVECTOR,
P2: FXMVECTOR,
)
{
unsafe {
let V1: XMVECTOR = XMVector3Cross(P2, P1);
let LengthSq: XMVECTOR = XMVector3LengthSq(V1);
let V2: XMVECTOR = XMVector3Cross(P2, V1);
let P1W: XMVECTOR = XMVectorSplatW(P1);
let mut Point: XMVECTOR = XMVectorMultiply(V2, P1W);
let V3: XMVECTOR = XMVector3Cross(V1, P1);
let P2W: XMVECTOR = XMVectorSplatW(P2);
Point = XMVectorMultiplyAdd(V3, P2W, Point);
let LinePoint1: XMVECTOR = XMVectorDivide(Point, LengthSq);
let LinePoint2: XMVECTOR = XMVectorAdd(LinePoint1, V1);
let Control: XMVECTOR = XMVectorLessOrEqual(LengthSq, g_XMEpsilon.v);
*pLinePoint1 = XMVectorSelect(LinePoint1, g_XMQNaN.v, Control);
*pLinePoint2 = XMVectorSelect(LinePoint2, g_XMQNaN.v, Control);
}
}
#[inline]
pub fn XMPlaneTransform(
P: FXMVECTOR,
M: FXMMATRIX,
) -> XMVECTOR
{
unsafe {
let W: XMVECTOR = XMVectorSplatW(P);
let Z: XMVECTOR = XMVectorSplatZ(P);
let Y: XMVECTOR = XMVectorSplatY(P);
let X: XMVECTOR = XMVectorSplatX(P);
let mut Result: XMVECTOR = XMVectorMultiply(W, M.r[3]);
Result = XMVectorMultiplyAdd(Z, M.r[2], Result);
Result = XMVectorMultiplyAdd(Y, M.r[1], Result);
Result = XMVectorMultiplyAdd(X, M.r[0], Result);
return Result;
}
}
#[inline]
pub fn XMPlaneFromPointNormal(
Point: FXMVECTOR,
Normal: FXMVECTOR,
) -> XMVECTOR
{
unsafe {
let mut W: XMVECTOR = XMVector3Dot(Point, Normal);
W = XMVectorNegate(W);
return XMVectorSelect(W, Normal, g_XMSelect1110.v);
}
}
#[inline]
pub fn XMPlaneFromPoints(
Point1: FXMVECTOR,
Point2: FXMVECTOR,
Point3: FXMVECTOR,
) -> XMVECTOR
{
unsafe {
let V21: XMVECTOR = XMVectorSubtract(Point1, Point2);
let V31: XMVECTOR = XMVectorSubtract(Point1, Point3);
let mut N: XMVECTOR = XMVector3Cross(V21, V31);
N = XMVector3Normalize(N);
let mut D: XMVECTOR = XMPlaneDotNormal(N, Point1);
D = XMVectorNegate(D);
let Result: XMVECTOR = XMVectorSelect(D, N, g_XMSelect1110.v);
return Result;
}
}
#[inline]
pub fn XMFresnelTerm(
CosIncidentAngle: FXMVECTOR,
RefractionIndex: FXMVECTOR,
) -> FXMVECTOR
{
debug_assert!(!XMVector4IsInfinite(CosIncidentAngle));
#[cfg(_XM_NO_INTRINSICS_)]
unsafe {
let mut G: XMVECTOR = XMVectorMultiplyAdd(RefractionIndex, RefractionIndex, g_XMNegativeOne.v);
G = XMVectorMultiplyAdd(CosIncidentAngle, CosIncidentAngle, G);
G = XMVectorAbs(G);
G = XMVectorSqrt(G);
let S: XMVECTOR = XMVectorAdd(G, CosIncidentAngle);
let D: XMVECTOR = XMVectorSubtract(G, CosIncidentAngle);
let mut V0: XMVECTOR = XMVectorMultiply(D, D);
let mut V1: XMVECTOR = XMVectorMultiply(S, S);
V1 = XMVectorReciprocal(V1);
V0 = XMVectorMultiply(g_XMOneHalf.v, V0);
V0 = XMVectorMultiply(V0, V1);
let mut V2: XMVECTOR = XMVectorMultiplyAdd(CosIncidentAngle, S, g_XMNegativeOne.v);
let mut V3: XMVECTOR = XMVectorMultiplyAdd(CosIncidentAngle, D, g_XMOne.v);
V2 = XMVectorMultiply(V2, V2);
V3 = XMVectorMultiply(V3, V3);
V3 = XMVectorReciprocal(V3);
V2 = XMVectorMultiplyAdd(V2, V3, g_XMOne.v);
let mut Result: XMVECTOR = XMVectorMultiply(V0, V2);
Result = XMVectorSaturate(Result);
return Result;
}
#[cfg(_XM_ARM_NEON_INTRINSICS_)]
{
unimplemented!()
}
#[cfg(_XM_SSE_INTRINSICS_)]
unsafe {
let mut G: XMVECTOR = _mm_mul_ps(RefractionIndex, RefractionIndex);
let mut vTemp: XMVECTOR = _mm_mul_ps(CosIncidentAngle, CosIncidentAngle);
G = _mm_sub_ps(G, g_XMOne.v);
vTemp = _mm_add_ps(vTemp, G);
G = _mm_setzero_ps();
G = _mm_sub_ps(G, vTemp);
G = _mm_max_ps(G, vTemp);
G = _mm_sqrt_ps(G);
let mut GAddC: XMVECTOR = _mm_add_ps(G, CosIncidentAngle);
let mut GSubC: XMVECTOR = _mm_sub_ps(G, CosIncidentAngle);
let mut vResult: XMVECTOR = _mm_mul_ps(GSubC, GSubC);
vTemp = _mm_mul_ps(GAddC, GAddC);
vResult = _mm_mul_ps(vResult, g_XMOneHalf.v);
vResult = _mm_div_ps(vResult, vTemp);
GAddC = _mm_mul_ps(GAddC, CosIncidentAngle);
GSubC = _mm_mul_ps(GSubC, CosIncidentAngle);
GAddC = _mm_sub_ps(GAddC, g_XMOne.v);
GSubC = _mm_add_ps(GSubC, g_XMOne.v);
GAddC = _mm_mul_ps(GAddC, GAddC);
GSubC = _mm_mul_ps(GSubC, GSubC);
GAddC = _mm_div_ps(GAddC, GSubC);
GAddC = _mm_add_ps(GAddC, g_XMOne.v);
vResult = _mm_mul_ps(vResult, GAddC);
vResult = _mm_max_ps(vResult, g_XMZero.v);
vResult = _mm_min_ps(vResult, g_XMOne.v);
return vResult;
}
}
#[inline]
pub fn XMScalarNearEqual(
S1: f32,
S2: f32,
Epsilon: f32
) -> bool
{
let Delta: f32 = S1 - S2;
return (fabsf(Delta) <= Epsilon);
}
#[inline]
pub fn XMScalarModAngle(
Angle: f32
) -> f32
{
let Angle = Angle + XM_PI;
let mut fTemp: f32 = fabsf(Angle);
fTemp = fTemp - (XM_2PI * ((fTemp / XM_2PI) as i32) as f32);
fTemp = fTemp - XM_PI;
if (Angle < 0.0)
{
fTemp = -fTemp;
}
return fTemp;
}
#[inline]
pub fn XMScalarSin(
Value: f32
) -> f32
{
let mut quotient: f32 = XM_1DIV2PI * Value;
if (Value >= 0.0)
{
quotient = ((quotient + 0.5) as i32) as f32;
}
else
{
quotient = ((quotient - 0.5) as i32) as f32;
}
let mut y: f32 = Value - XM_2PI * quotient;
if (y > XM_PIDIV2)
{
y = XM_PI - y;
}
else if (y < -XM_PIDIV2)
{
y = -XM_PI - y;
}
let y2: f32 = y * y;
return (((((-2.3889859e-08 * y2 + 2.7525562e-06) * y2 - 0.00019840874) * y2 + 0.0083333310) * y2 - 0.16666667) * y2 + 1.0) * y;
}
#[inline]
pub fn XMScalarSinEst(
Value: f32
) -> f32
{
let mut quotient: f32 = XM_1DIV2PI * Value;
if (Value >= 0.0)
{
quotient = ((quotient + 0.5) as i32) as f32;
}
else
{
quotient = ((quotient - 0.5) as i32) as f32;
}
let mut y: f32 = Value - XM_2PI * quotient;
if (y > XM_PIDIV2)
{
y = XM_PI - y;
}
else if (y < -XM_PIDIV2)
{
y = -XM_PI - y;
}
let y2: f32 = y * y;
return (((-0.00018524670 * y2 + 0.0083139502) * y2 - 0.16665852) * y2 + 1.0) * y;
}
#[inline]
pub fn XMScalarCos(
Value: f32
) -> f32
{
let mut quotient: f32 = XM_1DIV2PI * Value;
if (Value >= 0.0)
{
quotient = ((quotient + 0.5) as i32) as f32;
}
else
{
quotient = ((quotient - 0.5) as i32) as f32;
}
let mut y: f32 = Value - XM_2PI * quotient;
let sign: f32;
if (y > XM_PIDIV2)
{
y = XM_PI - y;
sign = -1.0;
}
else if (y < -XM_PIDIV2)
{
y = -XM_PI - y;
sign = -1.0;
}
else
{
sign = 1.0;
}
let y2: f32 = y * y;
let p: f32 = ((((-2.6051615e-07 * y2 + 2.4760495e-05) * y2 - 0.0013888378) * y2 + 0.041666638) * y2 - 0.5) * y2 + 1.0;
return sign * p;
}
#[inline]
pub fn XMScalarCosEst(
Value: f32
) -> f32
{
let mut quotient: f32 = XM_1DIV2PI * Value;
if (Value >= 0.0)
{
quotient = ((quotient + 0.5) as i32) as f32;
}
else
{
quotient = ((quotient - 0.5) as i32) as f32;
}
let mut y: f32 = Value - XM_2PI * quotient;
let sign: f32;
if (y > XM_PIDIV2)
{
y = XM_PI - y;
sign = -1.0;
}
else if (y < -XM_PIDIV2)
{
y = -XM_PI - y;
sign = -1.0;
}
else
{
sign = 1.0;
}
let y2: f32 = y * y;
let p: f32 = ((-0.0012712436 * y2 + 0.041493919) * y2 - 0.49992746) * y2 + 1.0;
return sign * p;
}
#[inline]
pub fn XMScalarSinCos(
pSin: &mut f32,
pCos: &mut f32,
Value: f32,
)
{
let mut quotient: f32 = XM_1DIV2PI * Value;
if (Value >= 0.0)
{
quotient = ((quotient + 0.5) as i32) as f32;
}
else
{
quotient = ((quotient - 0.5) as i32) as f32;
}
let mut y: f32 = Value - XM_2PI * quotient;
let sign: f32;
if (y > XM_PIDIV2)
{
y = XM_PI - y;
sign = -1.0;
}
else if (y < -XM_PIDIV2)
{
y = -XM_PI - y;
sign = -1.0;
}
else
{
sign = 1.0; }
let y2: f32 = y * y;
*pSin = (((((-2.3889859e-08 * y2 + 2.7525562e-06) * y2 - 0.00019840874) * y2 + 0.0083333310) * y2 - 0.16666667) * y2 + 1.0) * y;
let p: f32 = ((((-2.6051615e-07 * y2 + 2.4760495e-05) * y2 - 0.0013888378) * y2 + 0.041666638) * y2 - 0.5) * y2 + 1.0;
*pCos = sign * p;
}
#[inline]
pub fn XMScalarSinCosEst(
pSin: &mut f32,
pCos: &mut f32,
Value: f32,
)
{
let mut quotient: f32 = XM_1DIV2PI * Value;
if (Value >= 0.0)
{
quotient = ((quotient + 0.5) as i32) as f32;
}
else
{
quotient = ((quotient - 0.5) as i32) as f32;
}
let mut y: f32 = Value - XM_2PI * quotient;
let sign: f32;
if (y > XM_PIDIV2)
{
y = XM_PI - y;
sign = -1.0;
}
else if (y < -XM_PIDIV2)
{
y = -XM_PI - y;
sign = -1.0;
}
else
{
sign = 1.0;
}
let y2: f32 = y * y;
*pSin = (((-0.00018524670 * y2 + 0.0083139502) * y2 - 0.16665852) * y2 + 1.0) * y;
let p: f32 = ((-0.0012712436 * y2 + 0.041493919) * y2 - 0.49992746) * y2 + 1.0;
*pCos = sign * p;
}
#[inline]
pub fn XMScalarASin(
Value: f32,
) -> f32
{
let nonnegative: bool = (Value >= 0.0);
let x: f32 = fabsf(Value);
let mut omx: f32 = 1.0 - x;
if (omx < 0.0)
{
omx = 0.0;
}
let root: f32 = sqrtf(omx);
let mut result: f32 = ((((((-0.0012624911 * x + 0.0066700901) * x - 0.0170881256) * x + 0.0308918810) * x - 0.0501743046) * x + 0.0889789874) * x - 0.2145988016) * x + 1.5707963050;
result *= root;
return (if nonnegative { XM_PIDIV2 - result } else { result - XM_PIDIV2 });
}
#[inline]
pub fn XMScalarASinEst(
Value: f32,
) -> f32
{
let nonnegative: bool = (Value >= 0.0);
let x: f32 = fabsf(Value);
let mut omx: f32 = 1.0 - x;
if (omx < 0.0)
{
omx = 0.0;
}
let root: f32 = sqrtf(omx);
let mut result: f32 = ((-0.0187293 * x + 0.0742610) * x - 0.2121144) * x + 1.5707288;
result *= root;
return (if nonnegative { XM_PIDIV2 - result } else { result - XM_PIDIV2 });
}
#[inline]
pub fn XMScalarACos(
Value: f32,
) -> f32
{
let nonnegative: bool = (Value >= 0.0);
let x: f32 = fabsf(Value);
let mut omx: f32 = 1.0 - x;
if (omx < 0.0)
{
omx = 0.0;
}
let root: f32 = sqrtf(omx);
let mut result: f32 = ((((((-0.0012624911 * x + 0.0066700901) * x - 0.0170881256) * x + 0.0308918810) * x - 0.0501743046) * x + 0.0889789874) * x - 0.2145988016) * x + 1.5707963050;
result *= root;
return (if nonnegative { result } else { XM_PI - result });
}
#[inline]
pub fn XMScalarACosEst(
Value: f32,
) -> f32
{
let nonnegative: bool = (Value >= 0.0);
let x: f32 = fabsf(Value);
let mut omx: f32 = 1.0 - x;
if (omx < 0.0)
{
omx = 0.0;
}
let root: f32 = sqrtf(omx);
let mut result: f32 = ((-0.0187293 * x + 0.0742610) * x - 0.2121144) * x + 1.5707288;
result *= root;
return (if nonnegative { result } else { XM_PI - result });
}