| 1 | namespace glm |
| 2 | { |
| 3 | template<typename T, typename U, qualifier Q> |
| 4 | GLM_FUNC_QUALIFIER vec<3, T, Q> projectZO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) |
| 5 | { |
| 6 | vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast<T>(1)); |
| 7 | tmp = model * tmp; |
| 8 | tmp = proj * tmp; |
| 9 | |
| 10 | tmp /= tmp.w; |
| 11 | tmp.x = tmp.x * static_cast<T>(0.5) + static_cast<T>(0.5); |
| 12 | tmp.y = tmp.y * static_cast<T>(0.5) + static_cast<T>(0.5); |
| 13 | |
| 14 | tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); |
| 15 | tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); |
| 16 | |
| 17 | return vec<3, T, Q>(tmp); |
| 18 | } |
| 19 | |
| 20 | template<typename T, typename U, qualifier Q> |
| 21 | GLM_FUNC_QUALIFIER vec<3, T, Q> projectNO(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) |
| 22 | { |
| 23 | vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast<T>(1)); |
| 24 | tmp = model * tmp; |
| 25 | tmp = proj * tmp; |
| 26 | |
| 27 | tmp /= tmp.w; |
| 28 | tmp = tmp * static_cast<T>(0.5) + static_cast<T>(0.5); |
| 29 | tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); |
| 30 | tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); |
| 31 | |
| 32 | return vec<3, T, Q>(tmp); |
| 33 | } |
| 34 | |
| 35 | template<typename T, typename U, qualifier Q> |
| 36 | GLM_FUNC_QUALIFIER vec<3, T, Q> project(vec<3, T, Q> const& obj, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) |
| 37 | { |
| 38 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT |
| 39 | return projectZO(obj, model, proj, viewport); |
| 40 | # else |
| 41 | return projectNO(obj, model, proj, viewport); |
| 42 | # endif |
| 43 | } |
| 44 | |
| 45 | template<typename T, typename U, qualifier Q> |
| 46 | GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectZO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) |
| 47 | { |
| 48 | mat<4, 4, T, Q> Inverse = inverse(proj * model); |
| 49 | |
| 50 | vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1)); |
| 51 | tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); |
| 52 | tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); |
| 53 | tmp.x = tmp.x * static_cast<T>(2) - static_cast<T>(1); |
| 54 | tmp.y = tmp.y * static_cast<T>(2) - static_cast<T>(1); |
| 55 | |
| 56 | vec<4, T, Q> obj = Inverse * tmp; |
| 57 | obj /= obj.w; |
| 58 | |
| 59 | return vec<3, T, Q>(obj); |
| 60 | } |
| 61 | |
| 62 | template<typename T, typename U, qualifier Q> |
| 63 | GLM_FUNC_QUALIFIER vec<3, T, Q> unProjectNO(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) |
| 64 | { |
| 65 | mat<4, 4, T, Q> Inverse = inverse(proj * model); |
| 66 | |
| 67 | vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1)); |
| 68 | tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); |
| 69 | tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); |
| 70 | tmp = tmp * static_cast<T>(2) - static_cast<T>(1); |
| 71 | |
| 72 | vec<4, T, Q> obj = Inverse * tmp; |
| 73 | obj /= obj.w; |
| 74 | |
| 75 | return vec<3, T, Q>(obj); |
| 76 | } |
| 77 | |
| 78 | template<typename T, typename U, qualifier Q> |
| 79 | GLM_FUNC_QUALIFIER vec<3, T, Q> unProject(vec<3, T, Q> const& win, mat<4, 4, T, Q> const& model, mat<4, 4, T, Q> const& proj, vec<4, U, Q> const& viewport) |
| 80 | { |
| 81 | # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT |
| 82 | return unProjectZO(win, model, proj, viewport); |
| 83 | # else |
| 84 | return unProjectNO(win, model, proj, viewport); |
| 85 | # endif |
| 86 | } |
| 87 | |
| 88 | template<typename T, qualifier Q, typename U> |
| 89 | GLM_FUNC_QUALIFIER mat<4, 4, T, Q> pickMatrix(vec<2, T, Q> const& center, vec<2, T, Q> const& delta, vec<4, U, Q> const& viewport) |
| 90 | { |
| 91 | assert(delta.x > static_cast<T>(0) && delta.y > static_cast<T>(0)); |
| 92 | mat<4, 4, T, Q> Result(static_cast<T>(1)); |
| 93 | |
| 94 | if(!(delta.x > static_cast<T>(0) && delta.y > static_cast<T>(0))) |
| 95 | return Result; // Error |
| 96 | |
| 97 | vec<3, T, Q> Temp( |
| 98 | (static_cast<T>(viewport[2]) - static_cast<T>(2) * (center.x - static_cast<T>(viewport[0]))) / delta.x, |
| 99 | (static_cast<T>(viewport[3]) - static_cast<T>(2) * (center.y - static_cast<T>(viewport[1]))) / delta.y, |
| 100 | static_cast<T>(0)); |
| 101 | |
| 102 | // Translate and scale the picked region to the entire window |
| 103 | Result = translate(Result, Temp); |
| 104 | return scale(Result, vec<3, T, Q>(static_cast<T>(viewport[2]) / delta.x, static_cast<T>(viewport[3]) / delta.y, static_cast<T>(1))); |
| 105 | } |
| 106 | }//namespace glm |