mirror of
https://github.com/NoelFB/blah.git
synced 2025-07-01 19:45:26 +08:00
restructured project to match a more standard cmake setup
This commit is contained in:
156
src/math/calc.cpp
Normal file
156
src/math/calc.cpp
Normal 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
11
src/math/circle.cpp
Normal 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
156
src/math/color.cpp
Normal 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
157
src/math/line.cpp
Normal 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
187
src/math/mat3x2.cpp
Normal 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
109
src/math/mat4x4.cpp
Normal 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
51
src/math/point.cpp
Normal 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
21
src/math/quad.cpp
Normal 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
275
src/math/rect.cpp
Normal 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
90
src/math/rectI.cpp
Normal 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
26
src/math/stopwatch.cpp
Normal 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
133
src/math/vec2.cpp
Normal 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
|
Reference in New Issue
Block a user