diff options
| author | Mel <einebeere@gmail.com> | 2023-07-07 21:39:42 +0200 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2023-07-07 21:39:42 +0200 |
| commit | f1fc192ddc4c739fa8b4b376c759b7d3218a34eb (patch) | |
| tree | 9e9afb9a21ba3ca27d1f25d46230aa9d27f8be39 /src/Math | |
| parent | 24b8124469350d1c80d0553cf3f4bf58cdb1489b (diff) | |
| download | meowcraft-f1fc192ddc4c739fa8b4b376c759b7d3218a34eb.tar.zst meowcraft-f1fc192ddc4c739fa8b4b376c759b7d3218a34eb.zip | |
Chunk-bound tree decoration
Diffstat (limited to 'src/Math')
| -rw-r--r-- | src/Math/Matrix.hpp | 21 | ||||
| -rw-r--r-- | src/Math/Random.cpp | 31 | ||||
| -rw-r--r-- | src/Math/Random.hpp | 31 | ||||
| -rw-r--r-- | src/Math/Vector.hpp | 79 |
4 files changed, 134 insertions, 28 deletions
diff --git a/src/Math/Matrix.hpp b/src/Math/Matrix.hpp index 69241d3..d467f72 100644 --- a/src/Math/Matrix.hpp +++ b/src/Math/Matrix.hpp @@ -9,14 +9,14 @@ template <size_t R, size_t C, typename T = float> struct Matrix { Matrix() : elements{} {}; - explicit Matrix(T scalar) { + explicit Matrix(const T scalar) { std::fill(elements, elements + R * C, scalar); }; template<typename ...Args, typename std::enable_if_t<sizeof...(Args) == R * C, int> = 0> Matrix(Args... args): elements{ args... } {}; - explicit Matrix(T values[R * C]) { + explicit Matrix(const T values[R * C]) { std::copy(values, values + R * C, elements); }; @@ -67,11 +67,11 @@ struct Matrix { return rotation_x * rotation_y * rotation_z; } - Vector<C, T> row(size_t index) { + Vector<C, T> row(size_t index) const { return { &elements[index * C] }; } - Vector<R, T> col(size_t index) { + Vector<R, T> col(size_t index) const { Vector<R, T> result{}; for (int i = 0; i < R; i++) { result[i] = this->operator()(index, i); @@ -79,7 +79,7 @@ struct Matrix { return result; } - Matrix transpose() { + Matrix transpose() const { Matrix result{}; for (int y = 0; y < R; y++) { for (int x = 0; x < C; x++) { @@ -89,7 +89,7 @@ struct Matrix { return result; } - Matrix operator+(Matrix other) { + Matrix operator+(const Matrix other) const { Matrix result{}; for (int i = 0; i < R * C; i++) { result.elements[i] = elements[i] + other.elements[i]; @@ -106,7 +106,7 @@ struct Matrix { } template<size_t N> - Matrix<R, N, T> operator*(Matrix<C, N, T> other) { + Matrix<R, N, T> operator*(const Matrix<C, N, T> other) const { Matrix<R, N, T> result{}; for (int y = 0; y < R; y++) { for (int x = 0; x < N; x++) { @@ -121,13 +121,16 @@ struct Matrix { return result; } - Vector<R, T> operator*(Vector<R, T> vector) { + Vector<R, T> operator*(const Vector<R, T> vector) const { Matrix<R, 1, T> matrix(vector.elements); matrix = this->operator*(matrix); return { matrix.elements }; } - auto& operator()(size_t x, size_t y) { + const T& operator()(const size_t x, const size_t y) const { + return elements[y * C + x]; + } + T& operator()(const size_t x, const size_t y) { return elements[y * C + x]; } diff --git a/src/Math/Random.cpp b/src/Math/Random.cpp new file mode 100644 index 0000000..e35cda7 --- /dev/null +++ b/src/Math/Random.cpp @@ -0,0 +1,31 @@ +#include "Random.hpp" + +namespace Math::Random { + +std::array<uint8_t, 4> break_float(const float f) { + static_assert(sizeof(float) == 4); + + union { float f; uint8_t u[4]; } t{}; + t.f = f; + + return { + t.u[0], t.u[1], t.u[2], t.u[3] + }; +} + +float to_float(uint8_t u) { + return (float)u / (float)255; +} + +uint8_t hash(uint8_t x) { + auto o = ((x ^ 0xAA) * 5); + auto rot = o % 8; + return o << rot | o >> (8 - rot); +} + +float random() { + uint8_t r = std::rand() % 255; + return to_float(hash(r)); +} + +} \ No newline at end of file diff --git a/src/Math/Random.hpp b/src/Math/Random.hpp new file mode 100644 index 0000000..ab94871 --- /dev/null +++ b/src/Math/Random.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "array" +#include "Common.hpp" + +namespace Math::Random { + +std::array<uint8_t, 4> break_float(float f); +float to_float(uint8_t u); + +uint8_t hash(uint8_t x); + +float random(); + +template <size_t D> +struct Noise { + float at(Vector<D> pos) const { + uint8_t to_hash[D * 4]; + for (int i = 0; i < D; i++) { + auto b = break_float(pos[i]); + to_hash[i*4] = b[0]; to_hash[i*4+1] = b[1]; to_hash[i*4+2] = b[2]; to_hash[i*4+3] = b[3]; + } + uint8_t h = 0; + for (int i = 0; i < D * 4; i++) { + h = hash(h) + to_hash[i]; + } + return to_float(h); + } +}; + +} \ No newline at end of file diff --git a/src/Math/Vector.hpp b/src/Math/Vector.hpp index 260891d..54207f0 100644 --- a/src/Math/Vector.hpp +++ b/src/Math/Vector.hpp @@ -10,31 +10,36 @@ struct Vector { Vector(): elements{} {}; template<typename ...Args, std::enable_if_t<sizeof...(Args) == S, int> = 0> - Vector<S, T>(Args... args) : elements{ args... } {}; + Vector(Args... args) : elements{ args... } {}; - Vector<S, T>(T values[S]) { + Vector(const T values[S]) { std::copy(values, values + S, elements); }; - Vector<S, T>(T scalar) { + explicit Vector(const T scalar) { std::fill(elements, elements + S, scalar); }; - Vector<S, T>(Vector<S - 1, T> vector, T scalar) { + Vector(const Vector<S - 1, T> vector, const T scalar) { std::copy(vector.elements, vector.elements + S - 1, elements); elements[S - 1] = scalar; } - Vector<S, T> map(std::function<T(T)> f) const { - Vector<S, T> result{}; + template<size_t N, std::enable_if_t<(N > S), int> = 0> + explicit Vector(const Vector<N, T> vector) { + std::copy(vector.elements, vector.elements + S, elements); + } + + Vector map(std::function<T(T)> f) const { + Vector result{}; for (int i = 0; i < S; i++) { result[i] = f(elements[i]); } return result; } - Vector<S, T> map(std::function<T(size_t, T)> f) const { - Vector<S, T> result{}; + Vector map(std::function<T(size_t, T)> f) const { + Vector result{}; for (int i = 0; i < S; i++) { result[i] = f(i, elements[i]); } @@ -57,20 +62,27 @@ struct Vector { return sqrt(map([](auto x) { return x * x;}).sum()); } - Vector<S, T> normalize() const { + Vector normalize() const { auto m = magnitude(); return map([=](auto x) { return x / m; }); } - T distance(Vector<S, T> other) const { + T distance(const Vector other) const { return (*this - other).magnitude(); } - Vector<S, T> abs() const { + Vector<3, T> any_orthogonal() { + if (Vector a{y(), -x(), 0.0f}; a != zero()) return a; + if (Vector b{z(), 0.0f, -x()}; b != zero()) return b; + if (Vector c{0.0f, z(), -y()}; c != zero()) return c; + return zero(); + } + + Vector abs() const { return map([=](auto x) { return std::abs(x); }); } - Vector<3, T> cross(Vector<3, T> other) const { + Vector<3, T> cross(const Vector<3, T> other) const { return { y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(), @@ -86,34 +98,52 @@ struct Vector { return elements[index]; } - Vector<S, T> operator+(Vector<S, T> other) const { + Vector operator+(const Vector other) const { return map([&](auto i, auto x) { return x + other[i]; }); } - Vector<S, T> operator+(T scalar) const { + Vector operator+(T scalar) const { return map([=](auto x) { return x + scalar; }); } - Vector<S, T> operator*(T scalar) const { + Vector operator*(T scalar) const { return map([=](auto x) { return x * scalar; }); } - T operator*(Vector<S, T> other) const { + T operator*(const Vector other) const { return map([&](auto i, auto x) { return x * other[i]; }).sum(); } - Vector<S, T> operator-(Vector<S, T> other) const { + Vector operator-(const Vector other) const { return map([&](auto i, auto x) { return x - other[i]; }); } - Vector<S, T> operator-() const { + Vector operator-() const { return map([](T x) -> T { return -x; }); } - Vector<S, T> operator/(T scalar) const { + Vector operator/(T scalar) const { return map([=](auto x) { return x / scalar; }); } + bool operator==(const Vector& other) { + for (int i = 0; i < S; i++) { + if (elements[i] != other[i]) { + return false; + } + } + return true; + } + + bool operator!=(const Vector& other) { + return !this->operator==(other); + } + + Vector& operator+=(const Vector& other) { + *this = *this + other; + return *this; + } + T& x() { static_assert(S > 0); return elements[0]; } const T& x() const { static_assert(S > 0); return elements[0]; } @@ -138,5 +168,16 @@ struct Vector { return str.str(); } + static Vector<3, T> up() { return {(T)0, (T)1, (T)0}; } + static Vector<3, T> down() { return {(T)0, (T)-1, (T)0}; } + static Vector<3, T> forward() { return {(T)0, (T)0, (T)1}; } + static Vector<3, T> back() { return {(T)0, (T)0, (T)-1}; } + static Vector<3, T> right() { return {(T)1, (T)0, (T)0}; } + static Vector<3, T> left() { return {(T)-1, (T)0, (T)0}; } + + static Vector<3, T> one() { return Vector{(T)1}; } + static Vector<3, T> zero() { return Vector{(T)0}; } + static Vector<3, T> max() { return Vector{(T)std::numeric_limits<T>::max()}; } + T elements[S]; }; |
