fennec
Loading...
Searching...
No Matches
transform.h
1// =====================================================================================================================
2// fennec, a free and open source game engine
3// Copyright © 2025 Medusa Slockbower
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17// =====================================================================================================================
18
19#ifndef FENNEC_MATH_EXT_TRANSFORM_H
20#define FENNEC_MATH_EXT_TRANSFORM_H
21
22#include <fennec/math/matrix.h>
25#include <fennec/math/ext/quaternion.h>
26
27namespace fennec
28{
29
34template<typename genType>
35constexpr mat<genType, 3, 3> translation(const vector<genType, 0, 1>& x) {
36 return mat<genType, 3, 3>(
37 1, 0, 0,
38 0, 1, 0,
39 x, 1
40 );
41}
42
47template<typename genType>
48constexpr mat<genType, 4, 4> translation(const vector<genType, 0, 1, 2>& x) {
49 return mat<genType, 4, 4>(
50 1, 0, 0, 0,
51 0, 1, 0, 0,
52 0, 0, 1, 0,
53 x, 1
54 );
55}
56
61template<typename genType>
62constexpr mat<genType, 3, 3> scaling(const vector<genType, 0, 1>& x) {
63 return mat<genType, 3, 3>(
64 x.x, 0, 0,
65 0, x.y, 0,
66 0, 0, 1
67 );
68}
69
74template<typename genType>
75constexpr mat<genType, 4, 4> scaling(const vector<genType, 0, 1, 2>& x) {
76 return mat<genType, 4, 4>(
77 x.x, 0, 0, 0,
78 0, x.y, 0, 0,
79 0, 0, x.z, 0,
80 0, 0, 0, 1
81 );
82}
83
84template<typename genType>
85constexpr mat<genType, 3, 3> shear(const vector<genType, 0, 1>& x) {
86 return mat<genType, 3, 3>(
87 1, x.x, 0,
88 x.y, 1, 0,
89 0, 0, 1
90 );
91}
92
97template<typename genType>
98constexpr mat<genType, 3, 3> rotation(const genType a) {
99
100 // Calculate sin and cos terms
101 const genType c = fennec::cos(a);
102 const genType s = fennec::sin(a);
103
104 // Calculate the matrix
105 return mat<genType, 3, 3>(
106 c, -s, 0,
107 s, c, 0,
108 0, 0, 1
109 );
110}
111
117template<typename genType>
118constexpr mat<genType, 4, 4> rotation(const vector<genType, 0, 1, 2>& A, genType a) {
119 // https://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle
120
121 // Calculate sin and cos terms
122 const genType c = fennec::cos(a);
123 const genType s = fennec::sin(a);
124
125 // Calculate axis term
126 const vector<genType, 0, 1, 2> u = (fennec::one<genType>() - c) * A;
127 const vector<genType, 0, 1, 2> v = s * A;
128
129 // Calculate the Matrix
130 return mat<genType, 4, 4>(
131 A.x * u.x + c, A.x * u.y + v.z, A.x * u.z - v.y, 0,
132 A.x * u.y - v.z, A.y * u.y + c, A.y * u.z + v.x, 0,
133 A.x * u.z + v.y, A.y * u.z - v.x, A.z * u.z + c, 0,
134 0, 0, 0, 1
135 );
136}
137
138// template<typename genType>
139// constexpr qua<genType> rotation(const vector<genType, 0, 1, 2>& axis, genType angle) {
140// vector<genType, 0, 1, 2> a = fennec::normalize(axis);
141// const genType s = fennec::sin(angle);
142//
143// return qua<genType>(fennec::cos(angle * genType(0.5)), s * a);
144// }
145
147enum rotation_
148{
149 rotation_x = 0
150, rotation_y
151, rotation_z
152};
153
159template<typename genType, rotation_ axis>
160constexpr mat<genType, 4, 4> rotation(genType a) {
161 // https://en.wikipedia.org/wiki/Rotation_matrix#Basic_3D_rotations
162
163 // Calculate sin and cos terms
164 const genType c = fennec::cos(a);
165 const genType s = fennec::sin(a);
166
167 // Calculate the matrix
168 if constexpr(axis == rotation_x) {
169 return mat<genType, 4, 4>(
170 1, 0, 0, 0,
171 0, c, -s, 0,
172 0, s, c, 0,
173 0, 0, 0, 1
174 );
175 }
176 else if constexpr(axis == rotation_y) {
177 return mat<genType, 4, 4>(
178 c, 0, s, 0,
179 0, 0, 0, 0,
180 -s, 0, c, 0,
181 0, 0, 0, 1
182 );
183 }
184 else if constexpr(axis == rotation_z) {
185 return mat<genType, 4, 4>(
186 c, -s, 0, 0,
187 s, c, 0, 0,
188 0, 0, 1, 0,
189 0, 0, 0, 1
190 );
191 }
192
193 return mat<genType, 4, 4>();
194}
195
198enum order_
199{
200 order_xyz
201, order_xzy
202, order_yxz
203, order_yzx
204, order_zxy
205, order_zyx
206};
207
213template<typename genType, order_ order = order_zxy>
214constexpr mat<genType, 4, 4> rotation(const vector<genType, 0, 1, 2>& E) {
215 // expanded using a CAS
216
217 // Calculate sin and cos terms
218 const genType ca = fennec::cos(E.x);
219 const genType sa = fennec::sin(E.x);
220 const genType cb = fennec::cos(E.y);
221 const genType sb = fennec::sin(E.y);
222 const genType cg = fennec::cos(E.z);
223 const genType sg = fennec::sin(E.z);
224
225 // Calculate the matrix
226 if constexpr(order == order_xyz) {
227 return mat<genType, 4, 4>(
228 cb*cg, -cg*sg, sb, 0,
229 ca*sg + cg*sa*sb, ca*cg - sa*sb*sg, -ca*sa, 0,
230 sa*sg - ca*cg*sb, ca*sb*sg + cg*sa, ca*cb, 0,
231 0, 0, 0, 1
232 );
233 } else if constexpr(order == order_xzy) {
234 return mat<genType, 4, 4>(
235 cb*cg, -sg, cg*sb, 0,
236 ca*cb*sg + sa*sb, ca*cg, cb*sa*sg - ca*sb, 0,
237 cb*sa*sg - ca*sb, cg*sa, ca*cb + sa*sb*sg, 0,
238 0, 0, 0, 1
239 );
240 } else if constexpr(order == order_yxz) {
241 return mat<genType, 4, 4>(
242 cb*cg + sa*sb*sg, cg*sa*sb - cb*sg, ca*sb, 0,
243 ca*sg, ca*cg, -sa, 0,
244 cb*sa*sg - cg*sb, cb*cg*sa + sb*sg, ca*cb, 0,
245 0, 0, 0, 1
246 );
247 } else if constexpr(order == order_yzx) {
248 return mat<genType, 4, 4>(
249 cb*cg, sa*sb - ca*cb*sg, ca*sb + cb*sa*sg, 0,
250 sg, ca*cg, -cg*sa, 0,
251 -cg*sb, ca*sb*sg + cb*sa, ca*cb - sa*sb*sg, 0,
252 0, 0, 0, 1
253 );
254 } else if constexpr(order == order_zxy) {
255 return mat<genType, 4, 4>(
256 cb*cg - sa*sb*sg, -ca*sg, cb*sa*sg + cg*sb, 0,
257 cb*sg + cg*sa*sb, ca*cg, sb*sg - cb*cg*sa, 0,
258 -ca*sb, sa, ca*cb, 0,
259 0, 0, 0, 1
260 );
261 } else if constexpr(order == order_zyx) {
262 return mat<genType, 4, 4>(
263 cb*cg, cg*sa*sb - ca*sg, ca*cg*sb + sa*sg, 0,
264 cb*sg, ca*cg + sa*sb*sg, ca*sb*sg - cg*sa, 0,
265 -sb, cb*sa, ca*cb, 0,
266 0, 0, 0, 1
267 );
268 }
269
270 return mat<genType, 4, 4>();
271}
272
273}
274
275#endif // FENNEC_MATH_EXT_TRANSFORM_H
Constants
the Matrices
the Trigonometry
constexpr genType sin(genType x)
The standard trigonometric sine.
Definition trigonometric.h:204
constexpr genType cos(genType x)
The Standard Trigonometric Cosine.
Definition trigonometric.h:218