From e77086601b5025872188a01fb42fb51e8370e0a7 Mon Sep 17 00:00:00 2001 From: Sven Balzer <4653051+Kyuusokuna@users.noreply.github.com> Date: Sun, 9 Mar 2025 20:31:27 +0100 Subject: [PATCH] clean up math_graphics.h --- CMakeLists.txt | 1 + src/main.cpp | 6 +- src/math_graphics.cpp | 897 ++++++++++++++++++++++++++++++++++++++++++ src/math_graphics.h | 877 ++++++++++++----------------------------- 4 files changed, 1159 insertions(+), 622 deletions(-) create mode 100644 src/math_graphics.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8c66825..75292b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ add_executable(mikemon src/log.cpp src/load_entire_file.cpp src/smol-atlas.cpp + src/math_graphics.cpp src/main.cpp ) target_link_libraries(mikemon diff --git a/src/main.cpp b/src/main.cpp index a161f03..5ca5d79 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -865,10 +865,10 @@ int main(int argc, char **argv) { int item_x = sma_item_x(tile_infos[i].atlas_item); int item_y = sma_item_y(tile_infos[i].atlas_item); - tile_infos[i].uv_min = { .x = (item_x + tile_border_size) / (float)tile_atlas_size, .y = (item_y + tile_border_size) / (float)tile_atlas_size }; - tile_infos[i].uv_max = { .x = (item_x + tile_border_size + width) / (float)tile_atlas_size, .y = (item_y + tile_border_size + height) / (float)tile_atlas_size }; + tile_infos[i].uv_min = V2_((item_x + tile_border_size) / (float)tile_atlas_size, (item_y + tile_border_size) / (float)tile_atlas_size); + tile_infos[i].uv_max = V2_((item_x + tile_border_size + width) / (float)tile_atlas_size, (item_y + tile_border_size + height) / (float)tile_atlas_size); - cpu_tile_infos_buffer[i] = V4{ tile_infos[i].uv_min, tile_infos[i].uv_max }; + cpu_tile_infos_buffer[i] = V4_(tile_infos[i].uv_min, tile_infos[i].uv_max); blit(tile_atlas_texture_cpu, tile_atlas_size, item_x + tile_border_size, item_y + tile_border_size, (char *)data, width, width, height); diff --git a/src/math_graphics.cpp b/src/math_graphics.cpp new file mode 100644 index 0000000..2e9643b --- /dev/null +++ b/src/math_graphics.cpp @@ -0,0 +1,897 @@ +#include "math_graphics.h" +#include + +namespace M { + float square_root(float a) { + return sqrtf(a); + } + + double square_root(double a) { + return sqrt(a); + } + + float reciprocal_square_root(float a) { + return 1.0f / square_root(a); + } + + double reciprocal_square_root(double a) { + return 1.0 / square_root(a); + } + + float lerp(float a, float b, float t) { + return (1.0f - t) * a + t * b; + } + + float ilerp(float a, float b, float v) { + return (v - a) / (b - a); + } + + float remap(float in_a, float in_b, float out_a, float out_b, float v) { + float t = ilerp(in_a, in_b, v); + return lerp(out_a, out_b, t); + } + + float radians(float degrees) { + return degrees * (M_PIf / 180.0f); + } + + V2 V2_(float x, float y) { + return { x, y }; + } + + V2 operator -(V2 a) { + return { + -a.x, + -a.y + }; + } + + V2 operator +(V2 a, V2 b) { + return { + a.x + b.x, + a.y + b.y + }; + } + + V2 operator +=(V2& a, V2 b) { + return a = a + b; + } + + V2 operator -(V2 a, V2 b) { + return { + a.x - b.x, + a.y - b.y + }; + } + + V2 operator -=(V2& a, V2 b) { + return a = a - b; + } + + V2 operator *(float a, V2 b) { + return { + a * b.x, + a * b.y + }; + } + + V2 operator *(V2 a, float b) { + return { + a.x * b, + a.y * b + }; + } + + V2 &operator *= (V2 &a, float b) { + a = a * b; + return a; + } + + V2 operator /(float a, V2 b) { + return { + a / b.x, + a / b.y + }; + } + + V2 operator /(V2 a, float b) { + return { + a.x / b, + a.y / b + }; + } + + V2 &operator /= (V2 &a, float b) { + a = a / b; + return a; + } + + V2 operator /(V2 a, V2 b) { + return { + a.x / b.x, + a.y / b.y + }; + } + + float dot(V2 a, V2 b) { + return a.x * b.x + a.y * b.y; + } + + V2 hadamard(V2 a, V2 b) { + return { + a.x * b.x, + a.y * b.y + }; + } + + float length_squared(V2 a) { + return dot(a, a); + } + + float length(V2 a) { + return square_root(length_squared(a)); + } + + float reciprocal_length(V2 a) { + return reciprocal_square_root(length_squared(a)); + } + + V2 normalize(V2 a) { + return a * reciprocal_length(a); + } + + V2 perpendicular(V2 a) { + return { + -a.y, + a.x + }; + } + + V2 clamp01(V2 a) { + return { + clamp01(a.x), + clamp01(a.y) + }; + } + + V2 min(V2 a, V2 b) { + return { + min(a.x, b.x), + min(a.y, b.y) + }; + } + + V2 max(V2 a, V2 b) { + return { + max(a.x, b.x), + max(a.y, b.y) + }; + } + + float min(V2 a) { + return min(a.x, a.y); + } + + float max(V2 a) { + return max(a.x, a.y); + } + + V2 lerp(V2 a, V2 b, float t) { + return { + lerp(a.x, b.x, t), + lerp(a.y, b.y, t) + }; + } + + V2 lerp(V2 a, V2 b, V2 t) { + return { + lerp(a.x, b.x, t.x), + lerp(a.y, b.y, t.y) + }; + } + + V2 ilerp(V2 a, V2 b, V2 v) { + return (v - a) / (b - a); + } + + V2 remap(V2 in_a, V2 in_b, V2 out_a, V2 out_b, V2 v) { + V2 t = ilerp(in_a, in_b, v); + return lerp(out_a, out_b, t); + } + + V3 V3_(float x, float y, float z) { + return { x, y, z }; + } + + V3 V3_(V2 xy, float z) { + return { xy[0], xy[1], z }; + } + + V3 V3_(float x, V2 yz) { + return { x, yz[0], yz[1] }; + } + + V3 operator -(V3 a) { + return { + -a.x, + -a.y, + -a.z + }; + } + + V3 operator +(V3 a, V3 b) { + return { + a.x + b.x, + a.y + b.y, + a.z + b.z + }; + } + + V3 operator +=(V3 &a, V3 b) { + return a = a + b; + } + + V3 operator -(V3 a, V3 b) { + return { + a.x - b.x, + a.y - b.y, + a.z - b.z + }; + } + + V3 operator -=(V3 &a, V3 b) { + return a = a - b; + } + + V3 operator *(float a, V3 b) { + return { + a * b.x, + a * b.y, + a * b.z + }; + } + + V3 operator *(V3 a, float b) { + return { + a.x * b, + a.y * b, + a.z * b + }; + } + + V3 operator *=(V3 &a, float b) { + return a = a * b; + } + + V3 operator /(float a, V3 b) { + return { + a / b.x, + a / b.y, + a / b.z + }; + } + + V3 operator /(V3 a, float b) { + return { + a.x / b, + a.y / b, + a.z / b + }; + } + + V3 operator /=(V3 &a, float b) { + return a = a / b; + } + + V3 operator /(V3 a, V3 b) { + return { + a.x / b.x, + a.y / b.y, + a.z / b.z + }; + } + + float dot(V3 a, V3 b) { + return a.x * b.x + a.y * b.y + a.z * b.z; + } + + V3 hadamard(V3 a, V3 b) { + return { + a.x * b.x, + a.y * b.y, + a.z * b.z + }; + } + + V3 cross(V3 a, V3 b) { + return { + a.y * b.z - a.z * b.y, + a.z * b.x - a.x * b.z, + a.x * b.y - a.y * b.x + }; + } + + float length_squared(V3 a) { + return dot(a, a); + } + + float length(V3 a) { + return square_root(length_squared(a)); + } + + float reciprocal_length(V3 a) { + return reciprocal_square_root(length_squared(a)); + } + + V3 normalize(V3 a) { + return a * reciprocal_length(a); + } + + V3 clamp01(V3 a) { + return { + clamp01(a.x), + clamp01(a.y), + clamp01(a.z) + }; + } + + V3 min(V3 a, V3 b) { + return { + min(a.x, b.x), + min(a.y, b.y), + min(a.z, b.z) + }; + } + + V3 max(V3 a, V3 b) { + return { + max(a.x, b.x), + max(a.y, b.y), + max(a.z, b.z) + }; + } + + float min(V3 a) { + return min(min(a.x, a.y), a.z); + } + + float max(V3 a) { + return max(max(a.x, a.y), a.z); + } + + V3 lerp(V3 a, V3 b, float t) { + return { + lerp(a.x, b.x, t), + lerp(a.y, b.y, t), + lerp(a.z, b.z, t) + }; + } + + V3 lerp(V3 a, V3 b, V3 t) { + return { + lerp(a.x, b.x, t.x), + lerp(a.y, b.y, t.y), + lerp(a.z, b.z, t.z) + }; + } + + V3 ilerp(V3 a, V3 b, V3 v) { + return (v - a) / (b - a); + } + + V3 remap(V3 in_a, V3 in_b, V3 out_a, V3 out_b, V3 v) { + V3 t = ilerp(in_a, in_b, v); + return lerp(out_a, out_b, t); + } + + V4 V4_(float x, float y, float z, float w) { + return { x, y, z, w }; + } + + V4 V4_(V2 xy, V2 zw) { + return { xy[0], xy[1], zw[0], zw[1] }; + } + + V4 V4_(V2 xy, float z, float w) { + return { xy[0], xy[1], z, w }; + } + + V4 V4_(float x, V2 yz, float w) { + return { x, yz[0], yz[1], w }; + } + + V4 V4_(float x, float y, V2 zw) { + return { x, y, zw[0], zw[1] }; + } + + V4 V4_(V3 xyz, float w) { + return { xyz[0], xyz[1], xyz[2], w }; + } + + V4 V4_(float x, V3 yzw) { + return { x, yzw[0], yzw[1], yzw[2] }; + } + + V4 operator -(V4 a) { + return { + -a.x, + -a.y, + -a.z, + -a.w + }; + } + + V4 operator +(V4 a, V4 b) { + return { + a.x + b.x, + a.y + b.y, + a.z + b.z, + a.w + b.w + }; + } + + V4 operator +=(V4 &a, V4 b) { + return a = a + b; + } + + V4 operator -(V4 a, V4 b) { + return { + a.x - b.x, + a.y - b.y, + a.z - b.z, + a.w - b.w + }; + } + + V4 operator -=(V4 &a, V4 b) { + return a = a - b; + } + + V4 operator *(float a, V4 b) { + return { + a * b.x, + a * b.y, + a * b.z, + a * b.w + }; + } + + V4 operator *(V4 a, float b) { + return { + a.x * b, + a.y * b, + a.z * b, + a.w * b + }; + } + + V4 operator *=(V4 &a, float b) { + return a = a * b; + } + + V4 operator /(float a, V4 b) { + return { + a / b.x, + a / b.y, + a / b.z, + a / b.w + }; + } + + V4 operator /(V4 a, float b) { + return { + a.x / b, + a.y / b, + a.z / b, + a.w / b + }; + } + + V4 operator /=(V4 &a, float b) { + return a = a / b; + } + + V4 operator /(V4 a, V4 b) { + return { + a.x / b.x, + a.y / b.y, + a.z / b.z, + a.w / b.w + }; + } + + float dot(V4 a, V4 b) { + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; + } + + V4 hadamard(V4 a, V4 b) { + return { + a.x * b.x, + a.y * b.y, + a.z * b.z, + a.w * b.w + }; + } + + float length_squared(V4 a) { + return dot(a, a); + } + + float length(V4 a) { + return square_root(length_squared(a)); + } + + float reciprocal_length(V4 a) { + return reciprocal_square_root(length_squared(a)); + } + + V4 normalize(V4 a) { + return a * reciprocal_length(a); + } + + V4 clamp01(V4 a) { + return { + clamp01(a.x), + clamp01(a.y), + clamp01(a.z), + clamp01(a.w) + }; + } + + V4 min(V4 a, V4 b) { + return { + min(a.x, b.x), + min(a.y, b.y), + min(a.z, b.z), + min(a.w, b.w) + }; + } + + V4 max(V4 a, V4 b) { + return { + max(a.x, b.x), + max(a.y, b.y), + max(a.z, b.z), + max(a.w, b.w) + }; + } + + float min(V4 a) { + return min(min(a.x, a.y), min(a.z, a.w)); + } + + float max(V4 a) { + return max(max(a.x, a.y), max(a.z, a.w)); + } + + V4 lerp(V4 a, V4 b, float t) { + return { + lerp(a.x, b.x, t), + lerp(a.y, b.y, t), + lerp(a.z, b.z, t), + lerp(a.w, b.w, t) + }; + } + + V4 lerp(V4 a, V4 b, V4 t) { + return { + lerp(a.x, b.x, t.x), + lerp(a.y, b.y, t.y), + lerp(a.z, b.z, t.z), + lerp(a.w, b.w, t.w) + }; + } + + V4 ilerp(V4 a, V4 b, V4 v) { + return (v - a) / (b - a); + } + + V4 remap(V4 in_a, V4 in_b, V4 out_a, V4 out_b, V4 v) { + V4 t = ilerp(in_a, in_b, v); + return lerp(out_a, out_b, t); + } + + M2x2 M2x2_(float _00, float _01, + float _10, float _11) { + return { + _00, _01, + _10, _11, + }; + } + + M2x2 M2x2_(V2 row0, V2 row1) { + return { + row0[0], row0[1], + row1[0], row1[1], + }; + } + + M2x2 operator -(M2x2 a){ + return { + -a[0][0], -a[0][1], + -a[1][0], -a[1][1] + }; + } + + M2x2 operator +(M2x2 a, M2x2 b) { + return { + a[0][0] + b[0][0], a[0][1] + b[0][1], + a[1][0] + b[1][0], a[1][1] + b[1][1] + }; + } + + M2x2 operator +=(M2x2 &a, M2x2 b) { + return a = a + b; + } + + M2x2 operator -(M2x2 a, M2x2 b) { + return { + a[0][0] - b[0][0], a[0][1] - b[0][1], + a[1][0] - b[1][0], a[1][1] - b[1][1] + }; + } + + M2x2 operator -=(M2x2 &a, M2x2 b) { + return a = a - b; + } + + M2x2 operator *(float a, M2x2 b) { + return { + a * b[0][0], a * b[0][1], + a * b[1][0], a * b[1][1] + }; + } + + M2x2 operator *(M2x2 a, float b) { + return { + a[0][0] * b, a[0][1] * b, + a[1][0] * b, a[1][1] * b + }; + } + + M2x2 operator *=(M2x2 &a, float b) { + return a = a * b; + } + + M2x2 operator *(M2x2 a, M2x2 b) { + return { + a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1], + a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1] + }; + } + + V2 operator *(M2x2 a, V2 b) { + return { + a[0][0] * b[0] + a[0][1] * b[1], + a[1][0] * b[0] + a[1][1] * b[1], + }; + } + + M2x2 transpose(M2x2 a) { + return { + a[0][0], a[1][0], + a[0][1], a[1][1] + }; + } + + M3x3 M3x3_(float _00, float _01, float _02, + float _10, float _11, float _12, + float _20, float _21, float _22) { + return { + _00, _01, _02, + _10, _11, _12, + _20, _21, _22 + }; + } + + M3x3 M3x3_(V3 row0, V3 row1, V3 row2) { + return { + row0[0], row0[1], row0[2], + row1[0], row1[1], row1[2], + row2[0], row2[1], row2[2] + }; + } + + M3x3 operator -(M3x3 a) { + return { + -a[0][0], -a[0][1], -a[0][1], + -a[1][0], -a[1][1], -a[1][2], + -a[2][0], -a[2][1], -a[2][2] + }; + } + + M3x3 operator +(M3x3 a, M3x3 b) { + return { + a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2], + a[1][0] + b[1][0], a[1][1] + b[1][1], a[1][2] + b[1][2], + a[2][0] + b[2][0], a[2][1] + b[2][1], a[2][2] + b[2][2] + }; + } + + M3x3 operator +=(M3x3 &a, M3x3 b) { + return a = a + b; + } + + M3x3 operator -(M3x3 a, M3x3 b) { + return { + a[0][0] - b[0][0], a[0][1] - b[0][1], a[0][2] - b[0][2], + a[1][0] - b[1][0], a[1][1] - b[1][1], a[1][2] - b[1][2], + a[2][0] - b[2][0], a[2][1] - b[2][1], a[2][2] - b[2][2] + }; + } + + M3x3 operator -=(M3x3 &a, M3x3 b) { + return a = a - b; + } + + M3x3 operator *(float a, M3x3 b) { + return { + a * b[0][0], a * b[0][1], a * b[0][2], + a * b[1][0], a * b[1][1], a * b[1][2], + a * b[2][0], a * b[2][1], a * b[2][2] + }; + } + + M3x3 operator *(M3x3 a, float b) { + return { + a[0][0] * b, a[0][1] * b, a[0][2] * b, + a[1][0] * b, a[1][1] * b, a[1][2] * b, + a[2][0] * b, a[2][1] * b, a[2][2] * b + }; + } + + M3x3 operator *=(M3x3 &a, float b) { + return a = a * b; + } + + M3x3 operator *(M3x3 a, M3x3 b) { + return { + a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0], a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1], a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2], + a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0], a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1], a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[0][2] * b[2][2], + a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0], a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1], a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[0][2] * b[2][2] + }; + } + + V3 operator *(M3x3 a, V3 b) { + return { + a[0][0] * b[0] + a[0][1] * b[1] + a[0][2] * b[2], + a[1][0] * b[0] + a[1][1] * b[1] + a[1][2] * b[2], + a[2][0] * b[0] + a[2][1] * b[1] + a[2][2] * b[2] + }; + } + + M3x3 transpose(M3x3 a) { + return { + a[0][0], a[1][0], a[2][0], + a[0][1], a[1][1], a[2][1], + a[0][2], a[1][2], a[2][2] + }; + } + + M4x4 M4x4_(float _00, float _01, float _02, float _03, + float _10, float _11, float _12, float _13, + float _20, float _21, float _22, float _23, + float _30, float _31, float _32, float _33) { + return { + _00, _01, _02, _03, + _10, _11, _12, _13, + _20, _21, _22, _23, + _30, _31, _32, _33 + }; + } + + M4x4 M4x4_(V4 row0, V4 row1, V4 row2, V4 row3) { + return { + row0[0], row0[1], row0[2], row0[3], + row1[0], row1[1], row1[2], row1[3], + row2[0], row2[1], row2[2], row2[3], + row3[0], row3[1], row3[2], row3[3] + }; + } + + M4x4 operator -(M4x4 a) { + return { + -a[0][0], -a[0][1], -a[0][1], -a[0][3], + -a[1][0], -a[1][1], -a[1][2], -a[1][3], + -a[2][0], -a[2][1], -a[2][2], -a[2][3], + -a[3][0], -a[3][1], -a[3][2], -a[3][3] + }; + } + + M4x4 operator +(M4x4 a, M4x4 b) { + return { + a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2], a[0][3] + b[0][3], + a[1][0] + b[1][0], a[1][1] + b[1][1], a[1][2] + b[1][2], a[1][3] + b[1][3], + a[2][0] + b[2][0], a[2][1] + b[2][1], a[2][2] + b[2][2], a[2][3] + b[2][3], + a[3][0] + b[3][0], a[3][1] + b[3][1], a[3][2] + b[3][2], a[3][3] + b[3][3] + }; + } + + M4x4 operator +=(M4x4 &a, M4x4 b) { + return a = a + b; + } + + M4x4 operator -(M4x4 a, M4x4 b) { + return { + a[0][0] - b[0][0], a[0][1] - b[0][1], a[0][2] - b[0][2], a[0][3] - b[0][3], + a[1][0] - b[1][0], a[1][1] - b[1][1], a[1][2] - b[1][2], a[1][3] - b[1][3], + a[2][0] - b[2][0], a[2][1] - b[2][1], a[2][2] - b[2][2], a[2][3] - b[2][3], + a[3][0] - b[3][0], a[3][1] - b[3][1], a[3][2] - b[3][2], a[3][3] - b[3][3] + }; + } + + M4x4 operator -=(M4x4 &a, M4x4 b) { + return a = a - b; + } + + M4x4 operator *(float a, M4x4 b) { + return { + a * b[0][0], a * b[0][1], a * b[0][2], a * b[0][3], + a * b[1][0], a * b[1][1], a * b[1][2], a * b[1][3], + a * b[2][0], a * b[2][1], a * b[2][2], a * b[2][3], + a * b[3][0], a * b[3][1], a * b[3][2], a * b[3][3] + }; + } + + M4x4 operator *(M4x4 a, float b) { + return { + a[0][0] * b, a[0][1] * b, a[0][2] * b, a[0][3] * b, + a[1][0] * b, a[1][1] * b, a[1][2] * b, a[1][3] * b, + a[2][0] * b, a[2][1] * b, a[2][2] * b, a[2][3] * b, + a[3][0] * b, a[3][1] * b, a[3][2] * b, a[3][3] * b + }; + } + + M4x4 operator *=(M4x4 &a, float b) { + return a = a * b; + } + + M4x4 operator *(M4x4 a, M4x4 b) { + return { + a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0] + a[0][3] * b[3][0], a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1] + a[0][3] * b[3][1], a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2] + a[0][3] * b[3][2], a[0][0] * b[0][3] + a[0][1] * b[1][3] + a[0][2] * b[2][3] + a[0][3] * b[3][3], + a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0] + a[1][3] * b[3][0], a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1] + a[1][3] * b[3][1], a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2] + a[1][3] * b[3][2], a[1][0] * b[0][3] + a[1][1] * b[1][3] + a[1][2] * b[2][3] + a[1][3] * b[3][3], + a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0] + a[2][3] * b[3][0], a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1] + a[2][3] * b[3][1], a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2] + a[2][3] * b[3][2], a[2][0] * b[0][3] + a[2][1] * b[1][3] + a[2][2] * b[2][3] + a[2][3] * b[3][3], + a[3][0] * b[0][0] + a[3][1] * b[1][0] + a[3][2] * b[2][0] + a[3][3] * b[3][0], a[3][0] * b[0][1] + a[3][1] * b[1][1] + a[3][2] * b[2][1] + a[3][3] * b[3][1], a[3][0] * b[0][2] + a[3][1] * b[1][2] + a[3][2] * b[2][2] + a[3][3] * b[3][2], a[3][0] * b[0][3] + a[3][1] * b[1][3] + a[3][2] * b[2][3] + a[3][3] * b[3][3], + }; + } + + V4 operator *(M4x4 a, V4 b) { + return { + a[0][0] * b[0] + a[0][1] * b[1] + a[0][2] * b[2] + a[0][3] * b[3], + a[1][0] * b[0] + a[1][1] * b[1] + a[1][2] * b[2] + a[1][3] * b[3], + a[2][0] * b[0] + a[2][1] * b[1] + a[2][2] * b[2] + a[2][3] * b[3], + a[3][0] * b[0] + a[3][1] * b[1] + a[3][2] * b[2] + a[3][3] * b[3], + }; + } + + M4x4 transpose(M4x4 a) { + return { + a[0][0], a[1][0], a[2][0], a[3][0], + a[0][1], a[1][1], a[2][1], a[3][1], + a[0][2], a[1][2], a[2][2], a[3][2], + a[0][3], a[1][3], a[2][3], a[3][3], + }; + } + + M4x4 projection(float fovy, float aspect, float near) { + float g = 1.0 / tanf(fovy * 0.5); + + return { + g / aspect, 0, 0, 0, + 0, g, 0, 0, + 0, 0, 0, near, + 0, 0, 1, 0, + }; + } + + M4x4 inverse_projection(float fovy, float aspect, float near) { + float g = 1.0 / tanf(fovy * 0.5); + + return { + aspect / g, 0, 0, 0, + 0, 1 / g, 0, 0, + 0, 0, 0, 1, + 0, 0, 1 / near, 0, + }; + } +} diff --git a/src/math_graphics.h b/src/math_graphics.h index 5ce4e62..64d7226 100644 --- a/src/math_graphics.h +++ b/src/math_graphics.h @@ -1,13 +1,5 @@ #pragma once -#define _CRT_SECURE_NO_WARNINGS - - -#include -#include -#include -#include -#include -#include +#include #undef min #undef max @@ -15,12 +7,12 @@ namespace M { template constexpr inline T min(T a, T b) { - return a < b ? a : b; + return (a < b) ? a : b; } template constexpr inline T max(T a, T b) { - return a > b ? a : b; + return (a > b) ? a : b; } template @@ -33,42 +25,18 @@ namespace M { return clamp((T)0, a, (T)1); } - inline float square_root(float a) { - return sqrtf(a); - } + float square_root(float a); + double square_root(double a); - inline float square_root(double a) { - return sqrt(a); - } + float reciprocal_square_root(float a); + double reciprocal_square_root(double a); - inline float reciprocal_square_root(float a) { - return 1.0f / square_root(a); - } + float lerp (float a, float b, float t); + float ilerp(float a, float b, float v); + float remap(float in_a, float in_b, float out_a, float out_b, float v); - inline double reciprocal_square_root(double a) { - return 1.0 / square_root(a); - } + float radians(float degrees); - constexpr float lerp(float a, float b, float t) { - return (1.0f - t) * a + t * b; - } - - inline float ilerp(float a, float b, float v) { - return (v - a) / (b - a); - } - - inline float remap(float in_a, float in_b, float out_a, float out_b, float v) { - float t = ilerp(in_a, in_b, v); - return lerp(out_a, out_b, t); - } - - inline float radians(float degrees) { - return degrees * (M_PIf / 180.0f); - } - - - //----------------------------------------------- - //Vektorberechnung 2-dim union V2 { struct { float x; @@ -89,194 +57,49 @@ namespace M { float E[2]; }; - float operator [](size_t index) { - assert(index < 2); + constexpr float &operator [](size_t index) { return E[index]; } }; - //Negation von 2-dim Vektor - inline V2 operator -(V2 a) { - return { - -a.x, - -a.y - }; - } + V2 V2_(float x, float y); - //Addition 2er 2-dim Vektoren - inline V2 operator +(V2 a, V2 b) { - return { - a.x + b.x, - a.y + b.y - }; - } + V2 operator - (V2 a); + V2 operator + (V2 a, V2 b); + V2 operator +=(V2 &a, V2 b); + V2 operator - (V2 a, V2 b); + V2 operator -=(V2 &a, V2 b); - //Vektor Addition - inline V2 operator +=(V2& a, V2 b) { - return a = a + b; - } + V2 operator * (float a, V2 b); + V2 operator * (V2 a, float b); + V2 &operator *=(V2 &a, float b); + V2 operator / (float a, V2 b); + V2 operator / (V2 a, float b); + V2 &operator /=(V2 &a, float b); + V2 operator / (V2 a, V2 b); - //Subtraktion 2er 2-dim Vektoren - inline V2 operator -(V2 a, V2 b) { - return { - a.x - b.x, - a.y - b.y - }; - } + float dot (V2 a, V2 b); + V2 hadamard(V2 a, V2 b); - //Vektor Subtraktion - inline V2 operator -=(V2& a, V2 b) { - return a = a - b; - } + float length_squared (V2 a); + float length (V2 a); + float reciprocal_length(V2 a); - //Skalarmultiplikation -> erst Skalar, dann Vektor - inline V2 operator *(float a, V2 b) { - return { - a * b.x, - a * b.y - }; - } + V2 normalize (V2 a); + V2 perpendicular(V2 a); + V2 clamp01 (V2 a); - //Skalarmultiplikation -> erst Vektor, dann Skalar - inline V2 operator *(V2 a, float b) { - return { - a.x * b, - a.y * b - }; - } + V2 min(V2 a, V2 b); + V2 max(V2 a, V2 b); + float min(V2 a); + float max(V2 a); - //Skalarmultiplikation -> mit V2 Pointer - inline V2 &operator *= (V2 &a, float b) { - a = a * b; - return a; - } + V2 lerp (V2 a, V2 b, float t); + V2 lerp (V2 a, V2 b, V2 t); + V2 ilerp(V2 a, V2 b, V2 v); - //Division mit einem Skalar Oo -> Skalar geteilt durch Vektor - inline V2 operator /(float a, V2 b) { - return { - a / b.x, - a / b.y - }; - } + V2 remap(V2 in_a, V2 in_b, V2 out_a, V2 out_b, V2 v); - //Division mit einem Skalar Oo -> Vektor geteilt durch Skalar - inline V2 operator /(V2 a, float b) { - return { - a.x / b, - a.y / b - }; - } - - //Division mit einem Skalar -> 2 Vektoren - inline V2 operator /(V2 a, V2 b) { - return { - a.x / b.x, - a.y / b.y - }; - } - - //Division mit einem Skalar -> mit V2 Pointer - inline V2 &operator /= (V2 &a, float b) { - a = a / b; - return a; - } - - //Skalarprodukt - inline float dot(V2 a, V2 b) { - return a.x * b.x + a.y * b.y; - } - - //Hadamard-Produkt - inline V2 hadamard(V2 a, V2 b) { - return { - a.x * b.x, - a.y * b.y - }; - } - - //Betrag des Vektors quadrieren - inline float length_squared(V2 a) { - return dot(a, a); - } - - //Betrag eines Vektors - inline float length(V2 a) { - return square_root(length_squared(a)); - } - - //Reziproke der Länge - inline float reciprocal_length(V2 a) { - return reciprocal_square_root(length_squared(a)); - } - - //Einheitsvektor - inline V2 normalize(V2 a) { - return a * reciprocal_length(a); - } - - //Vektor der 90 - inline V2 perp(V2 a) { - return { - -a.y, - a.x - }; - } - - //clamp für 2-dim Vektor - inline V2 clamp01(V2 a) { - return { - clamp01(a.x), - clamp01(a.y) - }; - } - - //Vektor mit den kleinsten Werten 2er Vektoren - inline V2 min(V2 a, V2 b) { - return { - min(a.x, b.x), - min(a.y, b.y), - }; - } - - //Vektor mit den groessten Werten 2er Vektoren - inline V2 max(V2 a, V2 b) { - return { - max(a.x, b.x), - max(a.y, b.y), - }; - } - - //kleinster Vektor Wert - inline float min(V2 a) { - return min(a.x, a.y); - } - - //groesster Vektor Wert - inline float max(V2 a) { - return max(a.x, a.y); - } - - //Lerp mit 2 Vektoren - inline V2 lerp(V2 a, V2 b, V2 t) { - return V2{ - lerp(a.x, b.x, t.x), - lerp(a.y, b.y, t.y), - }; - } - - // - inline V2 ilerp(V2 a, V2 b, V2 v) { - return (v - a) / (b - a); - } - - // - inline V2 remap(V2 in_a, V2 in_b, V2 out_a, V2 out_b, V2 v) { - V2 t = ilerp(in_a, in_b, v); - return lerp(out_a, out_b, t); - } - - //----------------------------------------------- - //Vektorberechnung 3-dim union V3 { struct { float x; @@ -284,149 +107,96 @@ namespace M { float z; }; - //farbvektor struct { float r; float g; float b; }; - //texturvektor struct { float u; float v; float s; }; - //von V3 zu V2 ohne z struct { V2 xy; float _z; }; - //von V3 zu V2 ohne x struct { float _x; V2 yz; }; + struct { + V2 uv; + float _s; + }; + + struct { + float _u; + V2 vs; + }; + + struct { + V2 rg; + float _b; + }; + + struct { + float _r; + V2 gb; + }; + struct { float E[3]; }; - float operator [](size_t index) { - assert(index < 3); - return E[index]; + constexpr float &operator [](size_t index) { + return E[index]; } }; - //Negation von 2-dim Vektor - inline V3 operator -(V3 a) { - return { - -a.x, - -a.y, - -a.z - }; - } + V3 V3_(float x, float y, float z); + V3 V3_(V2 xy, float z); + V3 V3_(float x, V2 yz); - //Addition 2er 2-dim Vektoren - inline V3 operator +(V3 a, V3 b) { - return { - a.x + b.x, - a.y + b.y, - a.z + b.z - }; - } + V3 operator - (V3 a); + V3 operator + (V3 a, V3 b); + V3 operator +=(V3 &a, V3 b); + V3 operator - (V3 a, V3 b); + V3 operator -=(V3 &a, V3 b); - //Subtraktion 2er 2-dim Vektoren - inline V3 operator -(V3 a, V3 b) { - return { - a.x - b.x, - a.y - b.y, - a.z - b.z - }; - } + V3 operator * (float a, V3 b); + V3 operator * (V3 a, float b); + V3 operator *=(V3 &a, float b); + V3 operator / (float a, V3 b); + V3 operator / (V3 a, float b); + V3 operator /=(V3 &a, float b); + V3 operator / (V3 a, V3 b); - //Skalarmultiplikation -> erst Skalar, dann Vektor - inline V3 operator *(float a, V3 b) { - return { - a * b.x, - a * b.y, - a * b.z - }; + float dot (V3 a, V3 b); + V3 hadamard(V3 a, V3 b); + V3 cross (V3 a, V3 b); - } + float length_squared (V3 a); + float length (V3 a); + float reciprocal_length(V3 a); - //Skalarmultiplikation -> erst Vektor, dann Skalar - inline V3 operator *(V3 a, float b) { - return { - a.x * b, - a.y * b, - a.z * b - }; + V3 normalize(V3 a); + V3 clamp01 (V3 a); - } + V3 min(V3 a, V3 b); + V3 max(V3 a, V3 b); + float min(V3 a); + float max(V3 a); - //Division mit nem Skalar Oo -> Skalar geteilt durch Vektor - inline V3 operator /(float a, V3 b) { - return { - a / b.x, - a / b.y, - a / b.z - }; - } + V3 lerp (V3 a, V3 b, float t); + V3 lerp (V3 a, V3 b, V3 t); + V3 ilerp(V3 a, V3 b, V3 v); - //Division mit nem Skalar Oo -> Vektor geteilt durch Skalar - inline V3 operator /(V3 a, float b) { - return { - a.x / b, - a.y / b, - a.z / b - }; - } - - //Skalarprodukt - inline float dot(V3 a, V3 b) { - return a.x * b.x + a.y * b.y + a.z * b.z; - } - - //Hadamard-Produkt - inline V3 hadamard(V3 a, V3 b) { - return { - a.x * b.x, - a.y * b.y, - a.z * b.z - }; - } - - //Kreuzprodukt - inline V3 cross(V3 a, V3 b) { - return { - a.y * b.z - a.z * b.y, - a.z * b.x - a.x * b.z, - a.x * b.y - a.y * b.x - }; - } - - //Betrag des Vektors quadrieren - inline float length_squared(V3 a) { - return dot(a, a); - } - - //Betrag eines Vektors - inline float length(V3 a) { - return square_root(length_squared(a)); - } - - //Reziproke der Länge - inline float reciprocal_length(V3 a) { - return reciprocal_square_root(length_squared(a)); - } - - //Einheitsvektor - inline V3 normalize(V3 a) { - return a * reciprocal_length(a); - } + V3 remap(V3 in_a, V3 in_b, V3 out_a, V3 out_b, V3 v); union V4 { struct { @@ -436,7 +206,6 @@ namespace M { float w; }; - //farbvektor struct { float r; float g; @@ -444,7 +213,6 @@ namespace M { float a; }; - //texturvektor struct { float u; float v; @@ -452,52 +220,110 @@ namespace M { float t; }; - //von V4 zu V2 ohne z struct { V2 xy; V2 zw; }; - //V2 fuer Teiltexturenausgabe - struct { - V2 uv0; - V2 uv1; - }; - - //von V4 zu V2 ohne x struct { float _x; V2 yz; float _w; }; + struct { + V2 uv0; + V2 uv1; + }; + + struct { + V2 uv; + V2 st; + }; + + struct { + float _u; + V2 vs; + float _t; + }; + + struct { + V2 rg; + V2 ba; + }; + + struct { + float _r; + V2 gb; + float _a; + }; + + struct { + V3 rgb; + float _a2; + }; + + struct { + float _r2; + V3 gba; + }; + struct { float E[4]; }; - V4(V2 a, V2 b) { xy = a; zw = b; } - V4(float a, float b, float c, float d) { x = a; y = b; z = c; w = d; } - V4() {} - - float &operator [](size_t index) { - assert(index < 4); + constexpr float &operator [](size_t index) { return E[index]; } }; + V4 V4_(float x, float y, float z, float w); + V4 V4_(V2 xy, V2 zw); + V4 V4_(V2 xy, float z, float w); + V4 V4_(float x, V2 yz, float w); + V4 V4_(float x, float y, V2 zw); + V4 V4_(V3 xyz, float w); + V4 V4_(float x, V3 yzw); - //----------------------------------------------- - //2x2 Matrix + V4 operator - (V4 a); + V4 operator + (V4 a, V4 b); + V4 operator +=(V4 &a, V4 b); + V4 operator - (V4 a, V4 b); + V4 operator -=(V4 &a, V4 b); - //M2x2 m; - //m.E[0][1] - //m.V[1] + V4 operator * (float a, V4 b); + V4 operator * (V4 a, float b); + V4 operator *=(V4 &a, float b); + V4 operator / (float a, V4 b); + V4 operator / (V4 a, float b); + V4 operator /=(V4 &a, float b); + V4 operator / (V4 a, V4 b); + + float dot (V4 a, V4 b); + V4 hadamard(V4 a, V4 b); + + float length_squared (V4 a); + float length (V4 a); + float reciprocal_length(V4 a); + + V4 normalize(V4 a); + V4 clamp01 (V4 a); + + V4 min(V4 a, V4 b); + V4 max(V4 a, V4 b); + float min(V4 a); + float max(V4 a); + + V4 lerp (V4 a, V4 b, float t); + V4 lerp (V4 a, V4 b, V4 t); + V4 ilerp(V4 a, V4 b, V4 v); + + V4 remap(V4 in_a, V4 in_b, V4 out_a, V4 out_b, V4 v); - //m[1][0] union M2x2 { struct { - float x1; float x2; - float y1; float y2; + float _00; float _01; + float _10; float _11; }; struct { @@ -508,92 +334,41 @@ namespace M { V2 V[2]; }; - V2 &operator [](size_t index) { - assert(index < 2); - return V[index]; + constexpr V2 &operator [](size_t row) { + return V[row]; + } + + constexpr static M2x2 identity() { + return { + 1.0f, 0.0f, + 0.0f, 1.0f + }; } }; - //Matrix negieren - inline M2x2 operator -(M2x2 a){ - return { - -a[0][0], -a[0][1], - -a[1][0], -a[1][1] - }; - } + M2x2 M2x2_(float _00, float _01, + float _10, float _11); + M2x2 M2x2_(V2 row0, V2 row1); - //Matrix Addition - inline M2x2 operator +(M2x2 a, M2x2 b) { - return { - a[0][0] + b[0][0], a[0][1] + b[0][1], - a[1][0] + b[1][0], a[1][1] + b[1][1] - }; - } + M2x2 operator - (M2x2 a); + M2x2 operator + (M2x2 a, M2x2 b); + M2x2 operator +=(M2x2 &a, M2x2 b); + M2x2 operator - (M2x2 a, M2x2 b); + M2x2 operator -=(M2x2 &a, M2x2 b); - //Matrix Subtraktion - inline M2x2 operator -(M2x2 a, M2x2 b) { - return { - a[0][0] - b[0][0], a[0][1] - b[0][1], - a[1][0] - b[1][0], a[1][1] - b[1][1] - }; - } + M2x2 operator * (float a, M2x2 b); + M2x2 operator * (M2x2 a, float b); + M2x2 operator *=(M2x2 &a, float b); + M2x2 operator * (M2x2 a, M2x2 b); + V2 operator * (M2x2 a, V2 b); - //Matrix Skalarmultiplikation - inline M2x2 operator *(M2x2 a, float b) { - return { - a[0][0] * b, a[0][1] * b, - a[1][0] * b, a[1][1] * b - }; - } + M2x2 transpose(M2x2 a); - //Matrix Skalarmultiplikation - inline M2x2 operator *(float a, M2x2 b) { - return { - a * b[0][0], a * b[0][1], - a * b[1][0], a * b[1][1] - }; - } - - //Matrix Multiplikation - inline M2x2 operator *(M2x2 a, M2x2 b) { - return { - a[0][0] * b[0][0] + a[0][1] * b[1][0], a[0][0] * b[0][1] + a[0][1] * b[1][1], - a[1][0] * b[0][0] + a[1][1] * b[1][0], a[1][0] * b[0][1] + a[1][1] * b[1][1] - }; - } - - //Matrix * Vektor - inline V2 operator *(M2x2 a, V2 b) { - return { - a[0][0] * b[0] + a[0][1] * b[1], - a[1][0] * b[0] + a[1][1] * b[1], - }; - } - - //Matrix Transponieren - inline M2x2 transpose(M2x2 a) { - return { - a[0][0], a[1][0], - a[0][1], a[1][1] - }; - } - - //Einheitsmatrix (oder Identitätsmatrix) - constexpr inline M2x2 identityM2x2() { - return { - 1.0f, 0.0f, - 0.0f, 1.0f - }; - } - - - //----------------------------------------------- - //3x3 Matrix union M3x3 { struct { - float x1; float x2; float x3; - float y1; float y2; float y3; - float z1; float z2; float z3; + float _00; float _01; float _02; + float _10; float _11; float _12; + float _20; float _21; float _22; }; struct { @@ -603,162 +378,45 @@ namespace M { struct { V3 V[3]; }; - - V3& operator [](size_t index) { - assert(index < 3); - return V[index]; + constexpr V3 &operator [](size_t row) { + return V[row]; + } + + constexpr static M3x3 identity() { + return { + 1.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 1.0f + }; } - }; - //Matrix negieren - inline M3x3 operator -(M3x3 a) { - return { - -a[0][0], -a[0][1], -a[0][1], - -a[1][0], -a[1][1], -a[1][2], - -a[2][0], -a[2][1], -a[2][2] - }; - } + M3x3 M3x3_(float _00, float _01, float _02, + float _10, float _11, float _12, + float _20, float _21, float _22); + M3x3 M3x3_(V3 row0, V3 row1, V3 row2); - //Matrix Addition - inline M3x3 operator +(M3x3 a, M3x3 b) { - return { - a[0][0] + b[0][0], a[0][1] + b[0][1], a[0][2] + b[0][2], - a[1][0] + b[1][0], a[1][1] + b[1][1], a[1][2] + b[1][2], - a[2][0] + b[2][0], a[2][1] + b[2][1], a[2][2] + b[2][2] - }; - } + M3x3 operator - (M3x3 a); + M3x3 operator + (M3x3 a, M3x3 b); + M3x3 operator +=(M3x3 &a, M3x3 b); + M3x3 operator - (M3x3 a, M3x3 b); + M3x3 operator -=(M3x3 &a, M3x3 b); - //Matrix Subtraktion - inline M3x3 operator -(M3x3 a, M3x3 b) { - return { - a[0][0] - b[0][0], a[0][1] - b[0][1], a[0][2] - b[0][2], - a[1][0] - b[1][0], a[1][1] - b[1][1], a[1][2] - b[1][2], - a[2][0] - b[2][0], a[2][1] - b[2][1], a[2][2] - b[2][2] - }; - } + M3x3 operator * (float a, M3x3 b); + M3x3 operator * (M3x3 a, float b); + M3x3 operator *=(M3x3 &a, float b); + M3x3 operator * (M3x3 a, M3x3 b); + V3 operator * (M3x3 a, V3 b); - //Matrix Skalarmultiplikation - inline M3x3 operator *(M3x3 a, float b) { - return { - a[0][0] * b, a[0][1] * b, a[0][2] * b, - a[1][0] * b, a[1][1] * b, a[1][2] * b, - a[2][0] * b, a[2][1] * b, a[2][2] * b - }; - } - - //Matrix Skalarmultiplikation - inline M3x3 operator *(float a, M3x3 b) { - return { - a * b[0][0], a * b[0][1], a * b[0][2], - a * b[1][0], a * b[1][1], a * b[1][2], - a * b[2][0], a * b[2][1], a * b[2][2] - }; - } - - //Matrix Multiplikation - inline M3x3 operator *(M3x3 a, M3x3 b) { - return { - a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0], a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1], a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2], - a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0], a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1], a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[0][2] * b[2][2], - a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0], a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1], a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[0][2] * b[2][2] - }; - } - - //Matrix * V2 - inline V2 operator *(M3x3 a, V2 b) { - return { - b.x * a[0][0] + b.y * a[0][1] + 1.0f * a[0][2], - b.x * a[1][0] + b.y * a[1][1] + 1.0f * a[1][2], - }; - } - - //Matrix * V3 - inline V3 operator *(M3x3 a, V3 b) { - return { - b.x * a[0][0] + b.y * a[0][1] + b.z * a[0][2], - b.x * a[1][0] + b.y * a[1][1] + b.z * a[1][2], - b.x * a[2][0] + b.y * a[2][1] + b.z * a[2][2] - }; - } - - - //Matrix transponieren - inline M3x3 transpose(M3x3 a) { - return { - a[0][0], a[1][0], a[2][0], - a[0][1], a[1][1], a[2][1], - a[0][2], a[1][2], a[2][2] - }; - } - - //Einheitsmatrix (oder Identitätsmatrix) - inline M3x3 identityM3x3() { - return { - 1.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 1.0f - }; - } - - - - //----------------------------------------------- - //m128i - struct m128i { - __m128i val; - }; - - inline __m128i operator &(m128i a, m128i b) { - return _mm_and_si128(a.val, b.val); - } - - inline __m128i operator |(m128i a, m128i b) { - return _mm_or_si128(a.val, b.val); - } - - inline __m128i operator >>(m128i a, int b) { - return _mm_srli_epi32(a.val, b); - } - - inline __m128i operator <<(m128i a, int b) { - return _mm_slli_epi32(a.val, b); - } - - - //----------------------------------------------- - //m128 - struct m128 { - __m128 val; - }; - - inline __m128 operator +(m128 a, m128 b) { - return _mm_mul_ps(a.val, b.val); - } - - inline __m128 operator *(m128 a, m128 b) { - return _mm_mul_ps(a.val, b.val); - } - - inline __m128 operator *(float a, m128 b) { - return _mm_mul_ps(_mm_set1_ps(a), b.val); - } - - inline __m128 square_root(__m128 a) { - return _mm_sqrt_ps(a); - } - - inline __m128 operator /(m128 a, m128 b) { - return _mm_div_ps(a.val, b.val); - } + M3x3 transpose(M3x3 a); union M4x4 { struct { - float x1; float x2; float x3; float x4; - float y1; float y2; float y3; float y4; - float z1; float z2; float z3; float z4; - float w1; float w2; float w3; float w4; + float _00; float _01; float _02; float _03; + float _10; float _11; float _12; float _13; + float _20; float _21; float _22; float _23; + float _30; float _31; float _32; float _33; }; struct { @@ -769,59 +427,40 @@ namespace M { V4 V[4]; }; - V4& operator [](size_t index) { - assert(index < 4); - return V[index]; + constexpr V4 &operator [](size_t row) { + return V[row]; + } + + constexpr static M4x4 identity() { + return { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f + }; } }; - inline V4 operator*(M4x4 a, V4 b) { - return { - b.x * a[0][0] + b.y * a[0][1] + b.z * a[0][2] + b.w * a[0][3], - b.x * a[1][0] + b.y * a[1][1] + b.z * a[1][2] + b.w * a[1][3], - b.x * a[2][0] + b.y * a[2][1] + b.z * a[2][2] + b.w * a[2][3], - b.x * a[3][0] + b.y * a[3][1] + b.z * a[3][2] + b.w * a[3][3], - }; - } + M4x4 M4x4_(float _00, float _01, float _02, float _03, + float _10, float _11, float _12, float _13, + float _20, float _21, float _22, float _23, + float _30, float _31, float _32, float _33); + M4x4 M4x4_(V4 row0, V4 row1, V4 row2, V4 row3); - inline M4x4 operator*(M4x4 a, M4x4 b) { - return { - a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0] + a[0][3] * b[3][0], a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1] + a[0][3] * b[3][1], a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2] + a[0][3] * b[3][2], a[0][0] * b[0][3] + a[0][1] * b[1][3] + a[0][2] * b[2][3] + a[0][3] * b[3][3], - a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0] + a[1][3] * b[3][0], a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1] + a[1][3] * b[3][1], a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2] + a[1][3] * b[3][2], a[1][0] * b[0][3] + a[1][1] * b[1][3] + a[1][2] * b[2][3] + a[1][3] * b[3][3], - a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0] + a[2][3] * b[3][0], a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1] + a[2][3] * b[3][1], a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2] + a[2][3] * b[3][2], a[2][0] * b[0][3] + a[2][1] * b[1][3] + a[2][2] * b[2][3] + a[2][3] * b[3][3], - a[3][0] * b[0][0] + a[3][1] * b[1][0] + a[3][2] * b[2][0] + a[3][3] * b[3][0], a[3][0] * b[0][1] + a[3][1] * b[1][1] + a[3][2] * b[2][1] + a[3][3] * b[3][1], a[3][0] * b[0][2] + a[3][1] * b[1][2] + a[3][2] * b[2][2] + a[3][3] * b[3][2], a[3][0] * b[0][3] + a[3][1] * b[1][3] + a[3][2] * b[2][3] + a[3][3] * b[3][3], - }; - } + M4x4 operator - (M4x4 a); + M4x4 operator + (M4x4 a, M4x4 b); + M4x4 operator +=(M4x4 &a, M4x4 b); + M4x4 operator - (M4x4 a, M4x4 b); + M4x4 operator -=(M4x4 &a, M4x4 b); - inline M4x4 transpose(M4x4 a) { - return { - a[0][0], a[1][0], a[2][0], a[3][0], - a[0][1], a[1][1], a[2][1], a[3][1], - a[0][2], a[1][2], a[2][2], a[3][2], - a[0][3], a[1][3], a[2][3], a[3][3], - }; - } + M4x4 operator * (float a, M4x4 b); + M4x4 operator * (M4x4 a, float b); + M4x4 operator *=(M4x4 &a, float b); + M4x4 operator * (M4x4 a, M4x4 b); + V4 operator * (M4x4 a, V4 b); - inline M4x4 projection(float fovy, float aspect, float near) { - float g = 1.0 / tanf(fovy * 0.5); - - return { - g / aspect, 0, 0, 0, - 0, g, 0, 0, - 0, 0, 0, near, - 0, 0, 1, 0, - }; - } - - inline M4x4 inverse_projection(float fovy, float aspect, float near) { - float g = 1.0 / tanf(fovy * 0.5); - - return { - aspect / g, 0, 0, 0, - 0, 1 / g, 0, 0, - 0, 0, 0, 1, - 0, 0, 1 / near, 0, - }; - } + M4x4 transpose(M4x4 a); + M4x4 projection (float fovy, float aspect, float near); + M4x4 inverse_projection(float fovy, float aspect, float near); }