| 2459 | |
| 2460 | COVERAGE(HMM_M4ToQ_LH, 4) |
| 2461 | static inline HMM_Quat HMM_M4ToQ_LH(HMM_Mat4 M) |
| 2462 | { |
| 2463 | float T; |
| 2464 | HMM_Quat Q; |
| 2465 | |
| 2466 | if (M.Elements[2][2] < 0.0f) { |
| 2467 | if (M.Elements[0][0] > M.Elements[1][1]) { |
| 2468 | ASSERT_COVERED(HMM_M4ToQ_LH); |
| 2469 | |
| 2470 | T = 1 + M.Elements[0][0] - M.Elements[1][1] - M.Elements[2][2]; |
| 2471 | Q = HMM_Q( |
| 2472 | T, |
| 2473 | M.Elements[0][1] + M.Elements[1][0], |
| 2474 | M.Elements[2][0] + M.Elements[0][2], |
| 2475 | M.Elements[2][1] - M.Elements[1][2] |
| 2476 | ); |
| 2477 | } else { |
| 2478 | ASSERT_COVERED(HMM_M4ToQ_LH); |
| 2479 | |
| 2480 | T = 1 - M.Elements[0][0] + M.Elements[1][1] - M.Elements[2][2]; |
| 2481 | Q = HMM_Q( |
| 2482 | M.Elements[0][1] + M.Elements[1][0], |
| 2483 | T, |
| 2484 | M.Elements[1][2] + M.Elements[2][1], |
| 2485 | M.Elements[0][2] - M.Elements[2][0] |
| 2486 | ); |
| 2487 | } |
| 2488 | } else { |
| 2489 | if (M.Elements[0][0] < -M.Elements[1][1]) { |
| 2490 | ASSERT_COVERED(HMM_M4ToQ_LH); |
| 2491 | |
| 2492 | T = 1 - M.Elements[0][0] - M.Elements[1][1] + M.Elements[2][2]; |
| 2493 | Q = HMM_Q( |
| 2494 | M.Elements[2][0] + M.Elements[0][2], |
| 2495 | M.Elements[1][2] + M.Elements[2][1], |
| 2496 | T, |
| 2497 | M.Elements[1][0] - M.Elements[0][1] |
| 2498 | ); |
| 2499 | } else { |
| 2500 | ASSERT_COVERED(HMM_M4ToQ_LH); |
| 2501 | |
| 2502 | T = 1 + M.Elements[0][0] + M.Elements[1][1] + M.Elements[2][2]; |
| 2503 | Q = HMM_Q( |
| 2504 | M.Elements[2][1] - M.Elements[1][2], |
| 2505 | M.Elements[0][2] - M.Elements[2][0], |
| 2506 | M.Elements[1][0] - M.Elements[0][2], |
| 2507 | T |
| 2508 | ); |
| 2509 | } |
| 2510 | } |
| 2511 | |
| 2512 | Q = HMM_MulQF(Q, 0.5f / HMM_SqrtF(T)); |
| 2513 | |
| 2514 | return Q; |
| 2515 | } |
| 2516 | |
| 2517 | |
| 2518 | COVERAGE(HMM_QFromAxisAngle_RH, 1) |