public static XMVector Orthogonal(XMVector v) { XMVector zero = XMVector.Zero; XMVector z = XMVector.SplatZ(v); XMVector yzyy = new XMVector(v.Y, v.Z, v.Y, v.Y); XMVector negativeV = XMVector.Subtract(zero, v); XMVector z_isNegative = XMVector.Less(z, zero); XMVector yzyyIsNegative = XMVector.Less(yzyy, zero); XMVector s = XMVector.Add(yzyy, z); XMVector d = XMVector.Subtract(yzyy, z); XMVector select = XMVector.EqualInt(z_isNegative, yzyyIsNegative); XMVector r0 = new XMVector(s.X, negativeV.X, negativeV.X, negativeV.X); XMVector r1 = new XMVector(d.X, v.X, v.X, v.X); return(XMVector.Select(r1, r0, select)); }
public static XMVector ClampLengthV(XMVector v, XMVector lengthMin, XMVector lengthMax) { Debug.Assert(lengthMin.Y == lengthMin.X && lengthMin.Z == lengthMin.X && lengthMin.W == lengthMin.X, "Reviewed"); Debug.Assert(lengthMax.Y == lengthMax.X && lengthMax.Z == lengthMax.X && lengthMax.W == lengthMax.X, "Reviewed"); Debug.Assert(XMVector4.GreaterOrEqual(lengthMin, XMGlobalConstants.Zero), "Reviewed"); Debug.Assert(XMVector4.GreaterOrEqual(lengthMax, XMGlobalConstants.Zero), "Reviewed"); Debug.Assert(XMVector4.GreaterOrEqual(lengthMax, lengthMin), "Reviewed"); XMVector lengthSq = XMVector4.LengthSquare(v); XMVector zero = XMVector.Zero; XMVector reciprocalLength = lengthSq.ReciprocalSqrt(); XMVector infiniteLength = XMVector.EqualInt(lengthSq, XMGlobalConstants.Infinity); XMVector zeroLength = XMVector.Equal(lengthSq, zero); XMVector normal = XMVector.Multiply(v, reciprocalLength); XMVector length = XMVector.Multiply(lengthSq, reciprocalLength); XMVector select = XMVector.EqualInt(infiniteLength, zeroLength); length = XMVector.Select(lengthSq, length, select); normal = XMVector.Select(lengthSq, normal, select); XMVector controlMax = XMVector.Greater(length, lengthMax); XMVector controlMin = XMVector.Less(length, lengthMin); XMVector clampLength = XMVector.Select(length, lengthMax, controlMax); clampLength = XMVector.Select(clampLength, lengthMin, controlMin); XMVector result = XMVector.Multiply(normal, clampLength); // Preserve the original vector (with no precision loss) if the length falls within the given range XMVector control = XMVector.EqualInt(controlMax, controlMin); result = XMVector.Select(result, v, control); return(result); }