make quaternion to rotate 'v0' to 'v1'
| 1335 | |
| 1336 | //! make quaternion to rotate 'v0' to 'v1' |
| 1337 | VECTORCALL VECMATH_FINLINE quat4f v_quat_from_arc(vec3f v0, vec3f v1) |
| 1338 | { |
| 1339 | vec4f inv_len_product = v_rsqrt_x(v_mul_x(v_length3_sq_x(v0), v_length3_sq_x(v1))); |
| 1340 | vec4f cosAngle = v_mul_x(v_dot3(v0, v1), inv_len_product); |
| 1341 | vec4f cosAngleX2Plus2 = v_madd_x(cosAngle, V_C_TWO, V_C_TWO); |
| 1342 | if (v_extract_x(cosAngleX2Plus2) > 1e-4) |
| 1343 | { |
| 1344 | vec3f crossVec = v_cross3(v0, v1); |
| 1345 | vec4f recipCosHalfAngleX2 = v_rsqrt_x(cosAngleX2Plus2); |
| 1346 | vec4f cosHalfAngleX2 = v_mul_x(recipCosHalfAngleX2, cosAngleX2Plus2); |
| 1347 | return v_perm_xyzd( |
| 1348 | v_mul(crossVec, v_splat_x(v_mul_x(recipCosHalfAngleX2, inv_len_product))), |
| 1349 | v_splat_x(v_mul_x(cosHalfAngleX2, V_C_HALF))); |
| 1350 | } |
| 1351 | // slow path for opposite vectors |
| 1352 | if (v_test_vec_x_eq_0(v0)) |
| 1353 | return v_perm_xzbx(v_mul(v0, V_C_UNIT_0010), v_neg(v0)); |
| 1354 | return v_perm_yaxx(v_mul(v0, V_C_UNIT_0100), v_neg(v0)); |
| 1355 | } |
| 1356 | |
| 1357 | //! make quaternion to rotate 'ang' radians around 'v' vector; v must be normalized |
| 1358 | VECTORCALL inline quat4f v_quat_from_unit_vec_ang(vec3f v, vec4f ang) |
nothing calls this directly
no test coverage detected