Skip to content

Commit e282990

Browse files
mariob92christophe-lunarg
authored andcommitted
Implement #1370 (reflection matrix calculation)
- add reflect2D - rewrite functions to accept an input matrix - add tests
1 parent 5f9187f commit e282990

File tree

4 files changed

+170
-27
lines changed

4 files changed

+170
-27
lines changed

glm/gtx/transform2.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,15 @@ namespace glm
5757
// Identity + tan(angle) * cross(Normal, OnPlaneVector) 0
5858
// - dot(PointOnPlane, normal) * OnPlaneVector 1
5959

60-
//! Build a reflection matrix.
60+
//! Reflects a matrix on an arbitrary plane.
6161
//! From GLM_GTX_transform2 extension.
6262
template<typename T, qualifier Q>
63-
GLM_FUNC_DECL mat<4, 4, T, Q> reflect3D(vec<3, T, Q> const& normal, T distance);
63+
GLM_FUNC_DECL mat<3, 3, T, Q> reflect2D(mat<3, 3, T, Q> const& m, vec<2, T, Q> const& normal, T distance);
64+
65+
//! Reflects a matrix on an arbitrary plane.
66+
//! From GLM_GTX_transform2 extension.
67+
template<typename T, qualifier Q>
68+
GLM_FUNC_DECL mat<4, 4, T, Q> reflect3D(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& normal, T distance);
6469

6570
//! Build planar projection matrix along normal axis.
6671
//! From GLM_GTX_transform2 extension.

glm/gtx/transform2.inl

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,34 +45,36 @@ namespace glm
4545
return m * r;
4646
}
4747

48-
// template<typename T, qualifier Q>
49-
// GLM_FUNC_QUALIFIER mat<3, 3, T, Q> reflect2D(mat<3, 3, T, Q> const& m, vec<3, T, Q> const& normal)
50-
// {
51-
// mat<3, 3, T, Q> r(static_cast<T>(1));
52-
// r[0][0] = static_cast<T>(1) - static_cast<T>(2) * normal.x * normal.x;
53-
// r[0][1] = -static_cast<T>(2) * normal.x * normal.y;
54-
// r[1][0] = -static_cast<T>(2) * normal.x * normal.y;
55-
// r[1][1] = static_cast<T>(1) - static_cast<T>(2) * normal.y * normal.y;
56-
// return m * r;
57-
// }
48+
template<typename T, qualifier Q>
49+
GLM_FUNC_QUALIFIER mat<3, 3, T, Q> reflect2D(mat<3, 3, T, Q> const& m, vec<2, T, Q> const& normal, T distance)
50+
{
51+
mat<3, 3, T, Q> r(static_cast<T>(1));
52+
r[0][0] = static_cast<T>(1) - static_cast<T>(2) * normal.x * normal.x;
53+
r[0][1] = -static_cast<T>(2) * normal.y * normal.x;
54+
r[1][0] = -static_cast<T>(2) * normal.x * normal.y;
55+
r[1][1] = static_cast<T>(1) - static_cast<T>(2) * normal.y * normal.y;
56+
r[2][0] = -static_cast<T>(2) * normal.x * distance;
57+
r[2][1] = -static_cast<T>(2) * normal.y * distance;
58+
return m * r;
59+
}
5860

5961
template<typename T, qualifier Q>
60-
GLM_FUNC_DECL mat<4, 4, T, Q> reflect3D(vec<3, T, Q> const& normal, T distance)
62+
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> reflect3D(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& normal, T distance)
6163
{
62-
mat<4, 4, T, Q> result(static_cast<T>(1));
63-
result[0][0] = static_cast<T>(1) - static_cast<T>(2) * normal.x * normal.x;
64-
result[0][1] = -static_cast<T>(2) * normal.y * normal.x;
65-
result[0][2] = -static_cast<T>(2) * normal.z * normal.x;
66-
result[1][0] = -static_cast<T>(2) * normal.x * normal.y;
67-
result[1][1] = static_cast<T>(1) - static_cast<T>(2) * normal.y * normal.y;
68-
result[1][2] = -static_cast<T>(2) * normal.z * normal.y;
69-
result[2][0] = -static_cast<T>(2) * normal.x * normal.z;
70-
result[2][1] = -static_cast<T>(2) * normal.y * normal.z;
71-
result[2][2] = static_cast<T>(1) - static_cast<T>(2) * normal.z * normal.z;
72-
result[3][0] = -static_cast<T>(2) * normal.x * distance;
73-
result[3][1] = -static_cast<T>(2) * normal.y * distance;
74-
result[3][2] = -static_cast<T>(2) * normal.z * distance;
75-
return result;
64+
mat<4, 4, T, Q> r(static_cast<T>(1));
65+
r[0][0] = static_cast<T>(1) - static_cast<T>(2) * normal.x * normal.x;
66+
r[0][1] = -static_cast<T>(2) * normal.y * normal.x;
67+
r[0][2] = -static_cast<T>(2) * normal.z * normal.x;
68+
r[1][0] = -static_cast<T>(2) * normal.x * normal.y;
69+
r[1][1] = static_cast<T>(1) - static_cast<T>(2) * normal.y * normal.y;
70+
r[1][2] = -static_cast<T>(2) * normal.z * normal.y;
71+
r[2][0] = -static_cast<T>(2) * normal.x * normal.z;
72+
r[2][1] = -static_cast<T>(2) * normal.y * normal.z;
73+
r[2][2] = static_cast<T>(1) - static_cast<T>(2) * normal.z * normal.z;
74+
r[3][0] = -static_cast<T>(2) * normal.x * distance;
75+
r[3][1] = -static_cast<T>(2) * normal.y * distance;
76+
r[3][2] = -static_cast<T>(2) * normal.z * distance;
77+
return m * r;
7678
}
7779

7880
template<typename T, qualifier Q>

test/gtx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ glmCreateTestGTC(gtx_spline)
5353
glmCreateTestGTC(gtx_string_cast)
5454
glmCreateTestGTC(gtx_structured_bindings)
5555
glmCreateTestGTC(gtx_texture)
56+
glmCreateTestGTC(gtx_transform2)
5657
glmCreateTestGTC(gtx_type_aligned)
5758
glmCreateTestGTC(gtx_type_trait)
5859
glmCreateTestGTC(gtx_vec_swizzle)

test/gtx/gtx_transform2.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#include <glm/glm.hpp>
2+
#include <glm/gtc/epsilon.hpp>
3+
4+
#define GLM_ENABLE_EXPERIMENTAL
5+
#include <glm/gtx/transform2.hpp>
6+
7+
static int test_reflect2D()
8+
{
9+
int Error = 0;
10+
11+
{
12+
const glm::mat3 m3(
13+
1, 0, 0,
14+
0, 1, 0,
15+
1, 2, 1
16+
);
17+
18+
const glm::mat3 eam3(
19+
1, 0, 0,
20+
0, -1, 0,
21+
1, 2, 1
22+
);
23+
24+
const glm::mat3 am3 = glm::reflect2D(
25+
m3,
26+
glm::vec2(0, 1),
27+
static_cast<glm::mat3::row_type::value_type>(0)
28+
);
29+
30+
Error += glm::all(glm::bvec3(
31+
glm::all(glm::epsilonEqual(eam3[0], am3[0], glm::epsilon<float>())),
32+
glm::all(glm::epsilonEqual(eam3[1], am3[1], glm::epsilon<float>())),
33+
glm::all(glm::epsilonEqual(eam3[2], am3[2], glm::epsilon<float>())))) ? 0 : 1;
34+
}
35+
36+
{
37+
const glm::mat3 m3(
38+
1, 0, 0,
39+
0, 1, 0,
40+
1, 2, 1
41+
);
42+
43+
const glm::mat3 eam3(
44+
0, 1, 0,
45+
1, 0, 0,
46+
1, 2, 1
47+
);
48+
49+
const glm::mat3 am3 = glm::reflect2D(
50+
m3,
51+
glm::vec2(-0.70710678, 0.70710678),
52+
static_cast<glm::mat3::row_type::value_type>(0)
53+
);
54+
55+
Error += glm::all(glm::bvec3(
56+
glm::all(glm::epsilonEqual(eam3[0], am3[0], glm::epsilon<float>())),
57+
glm::all(glm::epsilonEqual(eam3[1], am3[1], glm::epsilon<float>())),
58+
glm::all(glm::epsilonEqual(eam3[2], am3[2], glm::epsilon<float>())))) ? 0 : 1;
59+
}
60+
61+
return Error;
62+
}
63+
64+
static int test_reflect3D()
65+
{
66+
int Error = 0;
67+
68+
{
69+
const glm::mat4 m4(
70+
1, 0, 0, 0,
71+
0, 1, 0, 0,
72+
0, 0, 1, 0,
73+
0, 0, 0, 1
74+
);
75+
76+
const glm::mat4 eam4(
77+
1, 0, 0, 0,
78+
0, -1, 0, 0,
79+
0, 0, 1, 0,
80+
0, -2, 0, 1
81+
);
82+
83+
const glm::mat4 am4 = glm::reflect3D(
84+
m4,
85+
glm::vec3(0, 1, 0),
86+
static_cast<glm::mat4::row_type::value_type>(1)
87+
);
88+
89+
Error += glm::all(glm::bvec4(
90+
glm::all(glm::epsilonEqual(eam4[0], am4[0], glm::epsilon<float>())),
91+
glm::all(glm::epsilonEqual(eam4[1], am4[1], glm::epsilon<float>())),
92+
glm::all(glm::epsilonEqual(eam4[2], am4[2], glm::epsilon<float>())),
93+
glm::all(glm::epsilonEqual(eam4[3], am4[3], glm::epsilon<float>())))) ? 0 : 1;
94+
}
95+
96+
{
97+
const glm::mat4 m4(
98+
1, 0, 0, 0,
99+
0, 1, 0, 0,
100+
0, 0, 1, 0,
101+
0, 0, 0, 1
102+
);
103+
104+
const glm::mat4 eam4(
105+
0, 1, 0, 0,
106+
1, 0, 0, 0,
107+
0, 0, 1, 0,
108+
0, 0, 0, 1
109+
);
110+
111+
const glm::mat4 am4 = glm::reflect3D(
112+
m4,
113+
glm::vec3(-0.70710678, 0.70710678, 0.0),
114+
static_cast<glm::mat4::row_type::value_type>(0)
115+
);
116+
117+
Error += glm::all(glm::bvec4(
118+
glm::all(glm::epsilonEqual(eam4[0], am4[0], glm::epsilon<float>())),
119+
glm::all(glm::epsilonEqual(eam4[1], am4[1], glm::epsilon<float>())),
120+
glm::all(glm::epsilonEqual(eam4[2], am4[2], glm::epsilon<float>())),
121+
glm::all(glm::epsilonEqual(eam4[3], am4[3], glm::epsilon<float>())))) ? 0 : 1;
122+
}
123+
124+
return Error;
125+
}
126+
127+
int main()
128+
{
129+
int Error = 0;
130+
131+
Error += test_reflect2D();
132+
Error += test_reflect3D();
133+
134+
return Error;
135+
}

0 commit comments

Comments
 (0)