Copperfield Engine 0.1
C++ Game Engine
Loading...
Searching...
No Matches
matrix_4.h
1#ifndef __MATRIX4_H__
2#define __MATRIX4_H__ 1
3
4#include <math.h>
5
6#include "math/matrix_3.h"
7#include "math/vector_3.h"
8#include "math/vector_4.h"
9namespace coma{
11class Mat4 {
12public:
13 Mat4();
14 Mat4(const float a[16]);
15 Mat4(float value);
16 Mat4(const Mat4& copy);
17 Mat4(const Mat4&& move) noexcept;
18 ~Mat4();
21 inline static Mat4 Identity();
25 Mat4 Multiply(const Mat4& other) const;
26
29 float Determinant() const;
32 Mat4 Adjoint() const;
36 bool GetInverse(Mat4* out) const;
39 bool Inverse();
40
43 Mat4 Transpose() const;
44
49 Mat3 getSubMatrix(int r, int c) const;
50
54 static Mat4 Translate(const Vec3& distance);
60 static Mat4 Translate(float x, float y, float z);
61
65 static Mat4 Scale(const Vec3& scale);
71 static Mat4 Scale(float x, float y, float z);
72
76 static Mat4 RotateX(float radians);
80 static Mat4 RotateY(float radians);
84 static Mat4 RotateZ(float radians);
85
91 static Mat4 GetTransform(const Vec3& translate, const Vec3& scale,
92 const Vec3& rotation);
100 static Mat4 GetTransform(const Vec3& translate, const Vec3& scale,
101 float rotateX, float rotateY, float rotateZ);
113 static Mat4 GetTransform(float trans_x, float trans_y, float trans_z,
114 float scale_x, float scale_y, float scale_Z,
115 float rotateX, float rotateY, float rotateZ);
116
121 static Mat4 LookAtZeroCheck(const Vec3& position, const Vec3& target) {
122 Vec3 direction = (target - position).Normalized();
123 if(direction == Vec3::up) {
124 return LookAt(position, target, Vec3::back);
125 }
126 if(direction == Vec3::down) {
127 return LookAt(position, target, Vec3::forward);
128 }
129 return LookAt(position, target);
130 }
131
137 static Mat4 LookAt(const Vec3& position, const Vec3& target,
138 const Vec3& upDir = Vec3::up) {
139 Vec3 direction = (target - position).Normalized();
140 Vec3 right = Vec3::CrossProduct(direction, upDir).Normalized();
141 Vec3 up = Vec3::CrossProduct(right, direction);
142
143 Mat4 res = Identity();
144 res.m[0] = right.x;
145 res.m[4] = right.y;
146 res.m[8] = right.z;
147 res.m[1] = up.x;
148 res.m[5] = up.y;
149 res.m[9] = up.z;
150 res.m[2] = -direction.x;
151 res.m[6] = -direction.y;
152 res.m[10] = -direction.z;
153 res.m[12] = -Vec3::DotProduct(right, position);
154 res.m[13] = -Vec3::DotProduct(up, position);
155 res.m[14] = Vec3::DotProduct(direction, position);
156
157 return res;
158 }
165 static Mat4 PerspectiveMatrix(float fov, float aspect, float near, float far);
174 static Mat4 OrthoMatrix(float right, float left, float top, float bottom,
175 float near, float far);
179 Vec4 Transform(const Vec4& v);
180
183 Mat4 Projection() const;
187 Vec3 TransformVec3(Vec3* vector);
188
189
193 Vec4 GetColum(int colum) const;
197 Vec4 GetLine(int line) const;
198
199 Mat4 operator+(const Mat4& other) const;
200 Mat4& operator+=(const Mat4& other);
201 Mat4 operator+(float value) const;
202 Mat4& operator+=(float value);
203 Mat4 operator-(const Mat4& other) const;
204 Mat4& operator-=(const Mat4& other);
205 Mat4 operator-(float value) const;
206 Mat4& operator-=(float value);
207 Mat4& operator*=(float value);
208 Mat4 operator*(float value) const;
209 Mat4& operator*=(Mat4 value);
210 Mat4 operator*(Mat4 value) const;
211 Mat4& operator/=(float value);
212 Mat4 operator/(float value) const;
213 bool operator==(const Mat4& other);
214 bool operator!=(const Mat4& other);
215 Mat4& operator=(const Mat4& other);
216 Mat4& operator=(Mat4&& other) noexcept;
217
218 float m[16];
219};
220
221// Author: Alan Gutierrez Ramirez
222inline Mat4 Mat4::Projection() const {
223 float s[16] = {1.0f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,0.0f,
224 0.0f,0.0f,1.0f,1.0f,0.0f,0.0f,0.0f,0.0f};
225 return Mat4(s);
226}
227// Author: Alan Gutierrez Ramirez
229 float w = (this->m[3] * vector->x) + (this->m[7] * vector->y) +
230 (this->m[11] * vector->z) + this->m[15];
231 float s[3]{
232 ((this->m[0] * vector->x) + (this->m[4] * vector->y) +
233 (this->m[8] * vector->z) + this->m[12]) /
234 w,
235 ((this->m[1] * vector->x) + (this->m[5] * vector->y) +
236 (this->m[9] * vector->z) + this->m[13]) /
237 w,
238 ((this->m[2] * vector->z) + (this->m[6] * vector->z) +
239 (this->m[10] * vector->z) + this->m[14]) /
240 w,
241 };
242 return Vec3(s);
243}
244
245inline Vec4 Mat4::Transform(const Vec4& v) {
246 float res[4];
247 for (int i = 0; i < 4; i++) {
248 res[i] = m[i + 0 * 4] * v.x + m[i + 1 * 4] * v.y + m[i + 2 * 4] * v.z +
249 m[i + 3 * 4] * v.w;
250 }
251 return Vec4(res);
252}
253
255 float s[16] = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
256 return Mat4(s);
257}
258
259inline Mat4 Mat4::Multiply(const Mat4& other) const {
260 Mat4 res;
261 for (int row = 0; row < 4; row++) {
262 for (int col = 0; col < 4; col++) {
263 res.m[row * 4 + col] = m[row * 4 + 0] * other.m[0 * 4 + col] +
264 m[row * 4 + 1] * other.m[1 * 4 + col] +
265 m[row * 4 + 2] * other.m[2 * 4 + col] +
266 m[row * 4 + 3] * other.m[3 * 4 + col];
267 }
268 }
269 return res;
270}
271
272inline float Mat4::Determinant() const {
273 return Mat3(Vec3(m[5], m[6], m[7]), Vec3(m[9], m[10], m[11]),
274 Vec3(m[13], m[14], m[15]))
275 .Determinant() *
276 m[0] +
277 Mat3(Vec3(m[1], m[2], m[3]), Vec3(m[9], m[10], m[11]),
278 Vec3(m[13], m[14], m[15]))
279 .Determinant() *
280 -m[4] +
281 Mat3(Vec3(m[1], m[2], m[3]), Vec3(m[5], m[6], m[7]),
282 Vec3(m[13], m[14], m[15]))
283 .Determinant() *
284 m[8] +
285 Mat3(Vec3(m[1], m[2], m[3]), Vec3(m[5], m[6], m[7]),
286 Vec3(m[9], m[10], m[11]))
287 .Determinant() *
288 -m[12];
289}
290
291inline Mat3 Mat4::getSubMatrix(int r, int c) const {
292 float s[9];
293 int k = 0;
294 for (int i = 0; i < 4; i++) {
295 for (int j = 0; j < 4; j++) {
296 if (r != i && c != j) {
297 s[k] = this->m[i * 4 + j];
298 k++;
299 }
300 }
301 }
302 return Mat3(s);
303}
304
305inline Mat4 Mat4::Adjoint() const {
306 float s[16] = {
307 this->getSubMatrix(0, 0).Determinant(),
308 -this->getSubMatrix(0, 1).Determinant(),
309 this->getSubMatrix(0, 2).Determinant(),
310 -this->getSubMatrix(0, 3).Determinant(),
311
312 -this->getSubMatrix(1, 0).Determinant(),
313 this->getSubMatrix(1, 1).Determinant(),
314 -this->getSubMatrix(1, 2).Determinant(),
315 this->getSubMatrix(1, 3).Determinant(),
316
317 this->getSubMatrix(2, 0).Determinant(),
318 -this->getSubMatrix(2, 1).Determinant(),
319 this->getSubMatrix(2, 2).Determinant(),
320 -this->getSubMatrix(2, 3).Determinant(),
321
322 -this->getSubMatrix(3, 0).Determinant(),
323 this->getSubMatrix(3, 1).Determinant(),
324 -this->getSubMatrix(3, 2).Determinant(),
325 this->getSubMatrix(3, 3).Determinant(),
326 };
327 return Mat4(s).Transpose();
328}
329
330inline bool Mat4::Inverse() {
331 float det = this->Determinant();
332 if (det == 0) return false;
333 operator=(this->Adjoint() / det);
334 return true;
335}
336
337inline bool Mat4::GetInverse(Mat4* out) const {
338 float det = this->Determinant();
339 if (det == 0) return false;
340 *out = (this->Adjoint() / det);
341 return true;
342}
343
344inline Mat4 Mat4::Transpose() const {
345 float f[16] = {
346 m[0],m[4],m[8],m[12],m[1],m[5],m[9],m[13],
347 m[2],m[6],m[10],m[14],m[3],m[7],m[11],m[15],
348 };
349 return Mat4(f);
350}
351
352inline Mat4 Mat4::Translate(const Vec3& distance) {
353 float f[16] = {
354 1,0,0,0,0,1,0,0,0,0,1,0,distance.x,distance.y,distance.z,1,
355 };
356 return Mat4(f);
357}
358
359inline Mat4 Mat4::Translate(float x, float y, float z) {
360 float f[16] = {
361 1,0,0,0,0,1,0,0,0,0,1,0,x,y,z,1,
362 };
363 return Mat4(f);
364}
365
366inline Mat4 Mat4::Scale(const Vec3& scale) {
367 float f[16] = {
368 scale.x,0,0,0,0,scale.y,0,0,0,0,scale.z,0,0,0,0,1,
369 };
370 return Mat4(f);
371}
372
373inline Mat4 Mat4::Scale(float x, float y, float z) {
374 float f[16] = {
375 x,0,0,0,0,y,0,0,0,0,z,0,0,0,0,1,
376 };
377 return Mat4(f);
378}
379
380inline Mat4 Mat4::RotateX(float radians) {
381 float f[16] = {
382 1,
383 0,
384 0,
385 0,
386 0,
387 cosf(radians),
388 -sinf(radians),
389 0,
390 0,
391 sinf(radians),
392 cosf(radians),
393 0,
394 0,
395 0,
396 0,
397 1,
398 };
399 return Mat4(f);
400}
401
402inline Mat4 Mat4::RotateY(float radians) {
403 float f[16] = {
404 cosf(radians),0,sinf(radians),0,0,1,0,0,
405 -sinf(radians),0,cosf(radians),0,0,0,0,1,
406 };
407 return Mat4(f);
408}
409
410inline Mat4 Mat4::RotateZ(float radians) {
411 float f[16] = {
412 cosf(radians),
413 -sinf(radians),
414 0,
415 0,
416 sinf(radians),
417 cosf(radians),
418 0,
419 0,
420 0,
421 0,
422 1,
423 0,
424 0,
425 0,
426 0,
427 1,
428 };
429 return Mat4(f);
430}
431
432inline Mat4 Mat4::GetTransform(const Vec3& translate, const Vec3& scale,
433 const Vec3& rotation) {
434 return Scale(scale)
435 .Multiply(RotateX(rotation.x)
436 .Multiply(RotateY(rotation.y))
437 .Multiply(RotateZ(rotation.z)))
438 .Multiply(Translate(translate));
439}
440inline Mat4 Mat4::GetTransform(const Vec3& translate, const Vec3& scale,
441 float rotateX, float rotateY, float rotateZ) {
442 return Scale(scale)
443 .Multiply(RotateX(rotateX)
444 .Multiply(RotateY(rotateY))
445 .Multiply(RotateZ(rotateZ)))
446 .Multiply(Translate(translate));
447}
448
449inline Mat4 Mat4::GetTransform(float trans_x, float trans_y, float trans_z,
450 float scale_x, float scale_y, float scale_z,
451 float rotateX, float rotateY, float rotateZ) {
452 return Scale(scale_x, scale_y, scale_z)
453 .Multiply(RotateX(rotateX)
454 .Multiply(RotateY(rotateY))
455 .Multiply(RotateZ(rotateZ)))
456 .Multiply(Translate(trans_x, trans_y, trans_z));
457}
458
459inline Vec4 Mat4::GetColum(int colum) const {
460 return Vec4(m[0 + colum], m[4 + colum], m[8 + colum], m[12 + colum]);
461}
462
463inline Vec4 Mat4::GetLine(int line) const {
464 return Vec4(m[line * 4 + 0], m[line * 4 + 1], m[line * 4 + 2],
465 m[line * 4 + 3]);
466}
467
468inline Mat4 Mat4::PerspectiveMatrix(float fov, float aspect, float near,
469 float far) {
470 float const tan_half_fov = tanf(fov * 0.5f);
471 Mat4 result = Mat4();
472 result.m[0] = 1.0f / (aspect * tan_half_fov);
473 result.m[5] = 1.0f / tan_half_fov;
474 result.m[10] = -(far + near) / (far - near);
475 result.m[11] = -1.0f;
476 result.m[14] = -(2.0f * far * near) / (far - near);
477 return result;
478}
479
480inline Mat4 Mat4::OrthoMatrix(float right, float left, float top,
481 float bottom, float near, float far) {
482 Mat4 result = Mat4();
483 result.m[0] = -2.0f / (right - left);
484 result.m[5] = -2.0f / (top - bottom);
485 result.m[10] = -2.0f / (far - near);
486 result.m[12] = (right + left) / (right - left);
487 result.m[13] = (top + bottom) / (top - bottom);
488 result.m[14] = -(far + near) / (far - near);
489 result.m[15] = 1.0f;
490 return result;
491}
492
493inline Mat4 Mat4::operator+(const Mat4& other) const {
494 Mat4 res;
495 for (int i = 0; i < 16; i++) {
496 res.m[i] = m[i] + other.m[i];
497 }
498 return res;
499}
500
501inline Mat4& Mat4::operator+=(const Mat4& other) {
502 for (int i = 0; i < 16; i++) {
503 m[i] += other.m[i];
504 }
505 return *this;
506}
507
508inline Mat4 Mat4::operator+(float value) const {
509 Mat4 res;
510 for (int i = 0; i < 16; i++) {
511 res.m[i] = m[i] + value;
512 }
513 return res;
514}
515
516inline Mat4& Mat4::operator+=(float value) {
517 for (int i = 0; i < 16; i++) {
518 m[i] += value;
519 }
520 return *this;
521}
522
523inline Mat4 Mat4::operator-(const Mat4& other) const {
524 Mat4 res;
525 for (int i = 0; i < 16; i++) {
526 res.m[i] = m[i] - other.m[i];
527 }
528 return res;
529}
530
531inline Mat4& Mat4::operator-=(const Mat4& other) {
532 for (int i = 0; i < 16; i++) {
533 m[i] -= other.m[i];
534 }
535 return *this;
536}
537
538inline Mat4 Mat4::operator-(float value) const {
539 Mat4 res;
540 for (int i = 0; i < 16; i++) {
541 res.m[i] = m[i] - value;
542 }
543 return res;
544}
545
546inline Mat4& Mat4::operator-=(float value) {
547 for (int i = 0; i < 16; i++) {
548 m[i] -= value;
549 }
550 return *this;
551}
552
553inline Mat4& Mat4::operator*=(float value) {
554 for (int i = 0; i < 16; i++) {
555 m[i] *= value;
556 }
557 return *this;
558}
559
560inline Mat4 Mat4::operator*(float value) const {
561 Mat4 res;
562 for (int i = 0; i < 16; i++) {
563 res.m[i] = m[i] * value;
564 }
565 return res;
566}
567
568inline Mat4& Mat4::operator*=(Mat4 value) {
569 for (int row = 0; row < 4; row++) {
570 for (int col = 0; col < 4; col++) {
571 m[row * 4 + col] = m[row * 4 + 0] * value.m[0 * 4 + col] +
572 m[row * 4 + 1] * value.m[1 * 4 + col] +
573 m[row * 4 + 2] * value.m[2 * 4 + col] +
574 m[row * 4 + 3] * value.m[3 * 4 + col];
575 }
576 }
577 return *this;
578}
579inline Mat4 Mat4::operator*(Mat4 value) const {
580 Mat4 res;
581 for (int row = 0; row < 4; row++) {
582 for (int col = 0; col < 4; col++) {
583 res.m[row * 4 + col] = value.m[row * 4 + 0] * m[0 * 4 + col] +
584 value.m[row * 4 + 1] * m[1 * 4 + col] +
585 value.m[row * 4 + 2] * m[2 * 4 + col] +
586 value.m[row * 4 + 3] * m[3 * 4 + col];
587 }
588 }
589 return res;
590}
591
592inline Mat4& Mat4::operator/=(float value) {
593 for (int i = 0; i < 16; i++) {
594 m[i] /= value;
595 }
596 return *this;
597}
598
599inline Mat4 Mat4::operator/(float value) const {
600 Mat4 res;
601 for (int i = 0; i < 16; i++) {
602 res.m[i] = m[i] / value;
603 }
604 return res;
605}
606
607inline bool Mat4::operator==(const Mat4& other) {
608 for (int i = 0; i < 16; i++) {
609 if (m[i] != other.m[i]) return false;
610 }
611 return true;
612}
613
614inline bool Mat4::operator!=(const Mat4& other) {
615 for (int i = 0; i < 16; i++) {
616 if (m[i] != other.m[i]) return true;
617 }
618 return false;
619}
620
621inline Mat4& Mat4::operator=(const Mat4& other) {
622 for (int i = 0; i < 16; i++) {
623 m[i] = other.m[i];
624 }
625 return *this;
626}
627
628inline Mat4& Mat4::operator=(Mat4&& other) noexcept {
629 for (int i = 0; i < 16; i++) {
630 m[i] = other.m[i];
631 }
632 return *this;
633}
634} // namespace coma
635#endif
represents mathematical matrix with 3 cols and 3 rows
Definition: matrix_3.h:18
float Determinant() const
Definition: matrix_3.h:211
represents mathematical matrix with 4 cols and 4 rows
Definition: matrix_4.h:11
static Mat4 LookAtZeroCheck(const Vec3 &position, const Vec3 &target)
Like LoockAt but checking that no divisions by 0 are made.
Definition: matrix_4.h:121
bool GetInverse(Mat4 *out) const
Definition: matrix_4.h:337
static Mat4 PerspectiveMatrix(float fov, float aspect, float near, float far)
Definition: matrix_4.h:468
Mat4 Transpose() const
Definition: matrix_4.h:344
Mat3 getSubMatrix(int r, int c) const
Definition: matrix_4.h:291
bool Inverse()
Definition: matrix_4.h:330
Vec4 GetColum(int colum) const
Definition: matrix_4.h:459
float Determinant() const
Definition: matrix_4.h:272
Mat4 Multiply(const Mat4 &other) const
Definition: matrix_4.h:259
Vec4 Transform(const Vec4 &v)
Definition: matrix_4.h:245
static Mat4 GetTransform(const Vec3 &translate, const Vec3 &scale, const Vec3 &rotation)
Definition: matrix_4.h:432
static Mat4 RotateY(float radians)
Definition: matrix_4.h:402
Mat4 Adjoint() const
Definition: matrix_4.h:305
static Mat4 Scale(const Vec3 &scale)
Definition: matrix_4.h:366
Mat4 Projection() const
Definition: matrix_4.h:222
Vec4 GetLine(int line) const
Definition: matrix_4.h:463
static Mat4 LookAt(const Vec3 &position, const Vec3 &target, const Vec3 &upDir=Vec3::up)
Calculate the view matrix based on the position and a target.
Definition: matrix_4.h:137
static Mat4 Identity()
Definition: matrix_4.h:254
Vec3 TransformVec3(Vec3 *vector)
Definition: matrix_4.h:228
static Mat4 RotateX(float radians)
Definition: matrix_4.h:380
static Mat4 OrthoMatrix(float right, float left, float top, float bottom, float near, float far)
Definition: matrix_4.h:480
static Mat4 Translate(const Vec3 &distance)
Definition: matrix_4.h:352
static Mat4 RotateZ(float radians)
Definition: matrix_4.h:410
represents mathematical vector with 3 components
Definition: vector_3.h:12
static const Vec3 up
Vec3(0, 1, 0)
Definition: vector_3.h:117
static const Vec3 down
Vec3(0, -1, 0)
Definition: vector_3.h:119
static const Vec3 back
Vec3(0, 0, -1)
Definition: vector_3.h:127
static Vec3 CrossProduct(const Vec3 &a, const Vec3 &b)
Definition: vector_3.h:155
static float DotProduct(const Vec3 &a, const Vec3 &b)
Definition: vector_3.h:147
static const Vec3 forward
Vec3(0, 0, 1)
Definition: vector_3.h:125
Vec3 Normalized() const
Definition: vector_3.h:145
represents mathematical vector with 4 components
Definition: vector_4.h:8
copperdielf Math Library
Definition: buffer.hpp:5