namespace glm { template 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) { vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast(1)); tmp = model * tmp; tmp = proj * tmp; tmp /= tmp.w; tmp.x = tmp.x * static_cast(0.5) + static_cast(0.5); tmp.y = tmp.y * static_cast(0.5) + static_cast(0.5); tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); return vec<3, T, Q>(tmp); } template 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) { vec<4, T, Q> tmp = vec<4, T, Q>(obj, static_cast(1)); tmp = model * tmp; tmp = proj * tmp; tmp /= tmp.w; tmp = tmp * static_cast(0.5) + static_cast(0.5); tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); return vec<3, T, Q>(tmp); } template 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) { # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT return projectZO(obj, model, proj, viewport); # else return projectNO(obj, model, proj, viewport); # endif } template 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) { mat<4, 4, T, Q> Inverse = inverse(proj * model); vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1)); tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); tmp.x = tmp.x * static_cast(2) - static_cast(1); tmp.y = tmp.y * static_cast(2) - static_cast(1); vec<4, T, Q> obj = Inverse * tmp; obj /= obj.w; return vec<3, T, Q>(obj); } template 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) { mat<4, 4, T, Q> Inverse = inverse(proj * model); vec<4, T, Q> tmp = vec<4, T, Q>(win, T(1)); tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]); tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]); tmp = tmp * static_cast(2) - static_cast(1); vec<4, T, Q> obj = Inverse * tmp; obj /= obj.w; return vec<3, T, Q>(obj); } template 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) { # if GLM_CONFIG_CLIP_CONTROL & GLM_CLIP_CONTROL_ZO_BIT return unProjectZO(win, model, proj, viewport); # else return unProjectNO(win, model, proj, viewport); # endif } template 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) { assert(delta.x > static_cast(0) && delta.y > static_cast(0)); mat<4, 4, T, Q> Result(static_cast(1)); if(!(delta.x > static_cast(0) && delta.y > static_cast(0))) return Result; // Error vec<3, T, Q> Temp( (static_cast(viewport[2]) - static_cast(2) * (center.x - static_cast(viewport[0]))) / delta.x, (static_cast(viewport[3]) - static_cast(2) * (center.y - static_cast(viewport[1]))) / delta.y, static_cast(0)); // Translate and scale the picked region to the entire window Result = translate(Result, Temp); return scale(Result, vec<3, T, Q>(static_cast(viewport[2]) / delta.x, static_cast(viewport[3]) / delta.y, static_cast(1))); } }//namespace glm