///////////////////////////////////////////////////////////////////////////////////
/// OpenGL Mathematics (glm.g-truc.net)
///
/// Copyright (c) 2005 – 2015 G-Truc Creation (www.g-truc.net)
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the “Software”), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// Restrictions:
/// By making use of the Software for military purposes, you choose to make
/// a Bunny unhappy.
///
/// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
///
/// @ref core
/// @file glm/detail/type_mat4x4.inl
/// @date 2005-01-27 / 2011-06-15
/// @author Christophe Riccio
///////////////////////////////////////////////////////////////////////////////////
namespace glm{
namespace detail
{
template
GLM_FUNC_QUALIFIER tmat4x4
{
T Coef00 = m[2][2] * m[3][3] – m[3][2] * m[2][3];
T Coef02 = m[1][2] * m[3][3] – m[3][2] * m[1][3];
T Coef03 = m[1][2] * m[2][3] – m[2][2] * m[1][3];
T Coef04 = m[2][1] * m[3][3] – m[3][1] * m[2][3];
T Coef06 = m[1][1] * m[3][3] – m[3][1] * m[1][3];
T Coef07 = m[1][1] * m[2][3] – m[2][1] * m[1][3];
T Coef08 = m[2][1] * m[3][2] – m[3][1] * m[2][2];
T Coef10 = m[1][1] * m[3][2] – m[3][1] * m[1][2];
T Coef11 = m[1][1] * m[2][2] – m[2][1] * m[1][2];
T Coef12 = m[2][0] * m[3][3] – m[3][0] * m[2][3];
T Coef14 = m[1][0] * m[3][3] – m[3][0] * m[1][3];
T Coef15 = m[1][0] * m[2][3] – m[2][0] * m[1][3];
T Coef16 = m[2][0] * m[3][2] – m[3][0] * m[2][2];
T Coef18 = m[1][0] * m[3][2] – m[3][0] * m[1][2];
T Coef19 = m[1][0] * m[2][2] – m[2][0] * m[1][2];
T Coef20 = m[2][0] * m[3][1] – m[3][0] * m[2][1];
T Coef22 = m[1][0] * m[3][1] – m[3][0] * m[1][1];
T Coef23 = m[1][0] * m[2][1] – m[2][0] * m[1][1];
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tvec4
tmat4x4
tvec4
tvec4
T Dot1 = (Dot0.x + Dot0.y) + (Dot0.z + Dot0.w);
T OneOverDeterminant = static_cast
return Inverse * OneOverDeterminant;
}
}//namespace detail
//////////////////////////////////////////////////////////////
// Constructors
template
GLM_FUNC_QUALIFIER tmat4x4
{
# ifndef GLM_FORCE_NO_CTOR_INIT
this->value[0] = col_type(1, 0, 0, 0);
this->value[1] = col_type(0, 1, 0, 0);
this->value[2] = col_type(0, 0, 1, 0);
this->value[3] = col_type(0, 0, 0, 1);
# endif
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = m[0];
this->value[1] = m[1];
this->value[2] = m[2];
this->value[3] = m[3];
}
template
template
{
this->value[0] = m[0];
this->value[1] = m[1];
this->value[2] = m[2];
this->value[3] = m[3];
}
template
GLM_FUNC_QUALIFIER tmat4x4
{}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = col_type(s, 0, 0, 0);
this->value[1] = col_type(0, s, 0, 0);
this->value[2] = col_type(0, 0, s, 0);
this->value[3] = col_type(0, 0, 0, s);
}
template
GLM_FUNC_QUALIFIER tmat4x4
(
T const & x0, T const & y0, T const & z0, T const & w0,
T const & x1, T const & y1, T const & z1, T const & w1,
T const & x2, T const & y2, T const & z2, T const & w2,
T const & x3, T const & y3, T const & z3, T const & w3
)
{
this->value[0] = col_type(x0, y0, z0, w0);
this->value[1] = col_type(x1, y1, z1, w1);
this->value[2] = col_type(x2, y2, z2, w2);
this->value[3] = col_type(x3, y3, z3, w3);
}
template
GLM_FUNC_QUALIFIER tmat4x4
(
col_type const & v0,
col_type const & v1,
col_type const & v2,
col_type const & v3
)
{
this->value[0] = v0;
this->value[1] = v1;
this->value[2] = v2;
this->value[3] = v3;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
(
tmat4x4 const & m
)
{
this->value[0] = col_type(m[0]);
this->value[1] = col_type(m[1]);
this->value[2] = col_type(m[2]);
this->value[3] = col_type(m[3]);
}
//////////////////////////////////////
// Conversion constructors
template
template <
typename X1, typename Y1, typename Z1, typename W1,
typename X2, typename Y2, typename Z2, typename W2,
typename X3, typename Y3, typename Z3, typename W3,
typename X4, typename Y4, typename Z4, typename W4>
GLM_FUNC_QUALIFIER tmat4x4
(
X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2,
X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3,
X4 const & x4, Y4 const & y4, Z4 const & z4, W4 const & w4
)
{
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
this->value[0] = col_type(static_cast
this->value[1] = col_type(static_cast
this->value[2] = col_type(static_cast
this->value[3] = col_type(static_cast
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
(
tvec4
tvec4
tvec4
tvec4
)
{
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
GLM_STATIC_ASSERT(std::numeric_limits
this->value[0] = col_type(v1);
this->value[1] = col_type(v2);
this->value[2] = col_type(v3);
this->value[3] = col_type(v4);
}
//////////////////////////////////////
// Matrix convertion constructors
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = col_type(m[0], 0, 0);
this->value[1] = col_type(m[1], 0, 0);
this->value[2] = col_type(0);
this->value[3] = col_type(0, 0, 0, 1);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = col_type(m[0], 0);
this->value[1] = col_type(m[1], 0);
this->value[2] = col_type(m[2], 0);
this->value[3] = col_type(0, 0, 0, 1);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = col_type(m[0], 0);
this->value[1] = col_type(m[1], 0);
this->value[2] = col_type(0);
this->value[3] = col_type(0, 0, 0, 1);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = col_type(m[0], 0, 0);
this->value[1] = col_type(m[1], 0, 0);
this->value[2] = col_type(m[2], 0, 0);
this->value[3] = col_type(0, 0, 0, 1);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = m[0];
this->value[1] = m[1];
this->value[2] = col_type(0);
this->value[3] = col_type(0, 0, 0, 1);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = col_type(m[0], 0, 0);
this->value[1] = col_type(m[1], 0, 0);
this->value[2] = col_type(0);
this->value[3] = col_type(0, 0, 0, 1);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = m[0];
this->value[1] = m[1];
this->value[2] = m[2];
this->value[3] = col_type(0, 0, 0, 1);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] = col_type(m[0], 0);
this->value[1] = col_type(m[1], 0);
this->value[2] = col_type(m[2], 0);
this->value[3] = col_type(m[3], 1);
}
//////////////////////////////////////
// Accesses
# ifdef GLM_FORCE_SIZE_FUNC
template
GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat4x4
{
return 4;
}
template
GLM_FUNC_QUALIFIER typename tmat4x4
{
assert(i < this->size());
return this->value[i];
}
template
GLM_FUNC_QUALIFIER typename tmat4x4
{
assert(i < this->size());
return this->value[i];
}
# else
template
GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat4x4
{
return 4;
}
template
GLM_FUNC_QUALIFIER typename tmat4x4
{
assert(i < this->length());
return this->value[i];
}
template
GLM_FUNC_QUALIFIER typename tmat4x4
{
assert(i < this->length());
return this->value[i];
}
# endif//GLM_FORCE_SIZE_FUNC
//////////////////////////////////////////////////////////////
// Operators
template
GLM_FUNC_QUALIFIER tmat4x4
{
//memcpy could be faster
//memcpy(&this->value, &m.value, 16 * sizeof(valType));
this->value[0] = m[0];
this->value[1] = m[1];
this->value[2] = m[2];
this->value[3] = m[3];
return *this;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
//memcpy could be faster
//memcpy(&this->value, &m.value, 16 * sizeof(valType));
this->value[0] = m[0];
this->value[1] = m[1];
this->value[2] = m[2];
this->value[3] = m[3];
return *this;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] += s;
this->value[1] += s;
this->value[2] += s;
this->value[3] += s;
return *this;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] += m[0];
this->value[1] += m[1];
this->value[2] += m[2];
this->value[3] += m[3];
return *this;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] -= s;
this->value[1] -= s;
this->value[2] -= s;
this->value[3] -= s;
return *this;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] -= m[0];
this->value[1] -= m[1];
this->value[2] -= m[2];
this->value[3] -= m[3];
return *this;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] *= s;
this->value[1] *= s;
this->value[2] *= s;
this->value[3] *= s;
return *this;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
return (*this = *this * m);
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
this->value[0] /= s;
this->value[1] /= s;
this->value[2] /= s;
this->value[3] /= s;
return *this;
}
template
template
GLM_FUNC_QUALIFIER tmat4x4
{
return (*this = *this * detail::compute_inverse
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
++this->value[0];
++this->value[1];
++this->value[2];
++this->value[3];
return *this;
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
–this->value[0];
–this->value[1];
–this->value[2];
–this->value[3];
return *this;
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
tmat4x4
++*this;
return Result;
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
tmat4x4
–*this;
return Result;
}
// Binary operators
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m[0] + s,
m[1] + s,
m[2] + s,
m[3] + s);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m[0] + s,
m[1] + s,
m[2] + s,
m[3] + s);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m1[0] + m2[0],
m1[1] + m2[1],
m1[2] + m2[2],
m1[3] + m2[3]);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m[0] – s,
m[1] – s,
m[2] – s,
m[3] – s);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
s – m[0],
s – m[1],
s – m[2],
s – m[3]);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m1[0] – m2[0],
m1[1] – m2[1],
m1[2] – m2[2],
m1[3] – m2[3]);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m[0] * s,
m[1] * s,
m[2] * s,
m[3] * s);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m[0] * s,
m[1] * s,
m[2] * s,
m[3] * s);
}
template
GLM_FUNC_QUALIFIER typename tmat4x4
(
tmat4x4
typename tmat4x4
)
{
/*
__m128 v0 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(0, 0, 0, 0));
__m128 v1 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(1, 1, 1, 1));
__m128 v2 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(2, 2, 2, 2));
__m128 v3 = _mm_shuffle_ps(v.data, v.data, _MM_SHUFFLE(3, 3, 3, 3));
__m128 m0 = _mm_mul_ps(m[0].data, v0);
__m128 m1 = _mm_mul_ps(m[1].data, v1);
__m128 a0 = _mm_add_ps(m0, m1);
__m128 m2 = _mm_mul_ps(m[2].data, v2);
__m128 m3 = _mm_mul_ps(m[3].data, v3);
__m128 a1 = _mm_add_ps(m2, m3);
__m128 a2 = _mm_add_ps(a0, a1);
return typename tmat4x4
*/
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
return Add2;
/*
return typename tmat4x4
m[0][0] * v[0] + m[1][0] * v[1] + m[2][0] * v[2] + m[3][0] * v[3],
m[0][1] * v[0] + m[1][1] * v[1] + m[2][1] * v[2] + m[3][1] * v[3],
m[0][2] * v[0] + m[1][2] * v[1] + m[2][2] * v[2] + m[3][2] * v[3],
m[0][3] * v[0] + m[1][3] * v[1] + m[2][3] * v[2] + m[3][3] * v[3]);
*/
}
template
GLM_FUNC_QUALIFIER typename tmat4x4
(
typename tmat4x4
tmat4x4
)
{
return typename tmat4x4
m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3],
m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3],
m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3],
m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]);
}
template
GLM_FUNC_QUALIFIER tmat2x4
{
return tmat2x4
m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3],
m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3],
m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3],
m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3],
m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3]);
}
template
GLM_FUNC_QUALIFIER tmat3x4
{
return tmat3x4
m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
m1[0][3] * m2[0][0] + m1[1][3] * m2[0][1] + m1[2][3] * m2[0][2] + m1[3][3] * m2[0][3],
m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3],
m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1] + m1[2][1] * m2[1][2] + m1[3][1] * m2[1][3],
m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3],
m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3],
m1[0][0] * m2[2][0] + m1[1][0] * m2[2][1] + m1[2][0] * m2[2][2] + m1[3][0] * m2[2][3],
m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3],
m1[0][2] * m2[2][0] + m1[1][2] * m2[2][1] + m1[2][2] * m2[2][2] + m1[3][2] * m2[2][3],
m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2] + m1[3][3] * m2[2][3]);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
typename tmat4x4
tmat4x4
Result[0] = SrcA0 * SrcB0[0] + SrcA1 * SrcB0[1] + SrcA2 * SrcB0[2] + SrcA3 * SrcB0[3];
Result[1] = SrcA0 * SrcB1[0] + SrcA1 * SrcB1[1] + SrcA2 * SrcB1[2] + SrcA3 * SrcB1[3];
Result[2] = SrcA0 * SrcB2[0] + SrcA1 * SrcB2[1] + SrcA2 * SrcB2[2] + SrcA3 * SrcB2[3];
Result[3] = SrcA0 * SrcB3[0] + SrcA1 * SrcB3[1] + SrcA2 * SrcB3[2] + SrcA3 * SrcB3[3];
return Result;
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m[0] / s,
m[1] / s,
m[2] / s,
m[3] / s);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
s / m[0],
s / m[1],
s / m[2],
s / m[3]);
}
template
GLM_FUNC_QUALIFIER typename tmat4x4
{
return detail::compute_inverse
}
template
GLM_FUNC_QUALIFIER typename tmat4x4
{
return v * detail::compute_inverse
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
tmat4x4
return m1_copy /= m2;
}
// Unary constant operators
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
-m[0],
-m[1],
-m[2],
-m[3]);
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m[0] + static_cast
m[1] + static_cast
m[2] + static_cast
m[3] + static_cast
}
template
GLM_FUNC_QUALIFIER tmat4x4
{
return tmat4x4
m[0] – static_cast
m[1] – static_cast
m[2] – static_cast
m[3] – static_cast
}
//////////////////////////////////////
// Boolean operators
template
GLM_FUNC_QUALIFIER bool operator==(tmat4x4
{
return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]);
}
template
GLM_FUNC_QUALIFIER bool operator!=(tmat4x4
{
return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]);
}
}//namespace glm