#pragma once // math2d — primitive 2D types used across gamedev stack (issue 0072b). // Pure value types. No allocations, no virtual, trivial copy. #include namespace fn::math2d { struct Vec2 { float x = 0.0f; float y = 0.0f; constexpr Vec2() = default; constexpr Vec2(float xv, float yv) : x(xv), y(yv) {} constexpr Vec2 operator+(Vec2 b) const { return {x + b.x, y + b.y}; } constexpr Vec2 operator-(Vec2 b) const { return {x - b.x, y - b.y}; } constexpr Vec2 operator*(float s) const { return {x * s, y * s}; } constexpr Vec2 operator/(float s) const { return {x / s, y / s}; } constexpr Vec2& operator+=(Vec2 b) { x += b.x; y += b.y; return *this; } constexpr Vec2& operator-=(Vec2 b) { x -= b.x; y -= b.y; return *this; } constexpr Vec2& operator*=(float s) { x *= s; y *= s; return *this; } float length() const { return std::sqrt(x * x + y * y); } constexpr float length_sq() const { return x * x + y * y; } Vec2 normalized() const { float l = length(); return l > 0.0f ? Vec2{x / l, y / l} : Vec2{0.0f, 0.0f}; } static constexpr float dot(Vec2 a, Vec2 b) { return a.x * b.x + a.y * b.y; } static constexpr float cross(Vec2 a, Vec2 b) { return a.x * b.y - a.y * b.x; } }; struct Rect { float x = 0.0f; float y = 0.0f; float w = 0.0f; float h = 0.0f; constexpr Rect() = default; constexpr Rect(float xv, float yv, float wv, float hv) : x(xv), y(yv), w(wv), h(hv) {} constexpr float right() const { return x + w; } constexpr float bottom() const { return y + h; } constexpr Vec2 center() const { return {x + w * 0.5f, y + h * 0.5f}; } constexpr Vec2 min() const { return {x, y}; } constexpr Vec2 max() const { return {x + w, y + h}; } constexpr bool contains(Vec2 p) const { return p.x >= x && p.x < x + w && p.y >= y && p.y < y + h; } constexpr bool overlaps(Rect b) const { return !(b.x >= x + w || b.x + b.w <= x || b.y >= y + h || b.y + b.h <= y); } }; struct Color { float r = 1.0f; float g = 1.0f; float b = 1.0f; float a = 1.0f; constexpr Color() = default; constexpr Color(float rv, float gv, float bv, float av = 1.0f) : r(rv), g(gv), b(bv), a(av) {} static constexpr Color white() { return {1, 1, 1, 1}; } static constexpr Color black() { return {0, 0, 0, 1}; } static constexpr Color transparent() { return {0, 0, 0, 0}; } static Color rgba(unsigned char r8, unsigned char g8, unsigned char b8, unsigned char a8 = 255) { return {r8 / 255.0f, g8 / 255.0f, b8 / 255.0f, a8 / 255.0f}; } static Color hex(unsigned int packed) { return Color::rgba((packed >> 24) & 0xFF, (packed >> 16) & 0xFF, (packed >> 8) & 0xFF, packed & 0xFF); } }; } // namespace fn::math2d