aboutsummaryrefslogtreecommitdiff
path: root/src/math
diff options
context:
space:
mode:
Diffstat (limited to 'src/math')
-rw-r--r--src/math/mat4.cpp149
-rw-r--r--src/math/mat4.h166
-rw-r--r--src/math/quat.h74
-rw-r--r--src/math/tform.h35
-rw-r--r--src/math/vector.cpp175
-rw-r--r--src/math/vector.h266
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 };
+}
}