diff --git a/glm/ext.hpp b/glm/ext.hpp index 73941328..eb404a8e 100644 --- a/glm/ext.hpp +++ b/glm/ext.hpp @@ -11,12 +11,8 @@ #define glm_ext #include "./gtc/double_float.hpp" -#include "./gtc/gl_replacement.hpp" -#include "./gtc/glu_replacement.hpp" #include "./gtc/half_float.hpp" #include "./gtc/matrix_access.hpp" -#include "./gtc/matrix_operation.hpp" -#include "./gtc/matrix_projection.hpp" #include "./gtc/matrix_transform.hpp" #include "./gtc/quaternion.hpp" #include "./gtc/swizzle.hpp" @@ -49,11 +45,9 @@ #include "./gtx/inverse.hpp" #include "./gtx/inverse_transpose.hpp" #include "./gtx/log_base.hpp" -#include "./gtx/matrix_access.hpp" #include "./gtx/matrix_cross_product.hpp" #include "./gtx/matrix_major_storage.hpp" #include "./gtx/matrix_operation.hpp" -#include "./gtx/matrix_projection.hpp" #include "./gtx/matrix_query.hpp" #include "./gtx/matrix_selection.hpp" #include "./gtx/mixed_product.hpp" diff --git a/glm/gtc/gl_replacement.hpp b/glm/gtc/gl_replacement.hpp index 1c7f19c7..95f83454 100644 --- a/glm/gtc/gl_replacement.hpp +++ b/glm/gtc/gl_replacement.hpp @@ -15,7 +15,8 @@ // Dependency: #include "../glm.hpp" -#include "../gtc/gl_replacement.hpp" +#include "../gtc/matrix_transform.hpp" +#include "../gtc/matrix_projection.hpp" namespace glm { @@ -27,49 +28,6 @@ namespace glm //! GLM_GTC_gl_replacement extension: GLM replacement functions for OpenGL compatibility function namespace gl_replacement { - //! Builds a translation 4 * 4 matrix created from a vector of 3 components. - //! From GLM_GTC_gl_replacement extension. - template - detail::tmat4x4 translate( - detail::tmat4x4 const & m, - detail::tvec3 const & v); - - //! Builds a rotation 4 * 4 matrix created from an axis vector and an angle expressed in degrees. - //! From GLM_GTC_gl_replacement extension. - template - detail::tmat4x4 rotate( - detail::tmat4x4 const & m, - T const & angle, - detail::tvec3 const & v); - - //! Builds a scale 4 * 4 matrix created from 3 scalars. - //! From GLM_GTC_gl_replacement extension. - template - detail::tmat4x4 scale( - detail::tmat4x4 const & m, - detail::tvec3 const & v); - - //! Creates a matrix for an orthographic parallel viewing volume. - //! From GLM_GTC_matrix_projection extension. - template - detail::tmat4x4 ortho( - T const & left, - T const & right, - T const & bottom, - T const & top, - T const & zNear, - T const & zFar); - - //! Creates a frustum matrix. - //! From GLM_GTC_matrix_projection extension. - template - detail::tmat4x4 frustum( - T const & left, - T const & right, - T const & bottom, - T const & top, - T const & nearVal, - T const & farVal); }//namespace gl_replacement }//namespace gtc diff --git a/glm/gtc/gl_replacement.inl b/glm/gtc/gl_replacement.inl index 2121165e..e2642e20 100644 --- a/glm/gtc/gl_replacement.inl +++ b/glm/gtc/gl_replacement.inl @@ -11,176 +11,7 @@ namespace glm{ namespace gtc{ namespace gl_replacement { - template - inline detail::tmat4x4 translate - ( - detail::tmat4x4 const & m, - detail::tvec3 const & v - ) - { - detail::tmat4x4 Result(m); - Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3]; - return Result; - } - - template - inline detail::tmat4x4 rotate - ( - detail::tmat4x4 const & m, - T const & angle, - detail::tvec3 const & v - ) - { - T a = radians(angle); - T c = cos(a); - T s = sin(a); - detail::tvec3 axis = normalize(v); - - detail::tvec3 temp = (T(1) - c) * axis; - - detail::tmat4x4 Rotate(detail::tmat4x4::null); - Rotate[0][0] = c + temp[0] * axis[0]; - Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2]; - Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1]; - - Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2]; - Rotate[1][1] = c + temp[1] * axis[1]; - Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0]; - - Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1]; - Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0]; - Rotate[2][2] = c + temp[2] * axis[2]; - - detail::tmat4x4 Result(detail::tmat4x4::null); - Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; - Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; - Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; - Result[3] = m[3]; - return Result; - } - - template - inline detail::tmat4x4 scale - ( - detail::tmat4x4 const & m, - detail::tvec3 const & v - ) - { - detail::tmat4x4 Result(detail::tmat4x4::null); - Result[0] = m[0] * v[0]; - Result[1] = m[1] * v[1]; - Result[2] = m[2] * v[2]; - Result[3] = m[3]; - return Result; - } - - template - inline detail::tmat4x4 translate_slow - ( - detail::tmat4x4 const & m, - detail::tvec3 const & v - ) - { - detail::tmat4x4 Result(T(1)); - Result[3] = detail::tvec4(v, T(1)); - return m * Result; - - //detail::tmat4x4 Result(m); - Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3]; - //Result[3][0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0]; - //Result[3][1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1]; - //Result[3][2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2]; - //Result[3][3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3]; - //return Result; - } - - template - inline detail::tmat4x4 rotate_slow - ( - detail::tmat4x4 const & m, - T const & angle, - detail::tvec3 const & v - ) - { - T a = radians(angle); - T c = cos(a); - T s = sin(a); - detail::tmat4x4 Result; - - detail::tvec3 axis = normalize(v); - - Result[0][0] = c + (1 - c) * axis.x * axis.x; - Result[0][1] = (1 - c) * axis.x * axis.y + s * axis.z; - Result[0][2] = (1 - c) * axis.x * axis.z - s * axis.y; - Result[0][3] = 0; - - Result[1][0] = (1 - c) * axis.y * axis.x - s * axis.z; - Result[1][1] = c + (1 - c) * axis.y * axis.y; - Result[1][2] = (1 - c) * axis.y * axis.z + s * axis.x; - Result[1][3] = 0; - - Result[2][0] = (1 - c) * axis.z * axis.x + s * axis.y; - Result[2][1] = (1 - c) * axis.z * axis.y - s * axis.x; - Result[2][2] = c + (1 - c) * axis.z * axis.z; - Result[2][3] = 0; - - Result[3] = detail::tvec4(0, 0, 0, 1); - return m * Result; - } - - template - inline detail::tmat4x4 scale_slow - ( - detail::tmat4x4 const & m, - detail::tvec3 const & v - ) - { - detail::tmat4x4 Result(T(1)); - Result[0][0] = v.x; - Result[1][1] = v.y; - Result[2][2] = v.z; - return m * Result; - } - - template - inline detail::tmat4x4 ortho( - valType const & left, - valType const & right, - valType const & bottom, - valType const & top, - valType const & zNear, - valType const & zFar) - { - detail::tmat4x4 Result(1); - Result[0][0] = valType(2) / (right - left); - Result[1][1] = valType(2) / (top - bottom); - Result[2][2] = - valType(2) / (zFar - zNear); - Result[3][0] = - (right + left) / (right - left); - Result[3][1] = - (top + bottom) / (top - bottom); - Result[3][2] = - (zFar + zNear) / (zFar - zNear); - return Result; - } - - template - inline detail::tmat4x4 frustum( - valType const & left, - valType const & right, - valType const & bottom, - valType const & top, - valType const & nearVal, - valType const & farVal) - { - detail::tmat4x4 Result(0); - Result[0][0] = (valType(2) * nearVal) / (right - left); - Result[1][1] = (valType(2) * nearVal) / (top - bottom); - Result[2][0] = (right + left) / (right - left); - Result[2][1] = (top + bottom) / (top - bottom); - Result[2][2] = -(farVal + nearVal) / (farVal - nearVal); - Result[2][3] = valType(-1); - Result[3][2] = -(valType(2) * farVal * nearVal) / (farVal - nearVal); - return Result; - } }//namespace gl_replacement }//namespace gtc diff --git a/glm/gtc/glu_replacement.hpp b/glm/gtc/glu_replacement.hpp index 010b13b6..90a9213a 100644 --- a/glm/gtc/glu_replacement.hpp +++ b/glm/gtc/glu_replacement.hpp @@ -29,50 +29,6 @@ namespace glm { using namespace gtc::gl_replacement; - //! Creates a matrix for projecting two-dimensional coordinates onto the screen. - //! From GLM_GTC_glu_replacement extension. - template - detail::tmat4x4 ortho( - T const & left, - T const & right, - T const & bottom, - T const & top); - - //! Creates a matrix for a symetric perspective-view frustum. - //! From GLM_GTC_glu_replacement extension. - template - detail::tmat4x4 perspective( - T const & fovy, - T const & aspect, - T const & zNear, - T const & zFar); - - //! Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. - //! From GLM_GTC_glu_replacement extension. - template - detail::tvec3 project( - detail::tvec3 const & obj, - detail::tmat4x4 const & model, - detail::tmat4x4 const & proj, - detail::tvec4 const & viewport); - - //! Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. - //! From GLM_GTC_glu_replacement extension. - template - detail::tvec3 unProject( - detail::tvec3 const & win, - detail::tmat4x4 const & model, - detail::tmat4x4 const & proj, - detail::tvec4 const & viewport); - - //! Build a look at view matrix. - //! From GLM_GTC_glu_replacement extension. - template - detail::tmat4x4 lookAt( - detail::tvec3 const & eye, - detail::tvec3 const & center, - detail::tvec3 const & up); - }//namespace glu_replacement }//namespace gtc }//namespace glm diff --git a/glm/gtc/glu_replacement.inl b/glm/gtc/glu_replacement.inl index fdb4ba9e..22b6d24b 100644 --- a/glm/gtc/glu_replacement.inl +++ b/glm/gtc/glu_replacement.inl @@ -11,111 +11,7 @@ namespace glm{ namespace gtc{ namespace glu_replacement { - template - inline detail::tmat4x4 ortho( - valType const & left, - valType const & right, - valType const & bottom, - valType const & top) - { - detail::tmat4x4 Result(1); - Result[0][0] = valType(2) / (right - left); - Result[1][1] = valType(2) / (top - bottom); - Result[2][2] = - valType(1); - Result[3][0] = - (right + left) / (right - left); - Result[3][1] = - (top + bottom) / (top - bottom); - return Result; - } - template - inline detail::tmat4x4 perspective( - valType const & fovy, - valType const & aspect, - valType const & zNear, - valType const & zFar) - { - valType range = tan(radians(fovy / valType(2))) * zNear; - valType left = -range * aspect; - valType right = range * aspect; - valType bottom = -range; - valType top = range; - - detail::tmat4x4 Result(valType(0)); - Result[0][0] = (valType(2) * zNear) / (right - left); - Result[1][1] = (valType(2) * zNear) / (top - bottom); - Result[2][2] = - (zFar + zNear) / (zFar - zNear); - Result[2][3] = - valType(1); - Result[3][2] = - (valType(2) * zFar * zNear) / (zFar - zNear); - return Result; - } - - template - inline detail::tvec3 project( - detail::tvec3 const & obj, - detail::tmat4x4 const & model, - detail::tmat4x4 const & proj, - detail::tvec4 const & viewport) - { - detail::tvec4 tmp = detail::tvec4(obj, T(1)); - tmp = model * tmp; - tmp = proj * tmp; - - tmp /= tmp.w; - tmp = tmp * T(0.5) + T(0.5); - tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); - tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); - - return detail::tvec3(tmp); - } - - template - inline detail::tvec3 unProject( - detail::tvec3 const & win, - detail::tmat4x4 const & model, - detail::tmat4x4 const & proj, - detail::tvec4 const & viewport) - { - detail::tmat4x4 inverse = glm::inverse(proj * model); - - detail::tvec4 tmp = detail::tvec4(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 * T(2) - T(1); - - detail::tvec4 obj = inverse * tmp; - obj /= obj.w; - - return detail::tvec3(obj); - } - - template - inline detail::tmat4x4 lookAt( - const detail::tvec3& eye, - const detail::tvec3& center, - const detail::tvec3& up) - { - detail::tvec3 f = normalize(center - eye); - detail::tvec3 u = normalize(up); - detail::tvec3 s = normalize(cross(f, u)); - u = cross(s, f); - - detail::tmat4x4 Result(1); - Result[0][0] = s.x; - Result[1][0] = s.y; - Result[2][0] = s.z; - Result[0][1] = u.x; - Result[1][1] = u.y; - Result[2][1] = u.z; - Result[0][2] =-f.x; - Result[1][2] =-f.y; - Result[2][2] =-f.z; - /* Test this instead of translate3D - Result[3][0] =-dot(s, eye); - Result[3][1] =-dot(y, eye); - Result[3][2] = dot(f, eye); - */ - return gtc::matrix_transform::translate(Result, -eye); - } }//namespace glu_replacement }//namespace gtc diff --git a/glm/gtc/matrix_projection.hpp b/glm/gtc/matrix_projection.hpp index 650ccb9d..b08a92df 100644 --- a/glm/gtc/matrix_projection.hpp +++ b/glm/gtc/matrix_projection.hpp @@ -16,7 +16,6 @@ // Dependency: #include "../glm.hpp" -#include "../gtc/glu_replacement.hpp" namespace glm { @@ -28,7 +27,7 @@ namespace glm //! GLM_GTC_matrix_projection: Varius ways to build and operate on projection matrices namespace matrix_projection { - using namespace gtc::glu_replacement; + }//namespace matrix_projection }//namespace gtc diff --git a/glm/gtc/matrix_projection.inl b/glm/gtc/matrix_projection.inl index d9121353..70b36691 100644 --- a/glm/gtc/matrix_projection.inl +++ b/glm/gtc/matrix_projection.inl @@ -12,7 +12,6 @@ namespace gtc{ namespace matrix_projection { - }//namespace matrix_projection }//namespace gtc }//namespace glm diff --git a/glm/gtc/matrix_transform.hpp b/glm/gtc/matrix_transform.hpp index 94096a7b..57b6bee3 100644 --- a/glm/gtc/matrix_transform.hpp +++ b/glm/gtc/matrix_transform.hpp @@ -28,7 +28,93 @@ namespace glm //! GLM_GTC_matrix_transform extension: Add transformation matrices namespace matrix_transform { - using namespace gtc::gl_replacement; + //! Builds a translation 4 * 4 matrix created from a vector of 3 components. + //! From GLM_GTC_matrix_transform extension. + template + detail::tmat4x4 translate( + detail::tmat4x4 const & m, + detail::tvec3 const & v); + + //! Builds a rotation 4 * 4 matrix created from an axis vector and an angle expressed in degrees. + //! From GLM_GTC_matrix_transform extension. + template + detail::tmat4x4 rotate( + detail::tmat4x4 const & m, + T const & angle, + detail::tvec3 const & v); + + //! Builds a scale 4 * 4 matrix created from 3 scalars. + //! From GLM_GTC_matrix_transform extension. + template + detail::tmat4x4 scale( + detail::tmat4x4 const & m, + detail::tvec3 const & v); + + //! Creates a matrix for an orthographic parallel viewing volume. + //! From GLM_GTC_matrix_transform extension. + template + detail::tmat4x4 ortho( + T const & left, + T const & right, + T const & bottom, + T const & top, + T const & zNear, + T const & zFar); + + //! Creates a matrix for projecting two-dimensional coordinates onto the screen. + //! From GLM_GTC_matrix_transform extension. + template + detail::tmat4x4 ortho( + T const & left, + T const & right, + T const & bottom, + T const & top); + + //! Creates a frustum matrix. + //! From GLM_GTC_matrix_transform extension. + template + detail::tmat4x4 frustum( + T const & left, + T const & right, + T const & bottom, + T const & top, + T const & nearVal, + T const & farVal); + + //! Creates a matrix for a symetric perspective-view frustum. + //! From GLM_GTC_matrix_transform extension. + template + detail::tmat4x4 perspective( + T const & fovy, + T const & aspect, + T const & zNear, + T const & zFar); + + //! Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates. + //! From GLM_GTC_glu_replacement extension. + template + detail::tvec3 project( + detail::tvec3 const & obj, + detail::tmat4x4 const & model, + detail::tmat4x4 const & proj, + detail::tvec4 const & viewport); + + //! Map the specified window coordinates (win.x, win.y, win.z) into object coordinates. + //! From GLM_GTC_glu_replacement extension. + template + detail::tvec3 unProject( + detail::tvec3 const & win, + detail::tmat4x4 const & model, + detail::tmat4x4 const & proj, + detail::tvec4 const & viewport); + + //! Build a look at view matrix. + //! From GLM_GTC_matrix_transform extension. + template + detail::tmat4x4 lookAt( + detail::tvec3 const & eye, + detail::tvec3 const & center, + detail::tvec3 const & up); }//namespace matrix_transform }//namespace gtc diff --git a/glm/gtc/matrix_transform.inl b/glm/gtc/matrix_transform.inl index edddd895..ead8b994 100644 --- a/glm/gtc/matrix_transform.inl +++ b/glm/gtc/matrix_transform.inl @@ -11,7 +11,282 @@ namespace glm{ namespace gtc{ namespace matrix_transform { + template + inline detail::tmat4x4 translate + ( + detail::tmat4x4 const & m, + detail::tvec3 const & v + ) + { + detail::tmat4x4 Result(m); + Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3]; + return Result; + } + + template + inline detail::tmat4x4 rotate + ( + detail::tmat4x4 const & m, + T const & angle, + detail::tvec3 const & v + ) + { + T a = radians(angle); + T c = cos(a); + T s = sin(a); + detail::tvec3 axis = normalize(v); + + detail::tvec3 temp = (T(1) - c) * axis; + + detail::tmat4x4 Rotate(detail::tmat4x4::null); + Rotate[0][0] = c + temp[0] * axis[0]; + Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2]; + Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1]; + + Rotate[1][0] = 0 + temp[1] * axis[0] - s * axis[2]; + Rotate[1][1] = c + temp[1] * axis[1]; + Rotate[1][2] = 0 + temp[1] * axis[2] + s * axis[0]; + + Rotate[2][0] = 0 + temp[2] * axis[0] + s * axis[1]; + Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0]; + Rotate[2][2] = c + temp[2] * axis[2]; + + detail::tmat4x4 Result(detail::tmat4x4::null); + Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2]; + Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2]; + Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2]; + Result[3] = m[3]; + return Result; + } + + template + inline detail::tmat4x4 scale + ( + detail::tmat4x4 const & m, + detail::tvec3 const & v + ) + { + detail::tmat4x4 Result(detail::tmat4x4::null); + Result[0] = m[0] * v[0]; + Result[1] = m[1] * v[1]; + Result[2] = m[2] * v[2]; + Result[3] = m[3]; + return Result; + } + + template + inline detail::tmat4x4 translate_slow + ( + detail::tmat4x4 const & m, + detail::tvec3 const & v + ) + { + detail::tmat4x4 Result(T(1)); + Result[3] = detail::tvec4(v, T(1)); + return m * Result; + + //detail::tmat4x4 Result(m); + Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3]; + //Result[3][0] = m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0]; + //Result[3][1] = m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1]; + //Result[3][2] = m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2]; + //Result[3][3] = m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3]; + //return Result; + } + + template + inline detail::tmat4x4 rotate_slow + ( + detail::tmat4x4 const & m, + T const & angle, + detail::tvec3 const & v + ) + { + T a = radians(angle); + T c = cos(a); + T s = sin(a); + detail::tmat4x4 Result; + + detail::tvec3 axis = normalize(v); + + Result[0][0] = c + (1 - c) * axis.x * axis.x; + Result[0][1] = (1 - c) * axis.x * axis.y + s * axis.z; + Result[0][2] = (1 - c) * axis.x * axis.z - s * axis.y; + Result[0][3] = 0; + + Result[1][0] = (1 - c) * axis.y * axis.x - s * axis.z; + Result[1][1] = c + (1 - c) * axis.y * axis.y; + Result[1][2] = (1 - c) * axis.y * axis.z + s * axis.x; + Result[1][3] = 0; + + Result[2][0] = (1 - c) * axis.z * axis.x + s * axis.y; + Result[2][1] = (1 - c) * axis.z * axis.y - s * axis.x; + Result[2][2] = c + (1 - c) * axis.z * axis.z; + Result[2][3] = 0; + + Result[3] = detail::tvec4(0, 0, 0, 1); + return m * Result; + } + + template + inline detail::tmat4x4 scale_slow + ( + detail::tmat4x4 const & m, + detail::tvec3 const & v + ) + { + detail::tmat4x4 Result(T(1)); + Result[0][0] = v.x; + Result[1][1] = v.y; + Result[2][2] = v.z; + return m * Result; + } + + template + inline detail::tmat4x4 ortho( + valType const & left, + valType const & right, + valType const & bottom, + valType const & top, + valType const & zNear, + valType const & zFar) + { + detail::tmat4x4 Result(1); + Result[0][0] = valType(2) / (right - left); + Result[1][1] = valType(2) / (top - bottom); + Result[2][2] = - valType(2) / (zFar - zNear); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + Result[3][2] = - (zFar + zNear) / (zFar - zNear); + return Result; + } + + template + inline detail::tmat4x4 ortho( + valType const & left, + valType const & right, + valType const & bottom, + valType const & top) + { + detail::tmat4x4 Result(1); + Result[0][0] = valType(2) / (right - left); + Result[1][1] = valType(2) / (top - bottom); + Result[2][2] = - valType(1); + Result[3][0] = - (right + left) / (right - left); + Result[3][1] = - (top + bottom) / (top - bottom); + return Result; + } + + template + inline detail::tmat4x4 frustum( + valType const & left, + valType const & right, + valType const & bottom, + valType const & top, + valType const & nearVal, + valType const & farVal) + { + detail::tmat4x4 Result(0); + Result[0][0] = (valType(2) * nearVal) / (right - left); + Result[1][1] = (valType(2) * nearVal) / (top - bottom); + Result[2][0] = (right + left) / (right - left); + Result[2][1] = (top + bottom) / (top - bottom); + Result[2][2] = -(farVal + nearVal) / (farVal - nearVal); + Result[2][3] = valType(-1); + Result[3][2] = -(valType(2) * farVal * nearVal) / (farVal - nearVal); + return Result; + } + + template + inline detail::tmat4x4 perspective( + valType const & fovy, + valType const & aspect, + valType const & zNear, + valType const & zFar) + { + valType range = tan(radians(fovy / valType(2))) * zNear; + valType left = -range * aspect; + valType right = range * aspect; + valType bottom = -range; + valType top = range; + + detail::tmat4x4 Result(valType(0)); + Result[0][0] = (valType(2) * zNear) / (right - left); + Result[1][1] = (valType(2) * zNear) / (top - bottom); + Result[2][2] = - (zFar + zNear) / (zFar - zNear); + Result[2][3] = - valType(1); + Result[3][2] = - (valType(2) * zFar * zNear) / (zFar - zNear); + return Result; + } + + template + inline detail::tvec3 project( + detail::tvec3 const & obj, + detail::tmat4x4 const & model, + detail::tmat4x4 const & proj, + detail::tvec4 const & viewport) + { + detail::tvec4 tmp = detail::tvec4(obj, T(1)); + tmp = model * tmp; + tmp = proj * tmp; + + tmp /= tmp.w; + tmp = tmp * T(0.5) + T(0.5); + tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]); + tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]); + + return detail::tvec3(tmp); + } + + template + inline detail::tvec3 unProject( + detail::tvec3 const & win, + detail::tmat4x4 const & model, + detail::tmat4x4 const & proj, + detail::tvec4 const & viewport) + { + detail::tmat4x4 inverse = glm::inverse(proj * model); + + detail::tvec4 tmp = detail::tvec4(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 * T(2) - T(1); + + detail::tvec4 obj = inverse * tmp; + obj /= obj.w; + + return detail::tvec3(obj); + } + + template + inline detail::tmat4x4 lookAt( + const detail::tvec3& eye, + const detail::tvec3& center, + const detail::tvec3& up) + { + detail::tvec3 f = normalize(center - eye); + detail::tvec3 u = normalize(up); + detail::tvec3 s = normalize(cross(f, u)); + u = cross(s, f); + + detail::tmat4x4 Result(1); + Result[0][0] = s.x; + Result[1][0] = s.y; + Result[2][0] = s.z; + Result[0][1] = u.x; + Result[1][1] = u.y; + Result[2][1] = u.z; + Result[0][2] =-f.x; + Result[1][2] =-f.y; + Result[2][2] =-f.z; + /* Test this instead of translate3D + Result[3][0] =-dot(s, eye); + Result[3][1] =-dot(y, eye); + Result[3][2] = dot(f, eye); + */ + return gtc::matrix_transform::translate(Result, -eye); + } }//namespace matrix_transform }//namespace gtc }//namespace glm