diff options
author | vimene <vincent.menegaux@gmail.com> | 2024-12-31 03:40:14 +0100 |
---|---|---|
committer | vimene <vincent.menegaux@gmail.com> | 2024-12-31 03:40:14 +0100 |
commit | cc6fb8c33637566a7b116d46440e6063f016deea (patch) | |
tree | 5cc83f84525507994add57df7dd974e6611d675a /src/math | |
parent | 6b765a85cf81bf4b7162e4c9280dd4054581c611 (diff) | |
download | engine-cc6fb8c33637566a7b116d46440e6063f016deea.tar.gz |
various improvements
- added quaternions and rewrote all rotations to use them
- added transforms to put all object transforms in a single place
- added Wavefront .obj file parser
- removed frame buffer's abstract class
- improved vectors, matrices, triangles, vertices and vertices data by putting all code in header file
- added vector's operations
- changed from NULL to nullptr
- miscellaneous improvements
Diffstat (limited to 'src/math')
-rw-r--r-- | src/math/mat4.cpp | 149 | ||||
-rw-r--r-- | src/math/mat4.h | 166 | ||||
-rw-r--r-- | src/math/quat.h | 74 | ||||
-rw-r--r-- | src/math/tform.h | 35 | ||||
-rw-r--r-- | src/math/vector.cpp | 175 | ||||
-rw-r--r-- | src/math/vector.h | 266 |
6 files changed, 462 insertions, 403 deletions
diff --git a/src/math/mat4.cpp b/src/math/mat4.cpp deleted file mode 100644 index b9dff15..0000000 --- a/src/math/mat4.cpp +++ /dev/null @@ -1,149 +0,0 @@ -#include "math/mat4.h" -#include <array> -#include <cmath> -#include "math/vector.h" - -using namespace engine::math; - -Matrix4 Matrix4::idty() { - return { - 1.f, 0.f, 0.f, 0.f, - 0.f, 1.f, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f, - }; -} - -Matrix4 Matrix4::translate(Vector3 v) { - return { - 1.f, 0.f, 0.f, v.x, - 0.f, 1.f, 0.f, v.y, - 0.f, 0.f, 1.f, v.z, - 0.f, 0.f, 0.f, 1.f, - }; -} - -Matrix4 Matrix4::scale(float fac) { - return { - fac, 0.f, 0.f, 0.f, - 0.f, fac, 0.f, 0.f, - 0.f, 0.f, fac, 0.f, - 0.f, 0.f, 0.f, 1.f, - }; -} - -Matrix4 Matrix4::scale(Vector3 facs) { - return { - facs.x, 0.f, 0.f, 0.f, - 0.f, facs.y, 0.f, 0.f, - 0.f, 0.f, facs.z, 0.f, - 0.f, 0.f, 0.f, 1.f, - }; -} - -Matrix4 Matrix4::rot_x(float a) { - float c = std::cos(a); - float s = std::sin(a); - return { - 1.f, 0.f, 0.f, 0.f, - 0.f, c, -s, 0.f, - 0.f, s, c, 0.f, - 0.f, 0.f, 0.f, 1.f, - }; -} - -Matrix4 Matrix4::rot_y(float a) { - float c = std::cos(a); - float s = std::sin(a); - return { - c, 0.f, s, 0.f, - 0.f, 1.f, 0.f, 0.f, - -s, 0.f, c, 0.f, - 0.f, 0.f, 0.f, 1.f, - }; -} - -Matrix4 Matrix4::rot_z(float a) { - float c = std::cos(a); - float s = std::sin(a); - return { - c, -s, 0.f, 0.f, - s, c, 0.f, 0.f, - 0.f, 0.f, 1.f, 0.f, - 0.f, 0.f, 0.f, 1.f, - }; -} - -Matrix4 Matrix4::projection(float aspect_ratio, float min_z, float max_z) { - return {{ - aspect_ratio, 0.f, 0.f, 0.f, - 0.f, -1.f, 0.f, 0.f, - 0.f, 0.f, -2.f / (max_z - min_z), -(max_z + min_z) / (max_z - min_z), - 0.f, 0.f, -1.f, 0.f, - }}; -} - -Matrix4 Matrix4::operator+() const { - return *this; -} - -Matrix4 Matrix4::operator-() const { - return { - -values[ 0], -values[ 1], -values[ 2], -values[ 3], - -values[ 4], -values[ 5], -values[ 6], -values[ 7], - -values[ 8], -values[ 9], -values[10], -values[11], - -values[12], -values[13], -values[14], -values[15], - }; -} - -Matrix4 Matrix4::operator+(Matrix4 m) const { - return { - values[ 0] + m.values[ 0], values[ 1] + m.values[ 1], values[ 2] + m.values[ 2], values[ 3] + m.values[ 3], - values[ 4] + m.values[ 4], values[ 5] + m.values[ 5], values[ 6] + m.values[ 6], values[ 7] + m.values[ 7], - values[ 8] + m.values[ 8], values[ 9] + m.values[ 9], values[10] + m.values[10], values[11] + m.values[11], - values[12] + m.values[12], values[13] + m.values[13], values[14] + m.values[14], values[15] + m.values[15], - }; -} - -Matrix4 Matrix4::operator-(Matrix4 m) const { - return *this + (-m); -} - -Matrix4 Matrix4::operator*(Matrix4 m) const { - Matrix4 ret; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - ret.values[i * 4 + j] = 0.f; - for (int k = 0; k < 4; k++) - ret.values[i * 4 + j] += values[i * 4 + k] * m.values[k * 4 + j]; - } - } - return ret; -} - -Vector4 Matrix4::operator*(Vector4 v) const { - return { - values[ 0] * v.x + values[ 1] * v.y + values[ 2] * v.z + values[ 3] * v.w, - values[ 4] * v.x + values[ 5] * v.y + values[ 6] * v.z + values[ 7] * v.w, - values[ 8] * v.x + values[ 9] * v.y + values[10] * v.z + values[11] * v.w, - values[12] * v.x + values[13] * v.y + values[14] * v.z + values[15] * v.w, - }; -} - -std::array<Vector4, 4> Matrix4::to_vecs() const { - return {{ - { values[ 0], values[ 4], values[ 8], values[12] }, - { values[ 1], values[ 5], values[ 9], values[13] }, - { values[ 2], values[ 6], values[10], values[14] }, - { values[ 3], values[ 7], values[11], values[15] }, - }}; -} - -Matrix4 engine::math::operator*(float fac, Matrix4 m) { - return { - fac * m.values[ 0], fac * m.values[ 1], fac * m.values[ 2], fac * m.values[ 3], - fac * m.values[ 4], fac * m.values[ 5], fac * m.values[ 6], fac * m.values[ 7], - fac * m.values[ 8], fac * m.values[ 9], fac * m.values[10], fac * m.values[11], - fac * m.values[12], fac * m.values[13], fac * m.values[14], fac * m.values[15], - }; -} diff --git a/src/math/mat4.h b/src/math/mat4.h index 35b1ad2..adb2059 100644 --- a/src/math/mat4.h +++ b/src/math/mat4.h @@ -2,33 +2,157 @@ #define MATH_MAT4_H #include <array> +#include <cmath> #include "math/vector.h" namespace engine::math { -class Matrix4 { - public: - static Matrix4 idty(); - static Matrix4 translate(Vector3 v); - static Matrix4 scale(float fac); - static Matrix4 scale(Vector3 facs); - static Matrix4 rot_x(float a); - static Matrix4 rot_y(float a); - static Matrix4 rot_z(float a); - static Matrix4 projection(float aspect_ratio, float min_z, float max_z); - - std::array<float, 16> values; - - Matrix4 operator+() const; - Matrix4 operator-() const; - Matrix4 operator+(Matrix4 m) const; - Matrix4 operator-(Matrix4 m) const; - Matrix4 operator*(Matrix4 m) const; - Vector4 operator*(Vector4 v) const; - std::array<Vector4, 4> to_vecs() const; +struct Matrix4 { + static constexpr Matrix4 idty() { + return { + 1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f, + }; + } + + static constexpr Matrix4 translate(const Vector3& v) { + return { + 1.f, 0.f, 0.f, v.x, + 0.f, 1.f, 0.f, v.y, + 0.f, 0.f, 1.f, v.z, + 0.f, 0.f, 0.f, 1.f, + }; + } + + static constexpr Matrix4 scale(float fac) { + return { + fac, 0.f, 0.f, 0.f, + 0.f, fac, 0.f, 0.f, + 0.f, 0.f, fac, 0.f, + 0.f, 0.f, 0.f, 1.f, + }; + } + + static constexpr Matrix4 scale(const Vector3& facs) { + return { + facs.x, 0.f, 0.f, 0.f, + 0.f, facs.y, 0.f, 0.f, + 0.f, 0.f, facs.z, 0.f, + 0.f, 0.f, 0.f, 1.f, + }; + } + + static constexpr Matrix4 rot_x(float a) { + float c = std::cos(a); + float s = std::sin(a); + return { + 1.f, 0.f, 0.f, 0.f, + 0.f, c, -s, 0.f, + 0.f, s, c, 0.f, + 0.f, 0.f, 0.f, 1.f, + }; + } + + static constexpr Matrix4 rot_y(float a) { + float c = std::cos(a); + float s = std::sin(a); + return { + c, 0.f, s, 0.f, + 0.f, 1.f, 0.f, 0.f, + -s, 0.f, c, 0.f, + 0.f, 0.f, 0.f, 1.f, + }; + } + + static constexpr Matrix4 rot_z(float a) { + float c = std::cos(a); + float s = std::sin(a); + return { + c, -s, 0.f, 0.f, + s, c, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f, + }; + } + + static constexpr Matrix4 projection(float aspect_ratio, float min_z, float max_z) { + return {{ + aspect_ratio, 0.f, 0.f, 0.f, + 0.f, -1.f, 0.f, 0.f, + 0.f, 0.f, -2.f / (max_z - min_z), -(max_z + min_z) / (max_z - min_z), + 0.f, 0.f, -1.f, 0.f, + }}; + } + + std::array<float, 4 * 4> values; + + constexpr Matrix4 operator+() const & { + return *this; + } + + constexpr Matrix4 operator-() const & { + return { + -values[ 0], -values[ 1], -values[ 2], -values[ 3], + -values[ 4], -values[ 5], -values[ 6], -values[ 7], + -values[ 8], -values[ 9], -values[10], -values[11], + -values[12], -values[13], -values[14], -values[15], + }; + } + + constexpr Matrix4 operator+(const Matrix4& m) const & { + return { + values[ 0] + m.values[ 0], values[ 1] + m.values[ 1], values[ 2] + m.values[ 2], values[ 3] + m.values[ 3], + values[ 4] + m.values[ 4], values[ 5] + m.values[ 5], values[ 6] + m.values[ 6], values[ 7] + m.values[ 7], + values[ 8] + m.values[ 8], values[ 9] + m.values[ 9], values[10] + m.values[10], values[11] + m.values[11], + values[12] + m.values[12], values[13] + m.values[13], values[14] + m.values[14], values[15] + m.values[15], + }; + } + + constexpr Matrix4 operator-(const Matrix4& m) const & { + return *this + (-m); + } + + constexpr Matrix4 operator*(const Matrix4& m) const & { + Matrix4 ret; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + ret.values[i * 4 + j] = 0.f; + for (int k = 0; k < 4; k++) + ret.values[i * 4 + j] += values[i * 4 + k] * m.values[k * 4 + j]; + } + } + return ret; + } + + constexpr Vector4 operator*(const Vector4& v) const & { + return { + values[ 0] * v.x + values[ 1] * v.y + values[ 2] * v.z + values[ 3] * v.w, + values[ 4] * v.x + values[ 5] * v.y + values[ 6] * v.z + values[ 7] * v.w, + values[ 8] * v.x + values[ 9] * v.y + values[10] * v.z + values[11] * v.w, + values[12] * v.x + values[13] * v.y + values[14] * v.z + values[15] * v.w, + }; + } + + constexpr std::array<Vector4, 4> to_vecs() const & { + return {{ + { values[ 0], values[ 4], values[ 8], values[12] }, + { values[ 1], values[ 5], values[ 9], values[13] }, + { values[ 2], values[ 6], values[10], values[14] }, + { values[ 3], values[ 7], values[11], values[15] }, + }}; + } }; -Matrix4 operator*(float fac, Matrix4 m); +constexpr Matrix4 operator*(float fac, const Matrix4& m) { + return { + fac * m.values[ 0], fac * m.values[ 1], fac * m.values[ 2], fac * m.values[ 3], + fac * m.values[ 4], fac * m.values[ 5], fac * m.values[ 6], fac * m.values[ 7], + fac * m.values[ 8], fac * m.values[ 9], fac * m.values[10], fac * m.values[11], + fac * m.values[12], fac * m.values[13], fac * m.values[14], fac * m.values[15], + }; +} } diff --git a/src/math/quat.h b/src/math/quat.h new file mode 100644 index 0000000..763253b --- /dev/null +++ b/src/math/quat.h @@ -0,0 +1,74 @@ +#ifndef MATH_QUAT_H +#define MATH_QUAT_H + +#include <cmath> + +namespace engine::math { + +struct Quaternion { + static constexpr Quaternion zero() { + return {0.f, 0.f, 0.f, 0.f}; + } + + static constexpr Quaternion one() { + return {1.f, 0.f, 0.f, 0.f}; + } + + static constexpr Quaternion euler_zyx(float a, float b, float c) { + float ca = std::cos(a / 2.f), sa = std::sin(a / 2.f), + cb = std::cos(b / 2.f), sb = std::sin(b / 2.f), + cc = std::cos(c / 2.f), sc = std::sin(c / 2.f); + return { + ca * cb * cc - sa * sb * sc, + sa * cb * cc + ca * sb * sc, + ca * sb * cc - sa * cb * sc, + ca * cb * sc + sa * sb * cc, + }; + } + + float w, x, y, z; + + constexpr Quaternion() {} + constexpr Quaternion(float w, float x, float y, float z) : w{w}, x{x}, y{y}, z{z} {} + + constexpr bool operator==(const Quaternion& other) const & { + return w == other.w && x == other.x && y == other.y && z == other.z; + } + + constexpr bool operator!=(const Quaternion& other) const & { + return !(*this == other); + } + + constexpr Quaternion operator+() const & { + return *this; + } + + constexpr Quaternion operator-() const & { + return { -w, -x, -y, -z }; + } + + constexpr Quaternion operator+(const Quaternion& other) const & { + return { w + other.w, x + other.x, y + other.y, z + other.z }; + } + + constexpr Quaternion operator-(const Quaternion& other) const & { + return *this + (-other); + } + + constexpr Quaternion operator*(const Quaternion& other) const & { + return { + w * other.w - x * other.x - y * other.y - z * other.z, + w * other.x + x * other.w + y * other.z - z * other.y, + w * other.y + y * other.w + z * other.x - x * other.z, + w * other.z + z * other.w + x * other.y - y * other.x, + }; + } + + constexpr Quaternion conjugate() const & { + return {w, -x, -y, -z}; + } +}; + +} + +#endif // MATH_QUAT_H diff --git a/src/math/tform.h b/src/math/tform.h new file mode 100644 index 0000000..2d61494 --- /dev/null +++ b/src/math/tform.h @@ -0,0 +1,35 @@ +#ifndef MATH_TFORM_H +#define MATH_TFORM_H + +#include "math/vector.h" +#include "math/mat4.h" +#include "math/quat.h" + +namespace engine::math { + +class Transform { + public: + Vector3 loc; + Quaternion rot; + Vector3 scale; + + constexpr Transform(Vector3 loc, Quaternion rot, Vector3 scale) : loc{loc}, rot{rot}, scale{scale} { + } + + constexpr Transform opposite() const & { + return {-loc, rot.conjugate(), 1.f / scale}; + } + + constexpr Matrix4 to_mat4() const & { + return { + scale.x * (2.f * (rot.w * rot.w + rot.x * rot.x) - 1.f), scale.y * (2.f * (rot.x * rot.y - rot.w * rot.z) ), scale.z * (2.f * (rot.x * rot.z + rot.w * rot.y) ), loc.x, + scale.x * (2.f * (rot.x * rot.y + rot.w * rot.z) ), scale.y * (2.f * (rot.w * rot.w + rot.y * rot.y) - 1.f), scale.z * (2.f * (rot.y * rot.z - rot.w * rot.x) ), loc.y, + scale.x * (2.f * (rot.x * rot.z - rot.w * rot.y) ), scale.y * (2.f * (rot.y * rot.z + rot.w * rot.x) ), scale.z * (2.f * (rot.w * rot.w + rot.z * rot.z) - 1.f), loc.z, + 0.f, 0.f, 0.f, 1.f, + }; + } +}; + +} + +#endif // MATH_TFORM_H diff --git a/src/math/vector.cpp b/src/math/vector.cpp deleted file mode 100644 index 306fc3d..0000000 --- a/src/math/vector.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include "math/vector.h" -#include <cmath> - -using namespace engine::math; - -Vector2::Vector2() { -} - -Vector2::Vector2(float x, float y) : x{x}, y{y} { -} - -bool Vector2::operator==(Vector2 other) const { - return x == other.x && y == other.y; -} - -bool Vector2::operator!=(Vector2 other) const { - return !(*this == other); -} - -Vector2 Vector2::operator+() const { - return *this; -} - -Vector2 Vector2::operator-() const { - return { -x, -y }; -} - -Vector2 Vector2::operator+(Vector2 other) const { - return { x + other.x, y + other.y }; -} - -Vector2 Vector2::operator-(Vector2 other) const { - return *this + (-other); -} - -float Vector2::det(Vector2 other) const { - return this->x * other.y - other.x * this->y; -} - -Vector2 Vector2::round() const { - return { std::round(x), std::round(y) }; -} - -Vector2 engine::math::operator*(float n, Vector2 other) { - return { n * other.x, n * other.y }; -} - -Vector2 engine::math::operator*(Vector2 other, float n) { - return n * other; -} - -Vector2 engine::math::operator/(Vector2 other, float n) { - return { other.x / n, other.y / n }; -} - -Vector3::Vector3() { -} - -Vector3::Vector3(float x, float y, float z) : x{x}, y{y}, z{z} { -} - -bool Vector3::operator==(Vector3 other) const { - return x == other.x && y == other.y && z == other.z; -} - -bool Vector3::operator!=(Vector3 other) const { - return !(*this == other); -} - -Vector3 Vector3::operator+() const { - return *this; -} - -Vector3 Vector3::operator-() const { - return { -x, -y, -z }; -} - -Vector3 Vector3::operator+(Vector3 other) const { - return { x + other.x, y + other.y, z + other.z }; -} - -Vector3 Vector3::operator-(Vector3 other) const { - return *this + (-other); -} - -Vector3 Vector3::round() const { - return { std::round(x), std::round(y), std::round(z) }; -} - -Vector3 Vector3::cross(Vector3 other) const { - return { - y * other.z - z * other.y, - z * other.x - x * other.z, - x * other.y - y * other.x - }; -} - -Vector3 engine::math::operator*(float n, Vector3 other) { - return { n * other.x, n * other.y, n * other.z }; -} - -Vector3 engine::math::operator*(Vector3 other, float n) { - return n * other; -} - -Vector3 engine::math::operator/(Vector3 other, float n) { - return { other.x / n, other.y / n, other.z / n }; -} - -Vector4::Vector4() { -} - -Vector4::Vector4(float x, float y, float z, float w) : x{x}, y{y}, z{z}, w{w} { -} - -Vector4::Vector4(float x, float y, float z) : x{x}, y{y}, z{z}, w{1.f} { -} - -Vector4::Vector4(Vector3 v, float w) : x{v.x}, y{v.y}, z{v.z}, w{w} { -} - -Vector4::Vector4(Vector3 v) : x{v.x}, y{v.y}, z{v.z}, w{1.f} { -} - -bool Vector4::operator==(Vector4 other) const { - return x == other.x && y == other.y && z == other.z && w == other.w; -} - -bool Vector4::operator!=(Vector4 other) const { - return !(*this == other); -} - -Vector4 Vector4::operator+() const { - return *this; -} - -Vector4 Vector4::operator-() const { - return { -x, -y, -z, -w }; -} - -Vector4 Vector4::operator+(Vector4 other) const { - return { x + other.x, y + other.y, z + other.z, w + other.w }; -} - -Vector4 Vector4::operator-(Vector4 other) const { - return *this + (-other); -} - -Vector4 Vector4::round() const { - return { std::round(x), std::round(y), std::round(z), std::round(w) }; -} - -Vector2 Vector4::xy() const { - return { x, y }; -} - -Vector3 Vector4::xyz() const { - return { x, y, z }; -} - -Vector4 Vector4::div_by_w() const { - return {x / w, y / w, z / w, w}; -} - -Vector4 engine::math::operator*(float n, Vector4 other) { - return { n * other.x, n * other.y, n * other.z, n * other.w }; -} - -Vector4 engine::math::operator*(Vector4 other, float n) { - return n * other; -} - -Vector4 engine::math::operator/(Vector4 other, float n) { - return { other.x / n, other.y / n, other.z / n, other.w / n }; -} diff --git a/src/math/vector.h b/src/math/vector.h index 82e1513..b26c5fe 100644 --- a/src/math/vector.h +++ b/src/math/vector.h @@ -1,72 +1,222 @@ #ifndef MATH_VECTOR_H #define MATH_VECTOR_H +#include <cmath> +#include "math/quat.h" + namespace engine::math { -class Vector2 { - public: - float x, y; - - Vector2(); - Vector2(float x, float y); - bool operator==(Vector2 other) const; - bool operator!=(Vector2 other) const; - Vector2 operator+() const; - Vector2 operator-() const; - Vector2 operator+(Vector2 other) const; - Vector2 operator-(Vector2 other) const; - float det(Vector2 other) const; - Vector2 round() const; +struct Vector2 { + float x, y; + + constexpr bool operator==(const Vector2& other) const & { + return x == other.x && y == other.y; + } + + constexpr bool operator!=(const Vector2& other) const & { + return !(*this == other); + } + + constexpr Vector2 operator+() const & { + return *this; + } + + constexpr Vector2 operator-() const & { + return { -x, -y }; + } + + constexpr Vector2 operator+(const Vector2& other) const & { + return { x + other.x, y + other.y }; + } + + constexpr Vector2 operator-(const Vector2& other) const & { + return *this + (-other); + } + + constexpr float det(const Vector2& other) const & { + return this->x * other.y - other.x * this->y; + } + + constexpr Vector2 round() const & { + return { std::round(x), std::round(y) }; + } + + constexpr Vector2 mul_term(const Vector2& other) const & { + return { x * other.x, y * other.y }; + } }; -Vector2 operator*(float n, Vector2 other); -Vector2 operator*(Vector2 other, float n); -Vector2 operator/(Vector2 other, float n); - -class Vector3 { - public: - float x, y, z; - - Vector3(); - Vector3(float x, float y, float z); - bool operator==(Vector3 other) const; - bool operator!=(Vector3 other) const; - Vector3 operator+() const; - Vector3 operator-() const; - Vector3 operator+(Vector3 other) const; - Vector3 operator-(Vector3 other) const; - Vector3 round() const; - Vector3 cross(Vector3 other) const; +constexpr Vector2 operator*(float n, const Vector2& other) { + return { n * other.x, n * other.y }; +} + +constexpr Vector2 operator*(const Vector2& other, float n) { + return n * other; +} + +constexpr Vector2 operator/(const Vector2& other, float n) { + return { other.x / n, other.y / n }; +} + +constexpr Vector2 operator+(const Vector2& other, float n) { + return { other.x + n, other.y + n }; +} + +constexpr Vector2 operator-(const Vector2& other, float n) { + return { other.x - n, other.y - n }; +} + +struct Vector3; +constexpr Vector3 operator*(float n, const Vector3& other); +constexpr Vector3 operator/(const Vector3& other, float n); + +struct Vector3 { + static constexpr Vector3 bilerp(const Vector3& v1, const Vector3& v2, const Vector3& v3, float b0, float b1) { + return b0 * v1 + b1 * v2 + (1.f - b0 - b1) * v3; + } + + float x, y, z; + + constexpr bool operator==(const Vector3& other) const & { + return x == other.x && y == other.y && z == other.z; + } + + constexpr bool operator!=(const Vector3& other) const & { + return !(*this == other); + } + + constexpr Vector3 operator+() const & { + return *this; + } + + constexpr Vector3 operator-() const & { + return { -x, -y, -z }; + } + + constexpr Vector3 operator+(const Vector3& other) const & { + return { x + other.x, y + other.y, z + other.z }; + } + + constexpr Vector3 operator-(const Vector3& other) const & { + return *this + (-other); + } + + constexpr Vector3 round() { + return { std::round(x), std::round(y), std::round(z) }; + } + + constexpr Vector3 cross(const Vector3& other) const & { + return { + y * other.z - z * other.y, + z * other.x - x * other.z, + x * other.y - y * other.x + }; + } + + constexpr Vector3 rot(const Quaternion& q) const & { + return { + (2.f * (q.w * q.w + q.x * q.x) - 1.f) * x + (2.f * (q.x * q.y - q.w * q.z) ) * y + (2.f * (q.x * q.z + q.w * q.y) ) * z, + (2.f * (q.x * q.y + q.w * q.z) ) * x + (2.f * (q.w * q.w + q.y * q.y) - 1.f) * y + (2.f * (q.y * q.z - q.w * q.x) ) * z, + (2.f * (q.x * q.z - q.w * q.y) ) * x + (2.f * (q.y * q.z + q.w * q.x) ) * y + (2.f * (q.w * q.w + q.z * q.z) - 1.f) * z, + }; + } + + constexpr float dot(const Vector3& other) const & { + return x * other.x + y * other.y + z * other.z; + } + + constexpr float length_squared() const & { + return dot(*this); + } + + constexpr float length() const & { + return std::sqrt(length_squared()); + } + + constexpr Vector3 normalize() const & { + return *this / length(); + } }; -Vector3 operator*(float n, Vector3 other); -Vector3 operator*(Vector3 other, float n); -Vector3 operator/(Vector3 other, float n); - -class Vector4 { - public: - float x, y, z, w; - - Vector4(); - Vector4(float x, float y, float z, float w); - Vector4(float x, float y, float z); - Vector4(Vector3 v, float w); - Vector4(Vector3 v); - bool operator==(Vector4 other) const; - bool operator!=(Vector4 other) const; - Vector4 operator+() const; - Vector4 operator-() const; - Vector4 operator+(Vector4 other) const; - Vector4 operator-(Vector4 other) const; - Vector4 round() const; - Vector2 xy() const; - Vector3 xyz() const; - Vector4 div_by_w() const; +constexpr Vector3 operator*(float n, const Vector3& other) { + return { n * other.x, n * other.y, n * other.z }; +} + +constexpr Vector3 operator*(const Vector3& other, float n) { + return n * other; +} + +constexpr Vector3 operator/(float n, const Vector3& other) { + return { n / other.x, n / other.y, n / other.z }; +} + +constexpr Vector3 operator/(const Vector3& other, float n) { + return { other.x / n, other.y / n, other.z / n }; +} + +struct Vector4 { + float x, y, z, w; + + constexpr Vector4() {} + constexpr Vector4(float x, float y, float z, float w) : x{x}, y{y}, z{z}, w{w} {} + constexpr Vector4(float x, float y, float z) : x{x}, y{y}, z{z}, w{1.f} {} + constexpr Vector4(const Vector2& v, float z, float w) : x{v.x}, y{v.y}, z{z}, w{w} {} + constexpr Vector4(const Vector2& v, float z) : x{v.x}, y{v.y}, z{z}, w{1.f} {} + constexpr Vector4(const Vector3& v, float w) : x{v.x}, y{v.y}, z{v.z}, w{w} {} + constexpr Vector4(const Vector3& v) : x{v.x}, y{v.y}, z{v.z}, w{1.f} {} + + constexpr bool operator==(const Vector4& other) const & { + return x == other.x && y == other.y && z == other.z && w == other.w; + } + + constexpr bool operator!=(const Vector4& other) const & { + return !(*this == other); + } + + constexpr Vector4 operator+() const & { + return *this; + } + + constexpr Vector4 operator-() const & { + return { -x, -y, -z, -w }; + } + + constexpr Vector4 operator+(const Vector4& other) const & { + return { x + other.x, y + other.y, z + other.z, w + other.w }; + } + + constexpr Vector4 operator-(const Vector4& other) const & { + return *this + (-other); + } + + constexpr Vector4 round() const & { + return { std::round(x), std::round(y), std::round(z), std::round(w) }; + } + + constexpr Vector2 xy() const & { + return { x, y }; + } + + constexpr Vector3 xyz() const & { + return { x, y, z }; + } + + constexpr Vector4 div_by_w() const & { + return {x / w, y / w, z / w, w}; + } }; -Vector4 operator*(float n, Vector4 other); -Vector4 operator*(Vector4 other, float n); -Vector4 operator/(Vector4 other, float n); +constexpr Vector4 operator*(float n, const Vector4& other) { + return { n * other.x, n * other.y, n * other.z, n * other.w }; +} + +constexpr Vector4 operator*(const Vector4& other, float n) { + return n * other; +} + +constexpr Vector4 operator/(const Vector4& other, float n) { + return { other.x / n, other.y / n, other.z / n, other.w / n }; +} } |