/// <summary> /// Check an llRot2Euler conversion. /// </summary> /// <remarks> /// Testing Rot2Euler this way instead of comparing against expected angles because /// 1. There are several ways to get to the original Quaternion. For example a rotation /// of PI and -PI will give the same result. But PI and -PI aren't equal. /// 2. This method checks to see if the calculated angles from a quaternion can be used /// to create a new quaternion to produce the same rotation. /// However, can't compare the newly calculated quaternion against the original because /// once again, there are multiple quaternions that give the same result. For instance /// <X, Y, Z, S> == <-X, -Y, -Z, -S>. Additionally, the magnitude of S can be changed /// and will still result in the same rotation if the values for X, Y, Z are also changed /// to compensate. /// However, if two quaternions represent the same rotation, then multiplying the first /// quaternion by the conjugate of the second, will give a third quaternion representing /// a zero rotation. This can be tested for by looking at the X, Y, Z values which should /// be zero. /// </remarks> /// <param name="rot"></param> private void CheckllRot2Euler(LSL_Types.Quaternion rot) { // Call LSL function to convert quaternion rotaion to euler radians. LSL_Types.Vector3 eulerCalc = m_lslApi.llRot2Euler(rot); // Now use the euler radians to recalculate a new quaternion rotation LSL_Types.Quaternion newRot = m_lslApi.llEuler2Rot(eulerCalc); // Multiple original quaternion by conjugate of quaternion calculated with angles. LSL_Types.Quaternion check = rot * new LSL_Types.Quaternion(-newRot.x, -newRot.y, -newRot.z, newRot.s); Assert.AreEqual(0.0, check.x, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler X bounds check fail"); Assert.AreEqual(0.0, check.y, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler Y bounds check fail"); Assert.AreEqual(0.0, check.z, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler Z bounds check fail"); }