42c14fae59
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
84 lines
2.8 KiB
C++
84 lines
2.8 KiB
C++
#pragma once
|
|
|
|
// math2d — primitive 2D types used across gamedev stack (issue 0072b).
|
|
// Pure value types. No allocations, no virtual, trivial copy.
|
|
|
|
#include <cmath>
|
|
|
|
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
|