mirror of
https://github.com/g-truc/glm.git
synced 2024-11-22 08:54:35 +00:00
Merge pull request #1099 from Windsander/shearing
feat: add shearing matrix operation on matrix_transfom #1099
This commit is contained in:
commit
b2a9dae6dc
@ -95,6 +95,33 @@ namespace glm
|
||||
GLM_FUNC_DECL mat<4, 4, T, Q> scale(
|
||||
mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v);
|
||||
|
||||
/// Builds a scale 4 * 4 matrix created from point referent 3 shearers.
|
||||
///
|
||||
/// @param m Input matrix multiplied by this shear matrix.
|
||||
/// @param p Point of shearing as reference.
|
||||
/// @param l_x Ratio of matrix.x projection in YZ plane relative to the y-axis/z-axis.
|
||||
/// @param l_y Ratio of matrix.y projection in XZ plane relative to the x-axis/z-axis.
|
||||
/// @param l_z Ratio of matrix.z projection in XY plane relative to the x-axis/y-axis.
|
||||
///
|
||||
/// as example:
|
||||
/// [1 , l_xy, l_xz, -(l_xy+l_xz) * p_x] [x] T
|
||||
/// [x`, y`, z`, w`] = [x`, y`, z`, w`] * [l_yx, 1 , l_yz, -(l_yx+l_yz) * p_y] [y]
|
||||
/// [l_zx, l_zy, 1 , -(l_zx+l_zy) * p_z] [z]
|
||||
/// [0 , 0 , 0 , 1 ] [w]
|
||||
///
|
||||
/// @tparam T A floating-point shear type
|
||||
/// @tparam Q A value from qualifier enum
|
||||
///
|
||||
/// @see - shear(mat<4, 4, T, Q> const& m, T x, T y, T z)
|
||||
/// @see - shear(vec<3, T, Q> const& p)
|
||||
/// @see - shear(vec<2, T, Q> const& l_x)
|
||||
/// @see - shear(vec<2, T, Q> const& l_y)
|
||||
/// @see - shear(vec<2, T, Q> const& l_z)
|
||||
/// @see no resource...
|
||||
template <typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shear(
|
||||
mat<4, 4, T, Q> const &m, vec<3, T, Q> const& p, vec<2, T, Q> const &l_x, vec<2, T, Q> const &l_y, vec<2, T, Q> const &l_z);
|
||||
|
||||
/// Build a right handed look at view matrix.
|
||||
///
|
||||
/// @param eye Position of the camera
|
||||
|
@ -95,6 +95,60 @@ namespace glm
|
||||
return m * Result;
|
||||
}
|
||||
|
||||
template <typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shear(mat<4, 4, T, Q> const &m, vec<3, T, Q> const& p, vec<2, T, Q> const &l_x, vec<2, T, Q> const &l_y, vec<2, T, Q> const &l_z)
|
||||
{
|
||||
T const lambda_xy = l_x[0];
|
||||
T const lambda_xz = l_x[1];
|
||||
T const lambda_yx = l_y[0];
|
||||
T const lambda_yz = l_y[1];
|
||||
T const lambda_zx = l_z[0];
|
||||
T const lambda_zy = l_z[1];
|
||||
|
||||
vec<3, T, Q> point_lambda = vec<3, T, Q>(
|
||||
(lambda_xy + lambda_xz), (lambda_yx + lambda_yz), (lambda_zx + lambda_zy)
|
||||
);
|
||||
|
||||
mat<4, 4, T, Q> Shear = mat<4, 4, T, Q>(
|
||||
1 , lambda_yx , lambda_zx , 0,
|
||||
lambda_xy , 1 , lambda_zy , 0,
|
||||
lambda_xz , lambda_yz , 1 , 0,
|
||||
-point_lambda[0] * p[0], -point_lambda[1] * p[1], -point_lambda[2] * p[2], 1
|
||||
);
|
||||
|
||||
mat<4, 4, T, Q> Result;
|
||||
Result[0] = Shear[0] * m[0][0] + Shear[1] * m[0][1] + Shear[2] * m[0][2] + Shear[3] * m[0][3];
|
||||
Result[1] = Shear[0] * m[1][0] + Shear[1] * m[1][1] + Shear[2] * m[1][2] + Shear[3] * m[1][3];
|
||||
Result[2] = Shear[0] * m[2][0] + Shear[1] * m[2][1] + Shear[2] * m[2][2] + Shear[3] * m[2][3];
|
||||
Result[3] = Shear[0] * m[3][0] + Shear[1] * m[3][1] + Shear[2] * m[3][2] + Shear[3] * m[3][3];
|
||||
return Result;
|
||||
}
|
||||
|
||||
template <typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> shear_slow(mat<4, 4, T, Q> const &m, vec<3, T, Q> const& p, vec<2, T, Q> const &l_x, vec<2, T, Q> const &l_y, vec<2, T, Q> const &l_z)
|
||||
{
|
||||
T const lambda_xy = static_cast<T>(l_x[0]);
|
||||
T const lambda_xz = static_cast<T>(l_x[1]);
|
||||
T const lambda_yx = static_cast<T>(l_y[0]);
|
||||
T const lambda_yz = static_cast<T>(l_y[1]);
|
||||
T const lambda_zx = static_cast<T>(l_z[0]);
|
||||
T const lambda_zy = static_cast<T>(l_z[1]);
|
||||
|
||||
vec<3, T, Q> point_lambda = vec<3, T, Q>(
|
||||
static_cast<T>(lambda_xy + lambda_xz),
|
||||
static_cast<T>(lambda_yx + lambda_yz),
|
||||
static_cast<T>(lambda_zx + lambda_zy)
|
||||
);
|
||||
|
||||
mat<4, 4, T, Q> Shear = mat<4, 4, T, Q>(
|
||||
1 , lambda_yx , lambda_zx , 0,
|
||||
lambda_xy , 1 , lambda_zy , 0,
|
||||
lambda_xz , lambda_yz , 1 , 0,
|
||||
-point_lambda[0] * p[0], -point_lambda[1] * p[1], -point_lambda[2] * p[2], 1
|
||||
);
|
||||
return m * Shear;
|
||||
}
|
||||
|
||||
template<typename T, qualifier Q>
|
||||
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtRH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
|
||||
{
|
||||
|
@ -240,6 +240,85 @@ int test_inverse_simd()
|
||||
return Error;
|
||||
}
|
||||
|
||||
int test_shearing()
|
||||
{
|
||||
int Error = 0;
|
||||
|
||||
{
|
||||
glm::vec3 const center(0, 0, 0);
|
||||
glm::vec2 const l_x(2, 0);
|
||||
glm::vec2 const l_y(0, 0);
|
||||
glm::vec2 const l_z(0, 0);
|
||||
glm::mat4x4 const A4x4(
|
||||
glm::vec4(0, 0, 1, 1),
|
||||
glm::vec4(0, 1, 1, 0),
|
||||
glm::vec4(1, 1, 1, 0),
|
||||
glm::vec4(1, 1, 0, 1));
|
||||
glm::mat4x4 const B4x4 = glm::shear(A4x4, center, l_x, l_y, l_z);
|
||||
glm::mat4x4 const expected(
|
||||
glm::vec4(0, 0, 1, 1),
|
||||
glm::vec4(2, 1, 1, 0),
|
||||
glm::vec4(3, 1, 1, 0),
|
||||
glm::vec4(3, 1, 0, 1));
|
||||
Error += all(equal(B4x4, expected, epsilon<float>())) ? 0 : 1;
|
||||
}
|
||||
|
||||
{
|
||||
glm::vec3 const center(0, 0, 0);
|
||||
glm::vec2 const l_x(1, 0);
|
||||
glm::vec2 const l_y(0, 1);
|
||||
glm::vec2 const l_z(1, 0);
|
||||
glm::mat4x4 const A4x4(
|
||||
glm::vec4(0, 0, 1, 0),
|
||||
glm::vec4(0, 1, 1, 0),
|
||||
glm::vec4(1, 1, 1, 0),
|
||||
glm::vec4(1, 0, 0, 0));
|
||||
glm::mat4x4 const B4x4 = glm::shear(A4x4, center, l_x, l_y, l_z);
|
||||
glm::mat4x4 const expected(
|
||||
glm::vec4(0, 1, 1, 0),
|
||||
glm::vec4(1, 2, 1, 0),
|
||||
glm::vec4(2, 2, 2, 0),
|
||||
glm::vec4(1, 0, 1, 0));
|
||||
Error += all(equal(B4x4, expected, epsilon<float>())) ? 0 : 1;
|
||||
}
|
||||
|
||||
{
|
||||
glm::vec3 const center(3, 2, 1);
|
||||
glm::vec2 const l_x(1, 2);
|
||||
glm::vec2 const l_y(3, 1);
|
||||
glm::vec2 const l_z(4, 5);
|
||||
glm::mat4x4 const A4x4(1);
|
||||
glm::mat4x4 const B4x4 = glm::shear(A4x4, center, l_x, l_y, l_z);
|
||||
glm::mat4x4 const expected(
|
||||
glm::vec4(1, 3, 4, 0),
|
||||
glm::vec4(1, 1, 5, 0),
|
||||
glm::vec4(2, 1, 1, 0),
|
||||
glm::vec4(-9, -8, -9, 1));
|
||||
Error += all(equal(B4x4, expected, epsilon<float>())) ? 0 : 1;
|
||||
}
|
||||
|
||||
{
|
||||
glm::vec3 const center(3, 2, 1);
|
||||
glm::vec2 const l_x(1, 2);
|
||||
glm::vec2 const l_y(3, 1);
|
||||
glm::vec2 const l_z(4, 5);
|
||||
glm::mat4x4 const A4x4(
|
||||
glm::vec4(-3, 2, 1, 0),
|
||||
glm::vec4(3, 2, 1, 0),
|
||||
glm::vec4(4, -8, 0, 0),
|
||||
glm::vec4(7, 1, -2, 0));
|
||||
glm::mat4x4 const B4x4 = glm::shear(A4x4, center, l_x, l_y, l_z);
|
||||
glm::mat4x4 const expected(
|
||||
glm::vec4(1, -6, -1, 0),
|
||||
glm::vec4(7, 12, 23, 0),
|
||||
glm::vec4(-4, 4, -24, 0),
|
||||
glm::vec4(4, 20, 31, 0));
|
||||
Error += all(equal(B4x4, expected, epsilon<float>())) ? 0 : 1;
|
||||
}
|
||||
|
||||
return Error;
|
||||
}
|
||||
|
||||
template<typename VEC3, typename MAT4>
|
||||
int test_inverse_perf(std::size_t Count, std::size_t Instance, char const * Message)
|
||||
{
|
||||
@ -294,6 +373,7 @@ int main()
|
||||
Error += test_determinant();
|
||||
Error += test_inverse();
|
||||
Error += test_inverse_simd();
|
||||
Error += test_shearing();
|
||||
|
||||
# ifdef NDEBUG
|
||||
std::size_t const Samples = 1000;
|
||||
|
Loading…
Reference in New Issue
Block a user