matrix_projection.inl 3.9 KB

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