restructured project to match a more standard cmake setup

This commit is contained in:
Noel Berry
2020-12-31 13:43:23 -08:00
parent c841bd82a1
commit 241d863ac4
97 changed files with 233 additions and 264 deletions

156
src/math/calc.cpp Normal file
View File

@ -0,0 +1,156 @@
#include <blah/math/calc.h>
#include <math.h>
#include <stdlib.h>
using namespace Blah;
float Calc::rand_float(float min, float maxExc)
{
return min + rand_float(maxExc - min);
}
float Calc::rand_float(float maxExc)
{
return (rand() / (float)RAND_MAX) * maxExc;
}
int Calc::rand_int(int min, int maxExc)
{
return min + rand_int(maxExc - min);
}
int Calc::rand_int(int maxExc)
{
if (maxExc <= 0)
return 0;
return rand() % maxExc;
}
int Calc::rand_int()
{
return rand();
}
float Calc::approach(float t, float target, float maxDelta)
{
return t < target ? min(t + maxDelta, target) : max(t - maxDelta, target);
}
float Calc::clamp(float t, float min, float max)
{
return t < min ? min : (t > max ? max : t);
}
int Calc::clamp_int(int t, int min, int max)
{
return t < min ? min : (t > max ? max : t);
}
float Calc::map(float t, float old_min, float old_max, float new_min, float new_max)
{
return new_min + ((t - old_min) / (old_max - old_min)) * (new_max - new_min);
}
float Calc::clamped_map(float t, float old_min, float old_max, float new_min, float new_max)
{
return map(Calc::clamp(t, old_min, old_max), old_min, old_max, new_min, new_max);
}
int Calc::sign(int x)
{
return (x < 0 ? -1 : (x > 0 ? 1 : 0));
}
float Calc::sign(float x)
{
return (x < 0 ? -1.0f : (x > 0 ? 1.0f : 0.0f));
}
int Calc::abs(int x)
{
return x < 0 ? -x : x;
}
float Calc::abs(float x)
{
return x < 0 ? -x : x;
}
float Calc::round(float x)
{
return roundf(x);
}
float Calc::floor(float x)
{
return floorf(x);
}
float Calc::ceiling(float x)
{
return ceilf(x);
}
float Calc::mod(float x, float m)
{
return x - (int)(x / m) * m;
}
float Calc::sin(float x)
{
return sinf(x);
}
float Calc::cos(float x)
{
return cosf(x);
}
float Calc::atan2(float y, float x)
{
return atan2f(y, x);
}
float Calc::pow(float x, float n)
{
return powf(x, n);
}
float Calc::sqrt(float x)
{
return sqrtf(x);
}
float Calc::snap(float val, float interval)
{
if (val > 0)
return ((int)((val + interval / 2) / interval)) * interval;
else
return ((int)((val - interval / 2) / interval)) * interval;
}
float Calc::angle_diff(float radians_a, float radians_b)
{
return mod((radians_b - radians_a) + PI, TAU) - PI;
}
float Calc::angle_lerp(float radians_a, float radians_b, float p)
{
const auto shortest_angle = mod(mod(radians_b - radians_a, TAU) + (TAU + PI), TAU) - PI;
return radians_a + mod(shortest_angle * p, TAU);
}
float Calc::lerp(float a, float b, float t)
{
return a + (b - a) * t;
}
bool Calc::is_big_endian()
{
return (*((short*)"AB") == 0x4243);
}
bool Calc::is_little_endian()
{
return (*((short*)"AB") != 0x4243);
}

11
src/math/circle.cpp Normal file
View File

@ -0,0 +1,11 @@
#include <blah/math/circle.h>
#include <blah/math/calc.h>
using namespace Blah;
void Circle::project(const Vec2& axis, float* min, float* max) const
{
*min = Vec2::dot(center - axis * radius, axis);
*max = Vec2::dot(center + axis * radius, axis);
}

156
src/math/color.cpp Normal file
View File

@ -0,0 +1,156 @@
#include <blah/math/color.h>
#include <blah/math/vec4.h>
using namespace Blah;
char const hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
#define LT_HEX_VALUE(n) ((n >= '0' && n <= '9') ? (n - '0') : ((n >= 'A' && n <= 'F') ? (10 + n - 'A') : ((n >= 'a' && n <= 'f') ? (10 + n - 'a') : 0)))
Color::Color()
: r(0), g(0), b(0), a(0) {}
Color::Color(int rgb) :
r((uint8_t)((rgb & 0xFF0000) >> 16)),
g((uint8_t)((rgb & 0x00FF00) >> 8)),
b((uint8_t)(rgb & 0x0000FF)),
a(255) {}
Color::Color(int rgb, float alpha) :
r((int)(((uint8_t)((rgb & 0xFF0000) >> 16)) * alpha)),
g((int)(((uint8_t)((rgb & 0x00FF00) >> 8)) * alpha)),
b((int)(((uint8_t)(rgb & 0x0000FF)) * alpha)),
a((int)(255 * alpha)) {}
Color::Color(uint8_t r, uint8_t g, uint8_t b)
: r(r), g(g), b(b), a(255) {}
Color::Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
: r(r), g(g), b(b), a(a) {}
Color::Color(const char* value) : r(0), g(0), b(0), a(255)
{
int length = 0;
while (value[length] != '\0' && length < 10)
length ++;
int offset = 0;
if (length > 0 && value[0] == '#')
offset = 1;
else if (length >= 1 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
offset = 2;
if (length - offset >= 8)
a = (LT_HEX_VALUE(value[offset + 6]) << 4) + LT_HEX_VALUE(value[offset + 7]);
if (length - offset >= 6)
{
r = (LT_HEX_VALUE(value[offset + 0]) << 4) + LT_HEX_VALUE(value[offset + 1]);
g = (LT_HEX_VALUE(value[offset + 2]) << 4) + LT_HEX_VALUE(value[offset + 3]);
b = (LT_HEX_VALUE(value[offset + 4]) << 4) + LT_HEX_VALUE(value[offset + 5]);
}
}
void Color::premultiply()
{
r = r * a / 255;
g = g * a / 255;
b = b * a / 255;
}
uint32_t Color::to_rgba() const
{
return
((uint32_t)r << 24) |
((uint32_t)g << 16) |
((uint32_t)b << 8) |
(uint32_t)a;
}
Vec4 Color::to_vec4() const
{
return Vec4(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
}
void Color::to_hex_rgba(char* buffer) const
{
buffer[0] = hex[(r & 0xF0) >> 4];
buffer[1] = hex[(r & 0x0F) >> 0];
buffer[2] = hex[(g & 0xF0) >> 4];
buffer[3] = hex[(g & 0x0F) >> 0];
buffer[4] = hex[(b & 0xF0) >> 4];
buffer[5] = hex[(b & 0x0F) >> 0];
buffer[6] = hex[(a & 0xF0) >> 4];
buffer[7] = hex[(a & 0x0F) >> 0];
}
void Color::to_hex_rgb(char* buffer) const
{
buffer[0] = hex[(r & 0xF0) >> 4];
buffer[1] = hex[(r & 0x0F) >> 0];
buffer[2] = hex[(g & 0xF0) >> 4];
buffer[3] = hex[(g & 0x0F) >> 0];
buffer[4] = hex[(b & 0xF0) >> 4];
buffer[5] = hex[(b & 0x0F) >> 0];
}
Color Color::from_rgba(uint32_t value)
{
return
{
(uint8_t)((value & 0xFF000000) >> 24),
(uint8_t)((value & 0x00FF0000) >> 16),
(uint8_t)((value & 0x0000FF00) >> 8),
(uint8_t)((value & 0x000000FF))
};
}
Color Color::from_rgb(uint32_t value)
{
return
{
(uint8_t)((value & 0xFF0000) >> 16),
(uint8_t)((value & 0x00FF00) >> 8),
(uint8_t)((value & 0x0000FF))
};
}
Color Color::lerp(Color a, Color b, float amount)
{
if (amount < 0) amount = 0;
if (amount > 1) amount = 1;
return Color(
(uint8_t)(a.r + (b.r - a.r) * amount),
(uint8_t)(a.g + (b.g - a.g) * amount),
(uint8_t)(a.b + (b.b - a.b) * amount),
(uint8_t)(a.a + (b.a - a.a) * amount)
);
}
Color Color::operator*(float multiply) const
{
return Color(
(int)(r * multiply),
(int)(g * multiply),
(int)(b * multiply),
(int)(a * multiply));
}
Color& Color::operator= (const int rgb)
{
r = (uint8_t)((rgb & 0xFF0000) >> 16);
g = (uint8_t)((rgb & 0x00FF00) >> 8);
b = (uint8_t)(rgb & 0x0000FF);
a = 255;
return *this;
}
const Color Color::transparent = Color(0, 0, 0, 0);
const Color Color::white = Color(255, 255, 255, 255);
const Color Color::black = Color(0, 0, 0, 255);
const Color Color::red = Color(255, 0, 0, 255);
const Color Color::green = Color(0, 255, 0, 255);
const Color Color::blue = Color(0, 0, 255, 255);
const Color Color::yellow = Color(255, 255, 0, 255);
const Color Color::purple = Color(255, 0, 255, 255);
const Color Color::teal = Color(0, 255, 255, 255);

157
src/math/line.cpp Normal file
View File

@ -0,0 +1,157 @@
#include <blah/math/line.h>
#include <blah/math/rect.h>
#include <blah/math/vec2.h>
#include <blah/math/calc.h>
using namespace Blah;
Line::Line(float x0, float y0, float x1, float y1)
{
a.x = x0;
a.y = y0;
b.x = x1;
b.y = y1;
}
Line::Line(const Vec2& start, const Vec2& end)
: a(start), b(end) {}
Rect Line::bounds() const
{
Vec2 pos = Vec2(Calc::min(a.x, b.x), Calc::min(a.y, b.y));
return Rect(
pos,
Vec2(Calc::max(a.x, b.x) - pos.x, Calc::max(a.y, b.y) - pos.y)
);
}
Vec2 Line::closest_point(const Vec2& pt) const
{
Vec2 v = b - a;
Vec2 w = pt - a;
float t = Vec2::dot(w, v) / Vec2::dot(v, v);
t = Calc::clamp(t, 0, 1);
return v * t + a;
}
bool Line::intersects(const Rect& rect) const
{
char ca = rect.get_sector(a);
char cb = rect.get_sector(b);
if (ca == cb || (ca & cb) != 0)
return false;
char both = ca | cb;
// top
if ((both & 0b0100) != 0 && intersects(rect.top_line()))
return true;
// bottom
if ((both & 0b1000) != 0 && intersects(rect.bottom_line()))
return true;
// left
if ((both & 0b0001) != 0 && intersects(rect.left_line()))
return true;
// right
if ((both & 0b0010) != 0 && intersects(rect.right_line()))
return true;
return false;
}
bool Line::intersects(const Rect& rect, Vec2* out_intersection_point) const
{
char ca = rect.get_sector(a);
char cb = rect.get_sector(b);
if (ca == cb || (ca & cb) != 0)
return false;
char both = ca | cb;
// top
if ((both & 0b0100) != 0 && intersects(rect.top_line(), out_intersection_point))
return true;
// bottom
if ((both & 0b1000) != 0 && intersects(rect.bottom_line(), out_intersection_point))
return true;
// left
if ((both & 0b0001) != 0 && intersects(rect.left_line(), out_intersection_point))
return true;
// right
if ((both & 0b0010) != 0 && intersects(rect.right_line(), out_intersection_point))
return true;
return false;
}
bool Line::intersects(const Line& line) const
{
Vec2 e = b - a;
Vec2 d = line.b - line.a;
float e_dot_d_perp = e.x * d.y - e.y * d.x;
// if e dot d == 0, it means the lines are parallel
// so have infinite intersection points
if (e_dot_d_perp < 0.0001 && e_dot_d_perp > -0.0001)
return false;
Vec2 c = line.a - a;
float t = (c.x * d.y - c.y * d.x) / e_dot_d_perp;
if (t < 0 || t > 1)
return false;
float u = (c.x * e.y - c.y * e.x) / e_dot_d_perp;
if (u < 0 || u > 1)
return false;
return true;
}
bool Line::intersects(const Line& line, Vec2* intersection_point) const
{
Vec2 e = b - a;
Vec2 d = line.b - line.a;
float e_dot_d_perp = e.x * d.y - e.y * d.x;
// if e dot d == 0, it means the lines are parallel
// so have infinite intersection points
if (e_dot_d_perp < 0.0001 && e_dot_d_perp > -0.0001)
return false;
Vec2 c = line.a - a;
float t = (c.x * d.y - c.y * d.x) / e_dot_d_perp;
if (t < 0 || t > 1)
return false;
float u = (c.x * e.y - c.y * e.x) / e_dot_d_perp;
if (u < 0 || u > 1)
return false;
Vec2 i = (e * t) + a;
intersection_point->x = i.x;
intersection_point->y = i.y;
return true;
}
void Line::project(const Vec2& axis, float* min, float* max) const
{
float dot = a.x * axis.x + a.y * axis.y;
*min = dot;
*max = dot;
dot = b.x * axis.x + b.y * axis.y;
*min = Calc::min(dot, *min);
*max = Calc::max(dot, *max);
}
Line Line::operator +(const Vec2& rhs) const { return Line(a + rhs, b + rhs); }
Line Line::operator -(const Vec2& rhs) const { return Line(a - rhs, b - rhs); }

187
src/math/mat3x2.cpp Normal file
View File

@ -0,0 +1,187 @@
#include <blah/math/mat3x2.h>
#include <blah/math/vec2.h>
#include <string.h>
#include <math.h>
using namespace Blah;
Mat3x2::Mat3x2()
: m11(0), m12(0), m21(0), m22(0), m31(0), m32(0) {}
Mat3x2::Mat3x2(float m11, float m12, float m21, float m22, float m31, float m32)
: m11(m11), m12(m12), m21(m21), m22(m22), m31(m31), m32(m32) {}
Mat3x2 Mat3x2::invert() const
{
auto det = (m11 * m22) - (m21 * m12);
auto invDet = 1.0f / det;
return Mat3x2
{
m22 * invDet,
-m12 * invDet,
-m21 * invDet,
m11 * invDet,
(m21 * m32 - m31 * m22) * invDet,
(m31 * m12 - m11 * m32) * invDet
};
}
float Mat3x2::scaling_factor() const
{
return (float)sqrt((double)m11 * m11 + (double)m12 * m12);
}
const Mat3x2 Mat3x2::identity = Mat3x2(1, 0, 0, 1, 0, 0);
Mat3x2 Mat3x2::operator *(const Mat3x2& rhs) const { return multiply(*this, rhs); }
Mat3x2 Mat3x2::operator +(const Mat3x2& rhs) const { return add(*this, rhs); }
Mat3x2 Mat3x2::operator -(const Mat3x2& rhs) const { return subtract(*this, rhs); }
Mat3x2& Mat3x2::operator*=(const Mat3x2& rhs)
{
*this = multiply(*this, rhs);
return *this;
}
bool Mat3x2::operator ==(const Mat3x2& rhs)
{
return memcmp(this, &rhs, sizeof(Mat3x2));
}
bool Mat3x2::operator !=(const Mat3x2& rhs)
{
return !(*this == rhs);
}
Mat3x2 Mat3x2::create_translation(const Vec2& Vec2)
{
return create_translation(Vec2.x, Vec2.y);
}
Mat3x2 Mat3x2::create_translation(float x, float y)
{
return Mat3x2(1, 0, 0, 1, x, y);
}
Mat3x2 Mat3x2::create_scale(float scale)
{
return create_scale(scale, scale);
}
Mat3x2 Mat3x2::create_scale(Vec2 Vec2)
{
return create_scale(Vec2.x, Vec2.y);
}
Mat3x2 Mat3x2::create_scale(float x, float y)
{
return Mat3x2(x, 0, 0, y, 0, 0);
}
Mat3x2 Mat3x2::create_scale(float scale, Vec2 centerPoint)
{
Mat3x2 result;
float tx = centerPoint.x * (1 - scale);
float ty = centerPoint.y * (1 - scale);
result.m11 = scale;
result.m12 = 0.0f;
result.m21 = 0.0f;
result.m22 = scale;
result.m31 = tx;
result.m32 = ty;
return result;
}
Mat3x2 Mat3x2::create_scale(Vec2 scale, Vec2 centerPoint)
{
Mat3x2 result;
float tx = centerPoint.x * (1 - scale.x);
float ty = centerPoint.y * (1 - scale.y);
result.m11 = scale.x;
result.m12 = 0.0f;
result.m21 = 0.0f;
result.m22 = scale.y;
result.m31 = tx;
result.m32 = ty;
return result;
}
Mat3x2 Mat3x2::create_scale(float scaleX, float scaleY, Vec2 centerPoint)
{
Mat3x2 result;
float tx = centerPoint.x * (1 - scaleX);
float ty = centerPoint.y * (1 - scaleY);
result.m11 = scaleX;
result.m12 = 0.0f;
result.m21 = 0.0f;
result.m22 = scaleY;
result.m31 = tx;
result.m32 = ty;
return result;
}
Mat3x2 Mat3x2::create_rotation(float radians)
{
float c = cosf(radians);
float s = sinf(radians);
return Mat3x2(c, s, -s, c, 0, 0);
}
Mat3x2 Mat3x2::create_transform(const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation)
{
Mat3x2 matrix = identity;
if (origin.x != 0 || origin.y != 0)
matrix = create_translation(-origin.x, -origin.y);
if (scale.x != 1 || scale.y != 1)
matrix = matrix * create_scale(scale);
if (rotation != 0)
matrix = matrix * create_rotation(rotation);
if (position.x != 0 || position.y != 0)
matrix = matrix * create_translation(position);
return matrix;
}
Mat3x2 Mat3x2::add(const Mat3x2& a, const Mat3x2& b)
{
return Mat3x2(
a.m11 + b.m11,
a.m12 + b.m12,
a.m21 + b.m21,
a.m22 + b.m22,
a.m31 + b.m31,
a.m32 + b.m32);
}
Mat3x2 Mat3x2::subtract(const Mat3x2& a, const Mat3x2& b)
{
return Mat3x2(
a.m11 - b.m11,
a.m12 - b.m12,
a.m21 - b.m21,
a.m22 - b.m22,
a.m31 - b.m31,
a.m32 - b.m32);
}
Mat3x2 Mat3x2::multiply(const Mat3x2& a, const Mat3x2& b)
{
return Mat3x2(a.m11 * b.m11 + a.m12 * b.m21,
a.m11 * b.m12 + a.m12 * b.m22,
a.m21 * b.m11 + a.m22 * b.m21,
a.m21 * b.m12 + a.m22 * b.m22,
a.m31 * b.m11 + a.m32 * b.m21 + b.m31,
a.m31 * b.m12 + a.m32 * b.m22 + b.m32);
}

109
src/math/mat4x4.cpp Normal file
View File

@ -0,0 +1,109 @@
#include <blah/math/mat4x4.h>
using namespace Blah;
Mat4x4::Mat4x4() :
m11(0.0f), m12(0.0f), m13(0.0f), m14(0.0f),
m21(0.0f), m22(0.0f), m23(0.0f), m24(0.0f),
m31(0.0f), m32(0.0f), m33(0.0f), m34(0.0f),
m41(0.0f), m42(0.0f), m43(0.0f), m44(0.0f) {}
Mat4x4::Mat4x4(
float m11, float m12, float m13, float m14,
float m21, float m22, float m23, float m24,
float m31, float m32, float m33, float m34,
float m41, float m42, float m43, float m44) :
m11(m11), m12(m12), m13(m13), m14(m14),
m21(m21), m22(m22), m23(m23), m24(m24),
m31(m31), m32(m32), m33(m33), m34(m34),
m41(m41), m42(m42), m43(m43), m44(m44) {}
const Mat4x4 Mat4x4::identity = Mat4x4(
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);
Mat4x4 Mat4x4::create_ortho(float width, float height, float z_near_plane, float z_far_plane)
{
Mat4x4 result = identity;
result.m11 = 2.0f / width;
result.m12 = result.m13 = result.m14 = 0.0f;
result.m22 = -2.0f / height;
result.m21 = result.m23 = result.m24 = 0.0f;
result.m33 = 1.0f / (z_near_plane - z_far_plane);
result.m31 = result.m32 = result.m34 = 0.0f;
result.m41 = result.m42 = 0.0f;
result.m43 = z_near_plane / (z_near_plane - z_far_plane);
result.m44 = 1.0f;
return result;
}
Mat4x4 Mat4x4::create_ortho_offcenter(float left, float right, float bottom, float top, float z_near_plane, float z_far_plane)
{
Mat4x4 result = identity;
result.m11 = 2.0f / (right - left);
result.m12 = result.m13 = result.m14 = 0.0f;
result.m22 = 2.0f / (top - bottom);
result.m21 = result.m23 = result.m24 = 0.0f;
result.m33 = 1.0f / (z_near_plane - z_far_plane);
result.m31 = result.m32 = result.m34 = 0.0f;
result.m41 = (left + right) / (left - right);
result.m42 = (top + bottom) / (bottom - top);
result.m43 = z_near_plane / (z_near_plane - z_far_plane);
result.m44 = 1.0f;
return result;
}
Mat4x4 Mat4x4::create_translation(float x, float y, float z)
{
Mat4x4 result = identity;
result.m41 = x;
result.m42 = y;
result.m43 = z;
return result;
}
Mat4x4 Mat4x4::create_scale(float x, float y, float z)
{
Mat4x4 result = identity;
result.m11 = x;
result.m22 = y;
result.m33 = z;
return result;
}
Mat4x4 Mat4x4::operator*(const Mat4x4& rhs)
{
Mat4x4 m;
m.m11 = m11 * rhs.m11 + m12 * rhs.m21 + m13 * rhs.m31 + m14 * rhs.m41;
m.m12 = m11 * rhs.m12 + m12 * rhs.m22 + m13 * rhs.m32 + m14 * rhs.m42;
m.m13 = m11 * rhs.m13 + m12 * rhs.m23 + m13 * rhs.m33 + m14 * rhs.m43;
m.m14 = m11 * rhs.m14 + m12 * rhs.m24 + m13 * rhs.m34 + m14 * rhs.m44;
m.m21 = m21 * rhs.m11 + m22 * rhs.m21 + m23 * rhs.m31 + m24 * rhs.m41;
m.m22 = m21 * rhs.m12 + m22 * rhs.m22 + m23 * rhs.m32 + m24 * rhs.m42;
m.m23 = m21 * rhs.m13 + m22 * rhs.m23 + m23 * rhs.m33 + m24 * rhs.m43;
m.m24 = m21 * rhs.m14 + m22 * rhs.m24 + m23 * rhs.m34 + m24 * rhs.m44;
m.m31 = m31 * rhs.m11 + m32 * rhs.m21 + m33 * rhs.m31 + m34 * rhs.m41;
m.m32 = m31 * rhs.m12 + m32 * rhs.m22 + m33 * rhs.m32 + m34 * rhs.m42;
m.m33 = m31 * rhs.m13 + m32 * rhs.m23 + m33 * rhs.m33 + m34 * rhs.m43;
m.m34 = m31 * rhs.m14 + m32 * rhs.m24 + m33 * rhs.m34 + m34 * rhs.m44;
m.m41 = m41 * rhs.m11 + m42 * rhs.m21 + m43 * rhs.m31 + m44 * rhs.m41;
m.m42 = m41 * rhs.m12 + m42 * rhs.m22 + m43 * rhs.m32 + m44 * rhs.m42;
m.m43 = m41 * rhs.m13 + m42 * rhs.m23 + m43 * rhs.m33 + m44 * rhs.m43;
m.m44 = m41 * rhs.m14 + m42 * rhs.m24 + m43 * rhs.m34 + m44 * rhs.m44;
return m;
}

51
src/math/point.cpp Normal file
View File

@ -0,0 +1,51 @@
#include <blah/math/vec2.h>
#include <blah/math/mat3x2.h>
#include <math.h>
using namespace Blah;
Point::Point()
{
x = y = 0;
}
Point::Point(int px, int py)
{
x = px;
y = py;
}
Point Point::operator +(const Point rhs) const { return Point(x + rhs.x, y + rhs.y); }
Point Point::operator -(const Point rhs) const { return Point(x - rhs.x, y - rhs.y); }
Point Point::operator /(const int rhs) const { return Point(x / rhs, y / rhs); }
Point Point::operator *(const int rhs) const { return Point(x * rhs, y * rhs); }
Point Point::operator-() const { return Point(-x, -y); }
Point& Point::operator +=(const Point& rhs) { x += rhs.x; y += rhs.y; return *this; }
Point& Point::operator -=(const Point& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
Point& Point::operator /=(const Point& rhs) { x /= rhs.x; y /= rhs.y; return *this; }
Point& Point::operator *=(const Point& rhs) { x *= rhs.x; y *= rhs.y; return *this; }
Point& Point::operator /=(int rhs) { x /= rhs; y /= rhs; return *this; }
Point& Point::operator *=(int rhs) { x *= rhs; y *= rhs; return *this; }
bool Point::operator ==(const Point& rhs) { return x == rhs.x && y == rhs.y; }
bool Point::operator !=(const Point& rhs) { return x != rhs.x || y != rhs.y; }
float Point::length() const
{
return sqrtf((float)(x * x + y * y));
}
int Point::length_squared() const
{
return x * x + y * y;
}
const Point Point::unitX = Point(1, 0);
const Point Point::unitY = Point(0, 1);
const Point Point::right = Point(1, 0);
const Point Point::up = Point(0, -1);
const Point Point::down = Point(0, 1);
const Point Point::left = Point(-1, 0);
const Point Point::zero = Point(0, 0);
const Point Point::one = Point(1, 1);

21
src/math/quad.cpp Normal file
View File

@ -0,0 +1,21 @@
#include <blah/math/quad.h>
#include <blah/math/calc.h>
namespace Blah
{
void Quad::project(const Vec2& axis, float* min, float* max) const
{
float dot = Vec2::dot(a, axis);
*min = dot;
*max = dot;
dot = Vec2::dot(b, axis);
*min = Calc::min(dot, *min);
*max = Calc::max(dot, *max);
dot = Vec2::dot(c, axis);
*min = Calc::min(dot, *min);
*max = Calc::max(dot, *max);
dot = Vec2::dot(d, axis);
*min = Calc::min(dot, *min);
*max = Calc::max(dot, *max);
}
}

275
src/math/rect.cpp Normal file
View File

@ -0,0 +1,275 @@
#include <blah/math/rect.h>
#include <blah/math/point.h>
#include <blah/math/rectI.h>
#include <blah/math/vec2.h>
#include <blah/math/calc.h>
#include <blah/math/mat3x2.h>
using namespace Blah;
Rect::Rect()
{
x = y = w = h = 0;
};
Rect::Rect(float rx, float ry, float rw, float rh)
{
x = rx;
y = ry;
w = rw;
h = rh;
}
Rect::Rect(Vec2 pos, Vec2 size)
{
x = pos.x;
y = pos.y;
w = size.x;
h = size.y;
}
Rect::Rect(RectI r)
{
x = (float)r.x;
y = (float)r.y;
w = (float)r.w;
h = (float)r.h;
}
Rect Rect::scale(float s)
{
x = (x * s);
y = (y * s);
w = (w * s);
h = (h * s);
return *this;
}
Rect Rect::scale(float sx, float sy)
{
x = (x * sx);
y = (y * sy);
w = (w * sx);
h = (h * sy);
return *this;
}
float Rect::left() const
{
return x;
}
float Rect::right() const
{
return x + w;
}
float Rect::top() const
{
return y;
}
float Rect::bottom() const
{
return y + h;
}
Vec2 Rect::center() const
{
return Vec2(x + w / 2, y + h / 2);
}
float Rect::center_x() const
{
return x + w / 2;
}
float Rect::center_y() const
{
return y + h / 2;
}
Vec2 Rect::top_left() const
{
return Vec2(x, y);
}
Vec2 Rect::top_right() const
{
return Vec2(x + w, y);
}
Vec2 Rect::bottom_right() const
{
return Vec2(x + w, y + h);
}
Vec2 Rect::bottom_left() const
{
return Vec2(x, y + h);
}
Vec2 Rect::center_left() const
{
return Vec2(x, y + h / 2);
}
Vec2 Rect::center_right() const
{
return Vec2(x + w, y + h / 2);
}
Vec2 Rect::middle_top() const
{
return Vec2(x + w / 2, y);
}
Vec2 Rect::middle_bottom() const
{
return Vec2(x + w / 2, y + h);
}
Line Rect::left_line() const
{
return Line(left(), top(), left(), bottom());
}
Line Rect::right_line() const
{
return Line(right(), top(), right(), bottom());
}
Line Rect::top_line() const
{
return Line(left(), top(), right(), top());
}
Line Rect::bottom_line() const
{
return Line(left(), bottom(), right(), bottom());
}
bool Rect::contains(const Point& pt) const
{
return pt.x >= x && pt.x < x + w && pt.y >= y && pt.y < y + h;
}
bool Rect::contains(const Vec2& pt) const
{
return pt.x >= x && pt.x < x + w && pt.y >= y && pt.y < y + h;
}
bool Rect::overlaps(const Rect& rect) const
{
return x + w >= rect.x && y + h >= rect.y && x < rect.x + rect.w && y < rect.y + rect.h;
}
Rect Rect::overlap_rect(const Rect& against) const
{
Rect result(0, 0, 0, 0);
if (x + w >= against.x && x < against.x + against.w)
{
result.x = Calc::max(x, against.x);
result.w = Calc::min(x + w, against.x + against.w) - result.x;
}
if (y + h >= against.y && y < against.y + against.h)
{
result.y = Calc::max(y, against.y);
result.h = Calc::min(y + h, against.y + against.h) - result.y;
}
return result;
}
bool Rect::intersects(const Line& line) const
{
return line.intersects(*this);
}
bool Rect::intersects(const Line& line, Vec2* out_intersection_point) const
{
return line.intersects(*this, out_intersection_point);
}
bool Rect::intersects(const Vec2& line_from, const Vec2& line_to) const
{
return intersects(Line(line_from, line_to));
}
bool Rect::intersects(const Vec2& line_from, const Vec2& line_to, Vec2* out_intersection_point) const
{
return intersects(Line(line_from, line_to), out_intersection_point);
}
Vec2 Rect::intersection_point(const Line& line) const
{
Vec2 ret;
if (line.intersects(*this, &ret))
return ret;
else
return Vec2::zero;
}
Vec2 Rect::intersection_point(const Vec2& line_from, const Vec2& line_to) const
{
Vec2 ret;
if (Line(line_from, line_to).intersects(*this, &ret))
return ret;
else
return Vec2::zero;
}
Rect Rect::inflate(float amount) const
{
return Rect(x - amount, y - amount, w + amount * 2, h + amount * 2);
}
Rect Rect::operator+(const Vec2& rhs) const { return Rect(x + rhs.x, y + rhs.y, w, h); }
Rect Rect::operator-(const Vec2& rhs) const { return Rect(x - rhs.x, y - rhs.y, w, h); }
Rect& Rect::operator+=(const Vec2& rhs) { x += rhs.x; y += rhs.y; return *this; }
Rect& Rect::operator-=(const Vec2& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
Rect Rect::transform(const Rect& rect, const Mat3x2& matrix)
{
return Rect(
(rect.x * matrix.m11) + (rect.y * matrix.m21) + matrix.m31,
(rect.x * matrix.m12) + (rect.y * matrix.m22) + matrix.m32,
(rect.w * matrix.m11) + (rect.h * matrix.m21),
(rect.w * matrix.m12) + (rect.h * matrix.m22));
}
Rect Rect::transform(float x, float y, float w, float h, const Mat3x2& matrix)
{
return Rect(
(x * matrix.m11) + (y * matrix.m21) + matrix.m31,
(x * matrix.m12) + (y * matrix.m22) + matrix.m32,
(w * matrix.m11) + (h * matrix.m21),
(w * matrix.m12) + (h * matrix.m22));
}
Rect Rect::from_points(Vec2& from, Vec2& to)
{
Vec2 min = Vec2(Calc::min(from.x, to.x), Calc::min(from.y, to.y));
Vec2 max = Vec2(Calc::max(from.x, to.x), Calc::max(from.y, to.y));
return Rect(min.x, min.y, max.x - min.x, max.y - min.y);
}
char Rect::get_sector(const Vec2& pt) const
{
char h;
if (pt.x < left())
h = 0b0001;
else if (pt.x >= right())
h = 0b0010;
else
h = 0;
char v;
if (pt.y < top())
v = 0b0100;
else if (pt.y >= bottom())
v = 0b1000;
else
v = 0;
return h | v;
}

90
src/math/rectI.cpp Normal file
View File

@ -0,0 +1,90 @@
#include <blah/math/rectI.h>
#include <blah/math/rect.h>
#include <blah/math/point.h>
#include <blah/math/vec2.h>
using namespace Blah;
RectI::RectI()
{
x = y = w = h = 0;
}
RectI::RectI(int rx, int ry, int rw, int rh)
{
x = rx;
y = ry;
w = rw;
h = rh;
}
RectI::RectI(Point pos, Point size)
{
x = pos.x;
y = pos.y;
w = size.x;
h = size.y;
}
Point RectI::center() const { return Point(centerX(), centerY()); }
Point RectI::top_left() const { return Point(left(), top()); }
Point RectI::top_right() const { return Point(right(), top()); }
Point RectI::bottom_left() const { return Point(left(), bottom()); }
Point RectI::bottom_right() const { return Point(right(), bottom()); }
bool RectI::contains(const Point& point) const
{
return point.x >= x && point.x < x + w && point.y >= y && point.y < y + h;
}
bool RectI::contains(const Vec2& point) const
{
return point.x >= x && point.x < x + w && point.y >= y && point.y < y + h;
}
char RectI::get_sector(const Point& pt) const
{
char h;
if (pt.x < left())
h = 0b0001;
else if (pt.x >= right())
h = 0b0010;
else
h = 0;
char v;
if (pt.y < top())
v = 0b0100;
else if (pt.y >= bottom())
v = 0b1000;
else
v = 0;
return h | v;
}
char RectI::get_sector(const Vec2& pt) const
{
char h;
if (pt.x < left())
h = 0b0001;
else if (pt.x >= right())
h = 0b0010;
else
h = 0;
char v;
if (pt.y < top())
v = 0b0100;
else if (pt.y >= bottom())
v = 0b1000;
else
v = 0;
return h | v;
}
RectI RectI::operator+(const Point& rhs) const { return RectI(x + rhs.x, y + rhs.y, w, h); }
RectI RectI::operator-(const Point& rhs) const { return RectI(x - rhs.x, y - rhs.y, w, h); }
RectI& RectI::operator+=(const Point& rhs) { x += rhs.x; y += rhs.y; return *this; }
RectI& RectI::operator-=(const Point& rhs) { x -= rhs.x; y -= rhs.y; return *this; }

26
src/math/stopwatch.cpp Normal file
View File

@ -0,0 +1,26 @@
#include <blah/math/stopwatch.h>
#include <chrono>
using namespace std::chrono;
using namespace Blah;
Stopwatch::Stopwatch()
{
reset();
}
void Stopwatch::reset()
{
start_time = std::chrono::duration_cast<std::chrono::microseconds>(system_clock::now().time_since_epoch()).count();
}
uint64_t Stopwatch::milliseconds()
{
return microseconds() / 1000;
}
uint64_t Stopwatch::microseconds()
{
return std::chrono::duration_cast<std::chrono::microseconds>(system_clock::now().time_since_epoch()).count() - start_time;
}

133
src/math/vec2.cpp Normal file
View File

@ -0,0 +1,133 @@
#include <blah/math/vec2.h>
#include <blah/math/mat3x2.h>
#include <blah/math/calc.h>
#include <math.h>
using namespace Blah;
Vec2::Vec2() { x = y = 0; }
Vec2::Vec2(float vx, float vy) { x = vx; y = vy; }
Vec2::Vec2(int vx, float vy) { x = (float)vx; y = vy; }
Vec2::Vec2(float vx, int vy) { x = vx; y = (float)vy; }
Vec2::Vec2(int vx, int vy) { x = (float)vx; y = (float)vy; }
Vec2::Vec2(Point p) { x = (float)p.x; y = (float)p.y; }
Vec2 Vec2::operator +(const Vec2 rhs) const { return Vec2(x + rhs.x, y + rhs.y); }
Vec2 Vec2::operator -(const Vec2 rhs) const { return Vec2(x - rhs.x, y - rhs.y); }
Vec2 Vec2::operator /(const float rhs) const { return Vec2(x / rhs, y / rhs); }
Vec2 Vec2::operator *(const float rhs) const { return Vec2(x * rhs, y * rhs); }
Vec2 Vec2::operator-() const { return Vec2(-x, -y); }
Vec2& Vec2::operator +=(const Vec2& rhs) { x += rhs.x; y += rhs.y; return *this; }
Vec2& Vec2::operator -=(const Vec2& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
Vec2& Vec2::operator /=(const Vec2& rhs) { x /= rhs.x; y /= rhs.y; return *this; }
Vec2& Vec2::operator *=(const Vec2& rhs) { x *= rhs.x; y *= rhs.y; return *this; }
Vec2& Vec2::operator/=(float rhs) { x /= rhs; y /= rhs; return *this; }
Vec2& Vec2::operator*=(float rhs) { x *= rhs; y *= rhs; return *this; }
bool Vec2::operator ==(const Vec2& rhs) { return x == rhs.x && y == rhs.y; }
bool Vec2::operator !=(const Vec2& rhs) { return x != rhs.x || y != rhs.y; }
Vec2 Vec2::normal() const
{
if (x == 0 && y == 0)
return zero;
float length = this->length();
return Vec2(x / length, y / length);
}
Vec2 Vec2::turn_right() const
{
return Vec2(y, -x);
}
Vec2 Vec2::turn_left() const
{
return Vec2(-y, x);
}
float Vec2::length() const { return sqrtf(x * x + y * y); }
float Vec2::length_squared() const { return x * x + y * y; }
Vec2 Vec2::perpendicular() const
{
return Vec2(-y, x);
}
float Vec2::angle() const
{
return Calc::atan2(y, x);
}
float Vec2::dot(Vec2 a, Vec2 b) { return (a.x * b.x + a.y * b.y); }
float Vec2::dot(float x, float y, Vec2 b) { return (x * b.x + y * b.y); }
float Vec2::dot(float x1, float y1, float x2, float y2) { return (x1 * x2 + y1 * y2); }
Vec2 Vec2::transform(const Vec2& vec, const Mat3x2& matrix)
{
return Vec2(
(vec.x * matrix.m11) + (vec.y * matrix.m21) + matrix.m31,
(vec.x * matrix.m12) + (vec.y * matrix.m22) + matrix.m32);
}
Vec2 Vec2::transform(float x, float y, const Mat3x2& matrix)
{
return Vec2(
(x * matrix.m11) + (y * matrix.m21) + matrix.m31,
(x * matrix.m12) + (y * matrix.m22) + matrix.m32);
}
Vec2 Vec2::from_angle(float radians, float length)
{
return Vec2((float)cos(radians) * length, (float)sin(radians) * length);
}
Vec2 Vec2::from_angle(float radians)
{
return from_angle(radians, 1);
}
Vec2 Vec2::lerp(Vec2 a, Vec2 b, float t)
{
if (t == 0)
return a;
else if (t == 1)
return b;
else
return a + (b - a) * t;
}
Vec2 Vec2::bezier_lerp(Vec2 start, Vec2 b, Vec2 end, float t)
{
return lerp(lerp(start, b, t), lerp(b, end, t), t);
}
Vec2 Vec2::bezier_lerp(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t)
{
return bezier_lerp(lerp(start, b, t), lerp(b, c, t), lerp(c, end, t), t);
}
Vec2 Vec2::reflect(const Vec2& vector, const Vec2& normal)
{
float dot = vector.x * normal.x + vector.y * normal.y;
return Vec2(
vector.x - 2.0f * dot * normal.x,
vector.y - 2.0f * dot * normal.y);
}
const Vec2 Vec2::unit_x = Vec2(1, 0);
const Vec2 Vec2::unit_y = Vec2(0, 1);
const Vec2 Vec2::right = Vec2(1, 0);
const Vec2 Vec2::up = Vec2(0, -1);
const Vec2 Vec2::down = Vec2(0, 1);
const Vec2 Vec2::left = Vec2(-1, 0);
const Vec2 Vec2::zero = Vec2(0, 0);
const Vec2 Vec2::one = Vec2(1, 1);
#define DIAGONAL_UNIT 0.70710678118f
const Vec2 Vec2::up_right = Vec2(DIAGONAL_UNIT, -DIAGONAL_UNIT);
const Vec2 Vec2::up_left = Vec2(-DIAGONAL_UNIT, -DIAGONAL_UNIT);
const Vec2 Vec2::down_right = Vec2(DIAGONAL_UNIT, DIAGONAL_UNIT);
const Vec2 Vec2::down_left = Vec2(-DIAGONAL_UNIT, DIAGONAL_UNIT);
#undef DIAGONAL_UNIT