This is done via a union. It must be enabled with GLM_SIMD_ENABLE_XYZW_UNION. A nameless struct/union warning in VC (C4201) is explicitly disabled with the "pragma warning(push/pop)" system.
Allowing xyzw access makes it much easier to toggle between SIMD and non-SIMD builds.
The original implementation had the same mistakes than the ray-sphere
intersection.
Added two new 'out' parameters to return both intersection ponits.
Changed the implementation to the geomethric method.
Changed the original analytic method to a geometrical.
The errors in the original intersection calculation:
The function has a sphere center parameter, but ignores it and assumes
that the sphere is in the origo.
It calculates the length of the ray direction vector, but later on uses
this vector as a unit vector.
The position calculation is simply wrong. It multiplies the direction
vector with the radius of the sphere instead of the calculated
intersection distance.
The quadratic equation solving could be improved too:
There should be an early exit for negative discriminant.
The naive implementation sould be changed to a floating-point
specialized one.
NB: glm::detail::tmat2x2::_inverse() incorrectly swaps all components instead of only main diagonals:
A = ⌈a b⌉
⌊c d⌋
(using standard representation). _inverse() on A incorrectly gives the order
⌈ d -c⌉
⌊-b a⌋
(swaps both diagonals) where it should be
⌈ d -b⌉
⌊-c a⌋
(I am leaving out division by the determinate for clarity).
Also, glm::inverse() in `glm/core/func_matrix.inl` is correct for 2x2 matrices and shows the mistake of _inverse().
The unit tests do not appear to test division of a mat2 by a mat2 (where this could arise).