Vec2 GetSize(Rect2 r) { Vec2 result = {r.max.x - r.min.x, r.max.y - r.min.y}; return result; } Vec2 GetSizeF(Rect2I r) { Vec2 result = {(float)(r.max.x - r.min.x), (float)(r.max.y - r.min.y)}; return result; } Vec2 ToVec2(Vec2I v) { return {(float)v.x, (float)v.y}; } Vec2I ToVec2I(Vec2 v) { return {(Int)v.x, (Int)v.y}; } Rect2I ToRect2I(Rect2 r) { return {ToVec2I(r.min), ToVec2I(r.max)}; } Rect2 ToRect2(Rect2I r) { return {ToVec2(r.min), ToVec2(r.max)}; } // clang-format off Rect2 operator-(Rect2 r, Rect2 value) { return { {r.min.x - value.min.x, r.min.y - value.min.y}, {r.max.x - value.max.x, r.max.y - value.max.y} }; } Rect2 operator+(Rect2 r, Rect2 value) { return { {r.min.x + value.min.x, r.min.y + value.min.y}, {r.max.x + value.max.x, r.max.y + value.max.y} }; } Rect2 operator*(Rect2 r, Rect2 value) { return { {r.min.x * value.min.x, r.min.y * value.min.y}, {r.max.x * value.max.x, r.max.y * value.max.y} }; } Rect2 operator/(Rect2 r, Rect2 value) { return { {r.min.x / value.min.x, r.min.y / value.min.y}, {r.max.x / value.max.x, r.max.y / value.max.y} }; } Rect2 operator-(Rect2 r, Vec2 value) { return { {r.min.x - value.x, r.min.y - value.y}, {r.max.x - value.x, r.max.y - value.y} }; } Rect2 operator+(Rect2 r, Vec2 value) { return { {r.min.x + value.x, r.min.y + value.y}, {r.max.x + value.x, r.max.y + value.y} }; } Rect2 operator*(Rect2 r, Vec2 value) { return { {r.min.x * value.x, r.min.y * value.y}, {r.max.x * value.x, r.max.y * value.y} }; } Rect2 operator/(Rect2 r, Vec2 value) { return { {r.min.x / value.x, r.min.y / value.y}, {r.max.x / value.x, r.max.y / value.y} }; } Rect2 operator-(Vec2 value, Rect2 r) { return { {r.min.x - value.x, r.min.y - value.y}, {r.max.x - value.x, r.max.y - value.y} }; } Rect2 operator+(Vec2 value, Rect2 r) { return { {r.min.x + value.x, r.min.y + value.y}, {r.max.x + value.x, r.max.y + value.y} }; } Rect2 operator*(Vec2 value, Rect2 r) { return { {r.min.x * value.x, r.min.y * value.y}, {r.max.x * value.x, r.max.y * value.y} }; } Rect2 operator/(Vec2 value, Rect2 r) { return { {r.min.x / value.x, r.min.y / value.y}, {r.max.x / value.x, r.max.y / value.y} }; } Rect2 operator-(Rect2 r, float value) { return { {r.min.x - value, r.min.y - value}, {r.max.x - value, r.max.y - value} }; } Rect2 operator+(Rect2 r, float value) { return { {r.min.x + value, r.min.y + value}, {r.max.x + value, r.max.y + value} }; } Rect2 operator*(Rect2 r, float value) { return { {r.min.x * value, r.min.y * value}, {r.max.x * value, r.max.y * value} }; } Rect2 operator/(Rect2 r, float value) { return { {r.min.x / value, r.min.y / value}, {r.max.x / value, r.max.y / value} }; } Rect2 operator-(float value, Rect2 r) { return { {r.min.x - value, r.min.y - value}, {r.max.x - value, r.max.y - value} }; } Rect2 operator+(float value, Rect2 r) { return { {r.min.x + value, r.min.y + value}, {r.max.x + value, r.max.y + value} }; } Rect2 operator*(float value, Rect2 r) { return { {r.min.x * value, r.min.y * value}, {r.max.x * value, r.max.y * value} }; } Rect2 operator/(float value, Rect2 r) { return { {r.min.x / value, r.min.y / value}, {r.max.x / value, r.max.y / value} }; } Rect2 operator-=(Rect2 &r, Rect2 value) { r = r - value; return r; } Rect2 operator+=(Rect2 &r, Rect2 value) { r = r + value; return r; } Rect2 operator*=(Rect2 &r, Rect2 value) { r = r * value; return r; } Rect2 operator/=(Rect2 &r, Rect2 value) { r = r / value; return r; } Rect2 operator-=(Rect2 &r, Vec2 value) { r = r - value; return r; } Rect2 operator+=(Rect2 &r, Vec2 value) { r = r + value; return r; } Rect2 operator*=(Rect2 &r, Vec2 value) { r = r * value; return r; } Rect2 operator/=(Rect2 &r, Vec2 value) { r = r / value; return r; } Rect2 operator-=(Rect2 &r, float value) { r = r - value; return r; } Rect2 operator+=(Rect2 &r, float value) { r = r + value; return r; } Rect2 operator*=(Rect2 &r, float value) { r = r * value; return r; } Rect2 operator/=(Rect2 &r, float value) { r = r / value; return r; } bool operator==(Rect2 a, Rect2 b) { bool result = a.min.x == b.min.x && a.min.y == b.min.y && a.max.x == b.max.x && a.max.y == b.max.y; return result; } bool operator!=(Rect2 a, Rect2 b) { bool result = !(a == b); return result; } Vec2 operator-(Vec2 a, Vec2 b) { return {a.x - b.x, a.y - b.y}; } Vec2 operator+(Vec2 a, Vec2 b) { return {a.x + b.x, a.y + b.y}; } Vec2 operator*(Vec2 a, Vec2 b) { return {a.x * b.x, a.y * b.y}; } Vec2 operator/(Vec2 a, Vec2 b) { return {a.x / b.x, a.y / b.y}; } Vec2 operator-(Vec2 a, float b) { return {a.x - b, a.y - b}; } Vec2 operator+(Vec2 a, float b) { return {a.x + b, a.y + b}; } Vec2 operator*(Vec2 a, float b) { return {a.x * b, a.y * b}; } Vec2 operator/(Vec2 a, float b) { return {a.x / b, a.y / b}; } Vec2 operator-(float b, Vec2 a) { return {a.x - b, a.y - b}; } Vec2 operator+(float b, Vec2 a) { return {a.x + b, a.y + b}; } Vec2 operator*(float b, Vec2 a) { return {a.x * b, a.y * b}; } Vec2 operator/(float b, Vec2 a) { return {a.x / b, a.y / b}; } Vec2 operator-=(Vec2 &a, Vec2 b) { a = a - b; return a; } Vec2 operator+=(Vec2 &a, Vec2 b) { a = a + b; return a; } Vec2 operator*=(Vec2 &a, Vec2 b) { a = a * b; return a; } Vec2 operator/=(Vec2 &a, Vec2 b) { a = a / b; return a; } Vec2 operator-=(Vec2 &a, float b) { a = a - b; return a; } Vec2 operator+=(Vec2 &a, float b) { a = a + b; return a; } Vec2 operator*=(Vec2 &a, float b) { a = a * b; return a; } Vec2 operator/=(Vec2 &a, float b) { a = a / b; return a; } // clang-format on Rect2 Rect0Size(float x, float y) { Rect2 rect = {0, 0, x, y}; return rect; } Rect2 Rect2FromSize(Vec2 pos, Vec2 size) { Rect2 result = {}; result.min = pos; result.max = pos + size; return result; } Rect2 Rect2MidHalf(Vec2 mid, Vec2 half_size) { Rect2 result = {}; result.min = mid - half_size; result.max = mid + half_size; return result; } Rect2 Shrink(Rect2 result, float v) { result.min.x += v; result.max.x -= v; result.min.y += v; result.max.y -= v; return result; } Rect2 ShrinkVertical(Rect2 result, float v) { result.min.y += v; result.max.y -= v; return result; } Rect2 ShrinkHorizontal(Rect2 result, float v) { result.min.x += v; result.max.x -= v; return result; } Vec2 GetMid(Rect2 r) { Vec2 size = GetSize(r); size.x /= 2.f; size.y /= 2.f; Vec2 result = r.min + size; return result; } Rect2 CutLeft(Rect2 *r, float value) { float minx = r->min.x; r->min.x = Min(r->min.x + value, r->max.x); Rect2 result = { { minx, r->min.y}, {r->min.x, r->max.y} }; return result; } Rect2 CutRight(Rect2 *r, float value) { float maxx = r->max.x; r->max.x = Max(r->min.x, r->max.x - value); Rect2 result = { {r->max.x, r->min.y}, { maxx, r->max.y}, }; return result; } // Y is up Rect2 CutBottom(Rect2 *r, float value) { float maxy = r->max.y; r->max.y = Max(r->min.y, r->max.y - value); Rect2 result = { {r->min.x, r->max.y}, {r->max.x, maxy}, }; return result; } // Y is up Rect2 CutTop(Rect2 *r, float value) { float miny = r->min.y; r->min.y = Min(r->min.y + value, r->max.y); Rect2 result = { {r->min.x, miny}, {r->max.x, r->min.y}, }; return result; } float SafeDivide(float a, float b) { if (b == 0.f) { return 0.f; } return a / b; } bool AreOverlapping(Vec2 point, Rect2 rec) { bool result = (point.x >= rec.min.x) && (point.x < rec.max.x) && (point.y >= rec.min.y) && (point.y < rec.max.y); return result; }