summaryrefslogtreecommitdiff
path: root/src/Math
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2023-07-07 21:39:42 +0200
committerMel <einebeere@gmail.com>2023-07-07 21:39:42 +0200
commitf1fc192ddc4c739fa8b4b376c759b7d3218a34eb (patch)
tree9e9afb9a21ba3ca27d1f25d46230aa9d27f8be39 /src/Math
parent24b8124469350d1c80d0553cf3f4bf58cdb1489b (diff)
downloadmeowcraft-f1fc192ddc4c739fa8b4b376c759b7d3218a34eb.tar.zst
meowcraft-f1fc192ddc4c739fa8b4b376c759b7d3218a34eb.zip
Chunk-bound tree decoration
Diffstat (limited to 'src/Math')
-rw-r--r--src/Math/Matrix.hpp21
-rw-r--r--src/Math/Random.cpp31
-rw-r--r--src/Math/Random.hpp31
-rw-r--r--src/Math/Vector.hpp79
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];
};