mirror of
				https://github.com/NoelFB/blah.git
				synced 2025-11-04 01:41:34 +08:00 
			
		
		
		
	cleanup pass on numerics
This commit is contained in:
		@ -31,16 +31,12 @@ add_library(blah
 | 
			
		||||
	src/images/packer.cpp
 | 
			
		||||
 | 
			
		||||
	src/numerics/calc.cpp
 | 
			
		||||
	src/numerics/circle.cpp
 | 
			
		||||
	src/numerics/color.cpp
 | 
			
		||||
	src/numerics/line.cpp
 | 
			
		||||
	src/numerics/mat3x2.cpp
 | 
			
		||||
	src/numerics/mat4x4.cpp
 | 
			
		||||
	src/numerics/point.cpp
 | 
			
		||||
	src/numerics/quad.cpp
 | 
			
		||||
	src/numerics/rect.cpp
 | 
			
		||||
	src/numerics/rectI.cpp
 | 
			
		||||
	src/numerics/vec2.cpp
 | 
			
		||||
 | 
			
		||||
	src/streams/bufferstream.cpp
 | 
			
		||||
	src/streams/filestream.cpp
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,10 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <blah/common.h>
 | 
			
		||||
#include <blah/numerics/vec2.h>
 | 
			
		||||
 | 
			
		||||
namespace Blah
 | 
			
		||||
{
 | 
			
		||||
	struct Vec2;
 | 
			
		||||
 | 
			
		||||
	namespace Calc
 | 
			
		||||
	{
 | 
			
		||||
		constexpr float PI = 3.141592653f;
 | 
			
		||||
 | 
			
		||||
@ -8,15 +8,19 @@ namespace Blah
 | 
			
		||||
		Vec2 center;
 | 
			
		||||
		float radius;
 | 
			
		||||
 | 
			
		||||
		Circle()
 | 
			
		||||
		constexpr Circle()
 | 
			
		||||
			: center(), radius(0) {}
 | 
			
		||||
 | 
			
		||||
		Circle(Vec2 center, float radius)
 | 
			
		||||
		constexpr Circle(Vec2 center, float radius)
 | 
			
		||||
			: center(center), radius(radius) {}
 | 
			
		||||
 | 
			
		||||
		Circle(float x, float y, float radius)
 | 
			
		||||
		constexpr Circle(float x, float y, float radius)
 | 
			
		||||
			: center(x, y), radius(radius) {}
 | 
			
		||||
 | 
			
		||||
		void project(const Vec2& axis, float* min, float* max) const;
 | 
			
		||||
		constexpr void project(const Vec2& axis, float* min, float* max) const
 | 
			
		||||
		{
 | 
			
		||||
			*min = Vec2::dot(center - axis * radius, axis);
 | 
			
		||||
			*max = Vec2::dot(center + axis * radius, axis);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
@ -1,12 +1,13 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <blah/common.h>
 | 
			
		||||
#include <blah/containers/str.h>
 | 
			
		||||
#include <blah/numerics/vec3.h>
 | 
			
		||||
#include <blah/numerics/vec4.h>
 | 
			
		||||
 | 
			
		||||
#define BLAH_HEX_VALUE(n) ((n >= '0' && n <= '9') ? (n - '0') : ((n >= 'A' && n <= 'F') ? (10 + n - 'A') : ((n >= 'a' && n <= 'f') ? (10 + n - 'a') : 0)))
 | 
			
		||||
 | 
			
		||||
namespace Blah
 | 
			
		||||
{
 | 
			
		||||
	struct Vec3;
 | 
			
		||||
	struct Vec4;
 | 
			
		||||
 | 
			
		||||
	struct Color
 | 
			
		||||
	{
 | 
			
		||||
		u8 r;
 | 
			
		||||
@ -14,59 +15,171 @@ namespace Blah
 | 
			
		||||
		u8 b;
 | 
			
		||||
		u8 a;
 | 
			
		||||
 | 
			
		||||
		Color();
 | 
			
		||||
		Color(int rgb);
 | 
			
		||||
		Color(int rgb, float alpha);
 | 
			
		||||
		Color(u8 r, u8 g, u8 b);
 | 
			
		||||
		Color(u8 r, u8 g, u8 b, u8 a);
 | 
			
		||||
		Color(const Vec3& vec3);
 | 
			
		||||
		Color(const Vec3& vec3, float alpha);
 | 
			
		||||
		Color(const Vec4& vec4);
 | 
			
		||||
		constexpr Color()
 | 
			
		||||
			: r(0), g(0), b(0), a(0) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Color(int rgb)
 | 
			
		||||
			: r((u8)((rgb & 0xFF0000) >> 16))
 | 
			
		||||
			, g((u8)((rgb & 0x00FF00) >> 8))
 | 
			
		||||
			, b((u8)(rgb & 0x0000FF))
 | 
			
		||||
			, a(255) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Color(int rgb, float alpha)
 | 
			
		||||
			: r((int)(((u8)((rgb & 0xFF0000) >> 16)) * alpha))
 | 
			
		||||
			, g((int)(((u8)((rgb & 0x00FF00) >> 8)) * alpha))
 | 
			
		||||
			, b((int)(((u8)(rgb & 0x0000FF)) * alpha))
 | 
			
		||||
			, a((int)(255 * alpha)) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Color(u8 r, u8 g, u8 b)
 | 
			
		||||
			: r(r)
 | 
			
		||||
			, g(g)
 | 
			
		||||
			, b(b)
 | 
			
		||||
			, a(255) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Color(u8 r, u8 g, u8 b, u8 a)
 | 
			
		||||
			: r(r)
 | 
			
		||||
			, g(g)
 | 
			
		||||
			, b(b)
 | 
			
		||||
			, a(a) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Color(const Vec3& vec3)
 | 
			
		||||
			: r((int)(vec3.x * 255))
 | 
			
		||||
			, g((int)(vec3.y * 255))
 | 
			
		||||
			, b((int)(vec3.z * 255))
 | 
			
		||||
			, a((int)(255)) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Color(const Vec3& vec3, float alpha)
 | 
			
		||||
			: r((int)(vec3.x* alpha * 255))
 | 
			
		||||
			, g((int)(vec3.y* alpha * 255))
 | 
			
		||||
			, b((int)(vec3.z* alpha * 255))
 | 
			
		||||
			, a((int)(alpha * 255)) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Color(const Vec4& vec4)
 | 
			
		||||
			: r((int)(vec4.x * 255))
 | 
			
		||||
			, g((int)(vec4.y * 255))
 | 
			
		||||
			, b((int)(vec4.z * 255))
 | 
			
		||||
			, a((int)(vec4.w * 255)) {}
 | 
			
		||||
 | 
			
		||||
		// Parses a Hex string in the format of "#00000000" or "0x00000000" or "00000000"
 | 
			
		||||
		Color(const String& hex_string);
 | 
			
		||||
		constexpr Color(const char* hex_string)
 | 
			
		||||
			: r(0), g(0), b(0), a(255)
 | 
			
		||||
		{
 | 
			
		||||
			if (*hex_string == '#')
 | 
			
		||||
				hex_string += 1;
 | 
			
		||||
			else if (*hex_string == '0' && (*(hex_string + 1) == 'x' || *(hex_string + 1) == 'X'))
 | 
			
		||||
				hex_string += 2;
 | 
			
		||||
 | 
			
		||||
			int len = 0;
 | 
			
		||||
			while (len < 8 && *(hex_string + len) != '\0')
 | 
			
		||||
				len++;
 | 
			
		||||
 | 
			
		||||
			if (len >= 8)
 | 
			
		||||
				a = (BLAH_HEX_VALUE(hex_string[6]) << 4) + BLAH_HEX_VALUE(hex_string[7]);
 | 
			
		||||
 | 
			
		||||
			if (len >= 6)
 | 
			
		||||
			{
 | 
			
		||||
				r = (BLAH_HEX_VALUE(hex_string[0]) << 4) + BLAH_HEX_VALUE(hex_string[1]);
 | 
			
		||||
				g = (BLAH_HEX_VALUE(hex_string[2]) << 4) + BLAH_HEX_VALUE(hex_string[3]);
 | 
			
		||||
				b = (BLAH_HEX_VALUE(hex_string[4]) << 4) + BLAH_HEX_VALUE(hex_string[5]);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Premultiplies the Color
 | 
			
		||||
		void premultiply();
 | 
			
		||||
		constexpr void premultiply()
 | 
			
		||||
		{
 | 
			
		||||
			r = r * a / 255;
 | 
			
		||||
			g = g * a / 255;
 | 
			
		||||
			b = b * a / 255;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Returns an RGBA hex string of the color
 | 
			
		||||
		String to_hex_rgba() const;
 | 
			
		||||
 | 
			
		||||
		// Sets a Hex string to the given buffer, in the format of RRGGBBAA
 | 
			
		||||
		// The buffer must be at least 8 bytes long
 | 
			
		||||
		void to_hex_rgba(char* buffer) const;
 | 
			
		||||
 | 
			
		||||
		// Sets a Hex string to the given buffer, in the format of RRGGBB
 | 
			
		||||
		// The buffer must be at least 6 bytes long
 | 
			
		||||
		void to_hex_rgb(char* buffer) const;
 | 
			
		||||
 | 
			
		||||
		// Returns an RGB hex string of the color
 | 
			
		||||
		String to_hex_rgb() const;
 | 
			
		||||
 | 
			
		||||
		// Convers the Color to a u32
 | 
			
		||||
		u32 to_rgba() const;
 | 
			
		||||
		// Converts the Color to a Vec3 (RGB)
 | 
			
		||||
		Vec3 to_vec3() const;
 | 
			
		||||
 | 
			
		||||
		// Converts the Color to a Vec4
 | 
			
		||||
		// Converts the Color to a Vec4 (RGBA)
 | 
			
		||||
		Vec4 to_vec4() const;
 | 
			
		||||
 | 
			
		||||
		// Convers the Color to a u32
 | 
			
		||||
		constexpr u32 to_rgba() const
 | 
			
		||||
		{
 | 
			
		||||
			return
 | 
			
		||||
				((u32)r << 24) |
 | 
			
		||||
				((u32)g << 16) |
 | 
			
		||||
				((u32)b << 8) |
 | 
			
		||||
				(u32)a;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Returns a RGBA Color representation of the integer value
 | 
			
		||||
		static Color from_rgba(u32 value);
 | 
			
		||||
		static constexpr Color from_rgba(u32 value)
 | 
			
		||||
		{
 | 
			
		||||
			return
 | 
			
		||||
			{
 | 
			
		||||
				(u8)((value & 0xFF000000) >> 24),
 | 
			
		||||
				(u8)((value & 0x00FF0000) >> 16),
 | 
			
		||||
				(u8)((value & 0x0000FF00) >> 8),
 | 
			
		||||
				(u8)((value & 0x000000FF))
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Returns a RGB Color representation of the integer value, with Alpha = 255
 | 
			
		||||
		static Color from_rgb(u32 value);
 | 
			
		||||
		static constexpr Color from_rgb(u32 value)
 | 
			
		||||
		{
 | 
			
		||||
			return
 | 
			
		||||
			{
 | 
			
		||||
				(u8)((value & 0xFF0000) >> 16),
 | 
			
		||||
				(u8)((value & 0x00FF00) >> 8),
 | 
			
		||||
				(u8)((value & 0x0000FF))
 | 
			
		||||
			};
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Lerps between two colors
 | 
			
		||||
		static Color lerp(Color a, Color b, float amount);
 | 
			
		||||
		static constexpr Color lerp(Color a, Color b, float amount)
 | 
			
		||||
		{
 | 
			
		||||
			if (amount < 0) amount = 0;
 | 
			
		||||
			if (amount > 1) amount = 1;
 | 
			
		||||
 | 
			
		||||
			return Color(
 | 
			
		||||
				(u8)(a.r + (b.r - a.r) * amount),
 | 
			
		||||
				(u8)(a.g + (b.g - a.g) * amount),
 | 
			
		||||
				(u8)(a.b + (b.b - a.b) * amount),
 | 
			
		||||
				(u8)(a.a + (b.a - a.a) * amount)
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Mutliplties the Color
 | 
			
		||||
		Color operator*(float multiply) const;
 | 
			
		||||
		constexpr Color operator*(float multiply) const
 | 
			
		||||
		{
 | 
			
		||||
			return Color(
 | 
			
		||||
				(int)(r * multiply),
 | 
			
		||||
				(int)(g * multiply),
 | 
			
		||||
				(int)(b * multiply),
 | 
			
		||||
				(int)(a * multiply));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// assignment from int
 | 
			
		||||
		Color& operator= (int rgb);
 | 
			
		||||
		
 | 
			
		||||
		// comparisons
 | 
			
		||||
		bool operator ==(const Color& rhs) const;
 | 
			
		||||
		bool operator !=(const Color& rhs) const;
 | 
			
		||||
		constexpr Color& operator= (int rgb)
 | 
			
		||||
		{
 | 
			
		||||
			r = (u8)((rgb & 0xFF0000) >> 16);
 | 
			
		||||
			g = (u8)((rgb & 0x00FF00) >> 8);
 | 
			
		||||
			b = (u8)(rgb & 0x0000FF);
 | 
			
		||||
			a = 255;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator ==(const Color& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator !=(const Color& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return r != rhs.r || g != rhs.g || b != rhs.b || a != rhs.a;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		static const Color transparent;
 | 
			
		||||
		static const Color white;
 | 
			
		||||
@ -79,4 +192,16 @@ namespace Blah
 | 
			
		||||
		static const Color purple;
 | 
			
		||||
		static const Color teal;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	inline const Color Color::transparent = Color(0, 0, 0, 0);
 | 
			
		||||
	inline const Color Color::white = Color(255, 255, 255, 255);
 | 
			
		||||
	inline const Color Color::black = Color(0, 0, 0, 255);
 | 
			
		||||
	inline const Color Color::red = Color(255, 0, 0, 255);
 | 
			
		||||
	inline const Color Color::green = Color(0, 255, 0, 255);
 | 
			
		||||
	inline const Color Color::blue = Color(0, 0, 255, 255);
 | 
			
		||||
	inline const Color Color::yellow = Color(255, 255, 0, 255);
 | 
			
		||||
	inline const Color Color::purple = Color(255, 0, 255, 255);
 | 
			
		||||
	inline const Color Color::teal = Color(0, 255, 255, 255);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef BLAH_HEX_VALUE
 | 
			
		||||
 | 
			
		||||
@ -10,9 +10,14 @@ namespace Blah
 | 
			
		||||
		Vec2 a;
 | 
			
		||||
		Vec2 b;
 | 
			
		||||
 | 
			
		||||
		Line() = default;
 | 
			
		||||
		Line(float x0, float y0, float x1, float y1);
 | 
			
		||||
		Line(const Vec2& start, const Vec2& end);
 | 
			
		||||
		constexpr Line()
 | 
			
		||||
			: a(), b() {}
 | 
			
		||||
 | 
			
		||||
		constexpr Line(const Vec2& a, const Vec2& b)
 | 
			
		||||
			: a(a), b(b) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Line(float x0, float y0, float x1, float y1)
 | 
			
		||||
			: a(x0, y0), b(x1, y1) {}
 | 
			
		||||
 | 
			
		||||
		Rect bounds() const;
 | 
			
		||||
 | 
			
		||||
@ -22,9 +27,24 @@ namespace Blah
 | 
			
		||||
		bool intersects(const Line& line) const;
 | 
			
		||||
		bool intersects(const Line& line, Vec2* out_intersection_point) const;
 | 
			
		||||
 | 
			
		||||
		void project(const Vec2& axis, float* min, float* max) const;
 | 
			
		||||
		constexpr void 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 = dot < *min ? dot : *min;
 | 
			
		||||
			*max = dot > *max ? dot : *max;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Line operator +(const Vec2& rhs) const;
 | 
			
		||||
		Line operator -(const Vec2& rhs) const;
 | 
			
		||||
		constexpr Line operator +(const Vec2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Line(a + rhs, b + rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Line operator -(const Vec2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Line(a - rhs, b - rhs);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
@ -13,21 +13,32 @@ namespace Blah
 | 
			
		||||
		float m31;
 | 
			
		||||
		float m32;
 | 
			
		||||
 | 
			
		||||
		Mat3x2();
 | 
			
		||||
		Mat3x2(float m11, float m12, float m21, float m22, float m31, float m32);
 | 
			
		||||
		constexpr Mat3x2()
 | 
			
		||||
			: m11(0), m12(0), m21(0), m22(0), m31(0), m32(0) {}
 | 
			
		||||
 | 
			
		||||
		Mat3x2 invert() const;
 | 
			
		||||
		float scaling_factor() const;
 | 
			
		||||
 | 
			
		||||
		Mat3x2 operator *(const Mat3x2& rhs) const;
 | 
			
		||||
		Mat3x2 operator +(const Mat3x2& rhs) const;
 | 
			
		||||
		Mat3x2 operator -(const Mat3x2& rhs) const;
 | 
			
		||||
		Mat3x2& operator *=(const Mat3x2& rhs);
 | 
			
		||||
		bool operator==(const Mat3x2& rhs);
 | 
			
		||||
		bool operator!=(const Mat3x2& rhs);
 | 
			
		||||
		constexpr 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) {}
 | 
			
		||||
 | 
			
		||||
		static const Mat3x2 identity;
 | 
			
		||||
 | 
			
		||||
		constexpr 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 scaling_factor() const;
 | 
			
		||||
 | 
			
		||||
	 	static Mat3x2 create_translation(const Vec2& position);
 | 
			
		||||
		static Mat3x2 create_translation(float x, float y);
 | 
			
		||||
		static Mat3x2 create_scale(float scale);
 | 
			
		||||
@ -39,9 +50,69 @@ namespace Blah
 | 
			
		||||
		static Mat3x2 create_rotation(float radians);
 | 
			
		||||
		static Mat3x2 create_transform(const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation);
 | 
			
		||||
 | 
			
		||||
		static Mat3x2 add(const Mat3x2& a, const Mat3x2& b);
 | 
			
		||||
		static Mat3x2 subtract(const Mat3x2& a, const Mat3x2& b);
 | 
			
		||||
		static Mat3x2 multiply(const Mat3x2& a, const Mat3x2& b);
 | 
			
		||||
		
 | 
			
		||||
		static constexpr 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static constexpr 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static constexpr 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Mat3x2 operator *(const Mat3x2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return multiply(*this, rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Mat3x2 operator +(const Mat3x2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return add(*this, rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Mat3x2 operator -(const Mat3x2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return subtract(*this, rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Mat3x2& operator *=(const Mat3x2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			*this = multiply(*this, rhs);
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator==(const Mat3x2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			return m11 == rhs.m11 && m12 == rhs.m12 && m21 == rhs.m21 && m22 == rhs.m22 && m31 == rhs.m31 && m32 == rhs.m32;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator!=(const Mat3x2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			return m11 != rhs.m11 || m12 != rhs.m12 || m21 != rhs.m21 || m22 != rhs.m22 || m31 != rhs.m31 || m32 != rhs.m32;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	inline const Mat3x2 Mat3x2::identity = Mat3x2(1, 0, 0, 1, 0, 0);
 | 
			
		||||
}
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <blah/numerics/calc.h>
 | 
			
		||||
 | 
			
		||||
namespace Blah
 | 
			
		||||
{
 | 
			
		||||
@ -7,27 +8,93 @@ namespace Blah
 | 
			
		||||
		int x;
 | 
			
		||||
		int y;
 | 
			
		||||
 | 
			
		||||
		Point();
 | 
			
		||||
		Point(int px, int py);
 | 
			
		||||
		constexpr Point()
 | 
			
		||||
			: x(0), y(0) {}
 | 
			
		||||
 | 
			
		||||
		Point operator +(const Point rhs) const;
 | 
			
		||||
		Point operator -(const Point rhs) const;
 | 
			
		||||
		Point operator /(const int rhs) const;
 | 
			
		||||
		Point operator *(const int rhs) const;
 | 
			
		||||
		Point operator -() const;
 | 
			
		||||
		constexpr Point(int x, int y)
 | 
			
		||||
			: x(x), y(y) {}
 | 
			
		||||
 | 
			
		||||
		Point& operator +=(const Point& rhs);
 | 
			
		||||
		Point& operator -=(const Point& rhs);
 | 
			
		||||
		Point& operator /=(const Point& rhs);
 | 
			
		||||
		Point& operator *=(const Point& rhs);
 | 
			
		||||
		Point& operator /=(int rhs);
 | 
			
		||||
		Point& operator *=(int rhs);
 | 
			
		||||
		constexpr Point operator +(const Point rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Point(x + rhs.x, y + rhs.y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator ==(const Point& rhs);
 | 
			
		||||
		bool operator !=(const Point& rhs);
 | 
			
		||||
		constexpr Point operator -(const Point rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Point(x - rhs.x, y - rhs.y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		float length() const;
 | 
			
		||||
		int length_squared() const;
 | 
			
		||||
		constexpr Point operator /(const int rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Point(x / rhs, y / rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Point operator *(const int rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Point(x * rhs, y * rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Point operator -() const
 | 
			
		||||
		{
 | 
			
		||||
			return Point(-x, -y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		constexpr Point& operator +=(const Point& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x += rhs.x; y += rhs.y; 
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Point& operator -=(const Point& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x -= rhs.x; y -= rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Point& operator /=(const Point& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x /= rhs.x; y /= rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Point& operator *=(const Point& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x *= rhs.x; y *= rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Point& operator /=(int rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x /= rhs; y /= rhs;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Point& operator *=(int rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x *= rhs; y *= rhs;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator ==(const Point& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return x == rhs.x && y == rhs.y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator !=(const Point& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return x != rhs.x || y != rhs.y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		float length() const
 | 
			
		||||
		{
 | 
			
		||||
			return Calc::sqrt((float)(x * x + y * y));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr int length_squared() const
 | 
			
		||||
		{
 | 
			
		||||
			return x * x + y * y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static const Point unitX;
 | 
			
		||||
		static const Point unitY;
 | 
			
		||||
@ -38,4 +105,13 @@ namespace Blah
 | 
			
		||||
		static const Point zero;
 | 
			
		||||
		static const Point one;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	inline const Point Point::unitX = Point(1, 0);
 | 
			
		||||
	inline const Point Point::unitY = Point(0, 1);
 | 
			
		||||
	inline const Point Point::right = Point(1, 0);
 | 
			
		||||
	inline const Point Point::up    = Point(0, -1);
 | 
			
		||||
	inline const Point Point::down  = Point(0, 1);
 | 
			
		||||
	inline const Point Point::left  = Point(-1, 0);
 | 
			
		||||
	inline const Point Point::zero  = Point(0, 0);
 | 
			
		||||
	inline const Point Point::one   = Point(1, 1);
 | 
			
		||||
}
 | 
			
		||||
@ -10,10 +10,26 @@ namespace Blah
 | 
			
		||||
		Vec2 c;
 | 
			
		||||
		Vec2 d;
 | 
			
		||||
 | 
			
		||||
		Quad() {}
 | 
			
		||||
		Quad(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d)
 | 
			
		||||
		constexpr Quad()
 | 
			
		||||
			: a(), b(), c(), d() {}
 | 
			
		||||
 | 
			
		||||
		constexpr Quad(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d)
 | 
			
		||||
			: a(a), b(b), c(c), d(d) {}
 | 
			
		||||
 | 
			
		||||
		void project(const Vec2& axis, float* min, float* max) const;
 | 
			
		||||
		constexpr void 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 = dot < *min ? dot : *min;
 | 
			
		||||
			*max = dot > *max ? dot : *max;
 | 
			
		||||
			dot = Vec2::dot(c, axis);
 | 
			
		||||
			*min = dot < *min ? dot : *min;
 | 
			
		||||
			*max = dot > *max ? dot : *max;
 | 
			
		||||
			dot = Vec2::dot(d, axis);
 | 
			
		||||
			*min = dot < *min ? dot : *min;
 | 
			
		||||
			*max = dot > *max ? dot : *max;
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
@ -3,11 +3,10 @@
 | 
			
		||||
#include <blah/numerics/vec2.h>
 | 
			
		||||
#include <blah/numerics/rectI.h>
 | 
			
		||||
#include <blah/numerics/line.h>
 | 
			
		||||
#include <blah/numerics/mat3x2.h>
 | 
			
		||||
 | 
			
		||||
namespace Blah
 | 
			
		||||
{
 | 
			
		||||
	struct Mat3x2;
 | 
			
		||||
 | 
			
		||||
	struct Rect
 | 
			
		||||
	{
 | 
			
		||||
		float x;
 | 
			
		||||
@ -15,42 +14,57 @@ namespace Blah
 | 
			
		||||
		float w;
 | 
			
		||||
		float h;
 | 
			
		||||
 | 
			
		||||
		Rect();
 | 
			
		||||
		Rect(float rx, float ry, float rw, float rh);
 | 
			
		||||
		Rect(Vec2 pos, Vec2 size);
 | 
			
		||||
		Rect(RectI r);
 | 
			
		||||
		constexpr Rect()
 | 
			
		||||
			: x(0), y(0), w(0), h(0) {}
 | 
			
		||||
 | 
			
		||||
		Rect scale(float s);
 | 
			
		||||
		Rect scale(float sx, float sy);
 | 
			
		||||
		constexpr Rect(float x, float y, float w, float h)
 | 
			
		||||
			: x(x), y(y), w(w), h(h) {}
 | 
			
		||||
 | 
			
		||||
		float left() const;
 | 
			
		||||
		float right() const;
 | 
			
		||||
		float top() const;
 | 
			
		||||
		float bottom() const;
 | 
			
		||||
		constexpr Rect(Vec2 pos, Vec2 size)
 | 
			
		||||
			: x(pos.x), y(pos.y), w(size.x), h(size.y) {}
 | 
			
		||||
 | 
			
		||||
		Vec2 center() const;
 | 
			
		||||
		float center_x() const;
 | 
			
		||||
		float center_y() const;
 | 
			
		||||
		constexpr Rect(const RectI& r)
 | 
			
		||||
			: x(static_cast<float>(r.x)), y(static_cast<float>(r.y)), w(static_cast<float>(r.w)), h(static_cast<float>(r.h)) {}
 | 
			
		||||
 | 
			
		||||
		Vec2 top_left() const;
 | 
			
		||||
		Vec2 top_right() const;
 | 
			
		||||
		Vec2 bottom_right() const;
 | 
			
		||||
		Vec2 bottom_left() const;
 | 
			
		||||
		constexpr float left() const         { return x; }
 | 
			
		||||
		constexpr float right() const        { return x + w; }
 | 
			
		||||
		constexpr float top() const          { return y; }
 | 
			
		||||
		constexpr float bottom() const       { return y + h; }
 | 
			
		||||
 | 
			
		||||
		Vec2 center_left() const;
 | 
			
		||||
		Vec2 center_right() const;
 | 
			
		||||
		Vec2 middle_top() const;
 | 
			
		||||
		Vec2 middle_bottom() const;
 | 
			
		||||
		constexpr Vec2 center() const        { return Vec2(x + w / 2, y + h / 2); }
 | 
			
		||||
		constexpr float center_x() const     { return x + w / 2; }
 | 
			
		||||
		constexpr float center_y() const     { return y + h / 2; }
 | 
			
		||||
 | 
			
		||||
		Line left_line() const;
 | 
			
		||||
		Line right_line() const;
 | 
			
		||||
		Line top_line() const;
 | 
			
		||||
		Line bottom_line() const;
 | 
			
		||||
		constexpr Vec2 top_left() const      { return Vec2(x, y); }
 | 
			
		||||
		constexpr Vec2 top_right() const     { return Vec2(x + w, y); }
 | 
			
		||||
		constexpr Vec2 bottom_right() const  { return Vec2(x + w, y + h); }
 | 
			
		||||
		constexpr Vec2 bottom_left() const   { return Vec2(x, y + h); }
 | 
			
		||||
 | 
			
		||||
		bool contains(const Point& pt) const;
 | 
			
		||||
		bool contains(const Vec2& pt) const;
 | 
			
		||||
		constexpr Vec2 center_left() const   { return Vec2(x, y + h / 2); }
 | 
			
		||||
		constexpr Vec2 center_right() const  { return Vec2(x + w, y + h / 2); }
 | 
			
		||||
		constexpr Vec2 middle_top() const    { return Vec2(x + w / 2, y); }
 | 
			
		||||
		constexpr Vec2 middle_bottom() const { return Vec2(x + w / 2, y + h); }
 | 
			
		||||
 | 
			
		||||
		constexpr Line left_line() const     { return Line(left(), top(), left(), bottom()); }
 | 
			
		||||
		constexpr Line right_line() const    { return Line(right(), top(), right(), bottom()); }
 | 
			
		||||
		constexpr Line top_line() const      { return Line(left(), top(), right(), top()); }
 | 
			
		||||
		constexpr Line bottom_line() const   { return Line(left(), bottom(), right(), bottom()); }
 | 
			
		||||
 | 
			
		||||
		constexpr bool contains(const Point& pt) const
 | 
			
		||||
		{
 | 
			
		||||
			return pt.x >= x && pt.x < x + w && pt.y >= y && pt.y < y + h;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool contains(const Vec2& pt) const
 | 
			
		||||
		{
 | 
			
		||||
			return pt.x >= x && pt.x < x + w && pt.y >= y && pt.y < y + h;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool overlaps(const Rect& rect) const
 | 
			
		||||
		{
 | 
			
		||||
			return x + w >= rect.x && y + h >= rect.y && x < rect.x + rect.w && y < rect.y + rect.h;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool overlaps(const Rect& rect) const;
 | 
			
		||||
		Rect overlap_rect(const Rect& other) const;
 | 
			
		||||
 | 
			
		||||
		bool intersects(const Line& line) const;
 | 
			
		||||
@ -61,27 +75,99 @@ namespace Blah
 | 
			
		||||
		Vec2 intersection_point(const Line& line) const;
 | 
			
		||||
		Vec2 intersection_point(const Vec2& line_from, const Vec2& line_to) const;
 | 
			
		||||
 | 
			
		||||
		Rect inflate(float amount) const;
 | 
			
		||||
		constexpr Rect scale(float s) const
 | 
			
		||||
		{
 | 
			
		||||
			return Rect(x * s, y * s, w * s, h * s);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/*
 | 
			
		||||
			Rect Sectors:
 | 
			
		||||
				0101  0100  0110
 | 
			
		||||
				0001  0000  0010
 | 
			
		||||
				1001  1000  1010
 | 
			
		||||
			0000 = inside rectangle, all others refer to sectors relative to the rectangle
 | 
			
		||||
		*/
 | 
			
		||||
		char get_sector(const Vec2& pt) const;
 | 
			
		||||
		constexpr Rect scale(float sx, float sy) const
 | 
			
		||||
		{
 | 
			
		||||
			return Rect(x * sx, y * sy, w * sx, h * sy);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool operator==(const Rect& rhs) const { return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h; }
 | 
			
		||||
		bool operator!=(const Rect& rhs) const { return !(*this == rhs); }
 | 
			
		||||
		constexpr Rect inflate(float amount) const
 | 
			
		||||
		{
 | 
			
		||||
			return Rect(x - amount, y - amount, w + amount * 2, h + amount * 2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Rect operator+(const Vec2& rhs) const;
 | 
			
		||||
		Rect operator-(const Vec2& rhs) const;
 | 
			
		||||
		Rect& operator+=(const Vec2& rhs);
 | 
			
		||||
		Rect& operator-=(const Vec2& rhs);
 | 
			
		||||
		// Rect Sectors:
 | 
			
		||||
		//		0101  0100  0110
 | 
			
		||||
		//		0001  0000  0010
 | 
			
		||||
		//		1001  1000  1010
 | 
			
		||||
		//	0000 = inside rectangle, all others refer to sectors relative to the rectangle
 | 
			
		||||
		constexpr char get_sector(const Vec2& pt) const
 | 
			
		||||
		{
 | 
			
		||||
			char h = 0;
 | 
			
		||||
			if (pt.x < left())
 | 
			
		||||
				h = 0b0001;
 | 
			
		||||
			else if (pt.x >= right())
 | 
			
		||||
				h = 0b0010;
 | 
			
		||||
 | 
			
		||||
		static Rect transform(const Rect& vec, const Mat3x2& matrix);
 | 
			
		||||
		static Rect transform(float x, float y, float w, float h, const Mat3x2& matrix);
 | 
			
		||||
		static Rect from_points(Vec2& from, Vec2& to);
 | 
			
		||||
			char v = 0;
 | 
			
		||||
			if (pt.y < top())
 | 
			
		||||
				v = 0b0100;
 | 
			
		||||
			else if (pt.y >= bottom())
 | 
			
		||||
				v = 0b1000;
 | 
			
		||||
 | 
			
		||||
			return h | v;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Rect operator+(const Vec2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Rect(x + rhs.x, y + rhs.y, w, h);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		constexpr Rect operator-(const Vec2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Rect(x - rhs.x, y - rhs.y, w, h);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		constexpr Rect& operator+=(const Vec2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x += rhs.x; y += rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		constexpr Rect& operator-=(const Vec2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x -= rhs.x; y -= rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator==(const Rect& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator!=(const Rect& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return x != rhs.x || y != rhs.y || w != rhs.w || h != rhs.h;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static constexpr 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));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static constexpr 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));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static constexpr Rect from_points(Vec2& from, Vec2& to)
 | 
			
		||||
		{
 | 
			
		||||
			auto min = Vec2(from.x < to.x ? from.x : to.x, from.y < to.y ? from.y : to.y);
 | 
			
		||||
			auto max = Vec2(from.x > to.x ? from.x : to.x, from.y > to.y ? from.y : to.y);
 | 
			
		||||
 | 
			
		||||
			return Rect(min.x, min.y, max.x - min.x, max.y - min.y);
 | 
			
		||||
		}
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,105 +1,263 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
#include <blah/numerics/point.h>
 | 
			
		||||
#include <blah/numerics/calc.h>
 | 
			
		||||
#include <blah/numerics/mat3x2.h>
 | 
			
		||||
 | 
			
		||||
namespace Blah
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	struct Mat3x2;
 | 
			
		||||
 | 
			
		||||
	struct Vec2
 | 
			
		||||
	{
 | 
			
		||||
		float x;
 | 
			
		||||
		float y;
 | 
			
		||||
 | 
			
		||||
		Vec2();
 | 
			
		||||
		Vec2(float vx, float vy);
 | 
			
		||||
		Vec2(int vx, float vy);
 | 
			
		||||
		Vec2(float vx, int vy);
 | 
			
		||||
		Vec2(int vx, int vy);
 | 
			
		||||
		Vec2(Point p);
 | 
			
		||||
		constexpr Vec2()
 | 
			
		||||
			: x(0), y(0) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2(float x, float y)
 | 
			
		||||
			: x(x), y(y) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2(int x, float y)
 | 
			
		||||
			: x(static_cast<float>(x)), y(y) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2(float x, int y)
 | 
			
		||||
			: x(x), y(static_cast<float>(y)) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2(int x, int y)
 | 
			
		||||
			: x(static_cast<float>(x)), y(static_cast<float>(y)) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2(const Point& p)
 | 
			
		||||
			: x(static_cast<float>(p.x)), y(static_cast<float>(p.y)) {}
 | 
			
		||||
		
 | 
			
		||||
		Vec2 operator +(const Vec2 rhs) const;
 | 
			
		||||
		Vec2 operator -(const Vec2 rhs) const;
 | 
			
		||||
		Vec2 operator /(const float rhs) const;
 | 
			
		||||
		Vec2 operator *(const float rhs) const;
 | 
			
		||||
		Vec2 operator -() const;
 | 
			
		||||
		
 | 
			
		||||
		Vec2& operator +=(const Vec2& rhs);
 | 
			
		||||
		Vec2& operator -=(const Vec2& rhs);
 | 
			
		||||
		Vec2& operator /=(const Vec2& rhs);
 | 
			
		||||
		Vec2& operator *=(const Vec2& rhs);
 | 
			
		||||
		Vec2& operator /=(float rhs);
 | 
			
		||||
		Vec2& operator *=(float rhs);
 | 
			
		||||
		
 | 
			
		||||
		bool operator ==(const Vec2& rhs) const;
 | 
			
		||||
		bool operator !=(const Vec2& rhs) const;
 | 
			
		||||
		constexpr Vec2 operator +(const Vec2 rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(x + rhs.x, y + rhs.y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2 operator -(const Vec2 rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(x - rhs.x, y - rhs.y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2 operator /(const float rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(x / rhs, y / rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2 operator *(const float rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(x * rhs, y * rhs);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2 operator -() const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(-x, -y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2& operator +=(const Vec2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x += rhs.x; y += rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2& operator -=(const Vec2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x -= rhs.x; y -= rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2& operator /=(const Vec2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x /= rhs.x; y /= rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2& operator *=(const Vec2& rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x *= rhs.x; y *= rhs.y;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2& operator /=(float rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x /= rhs; y /= rhs;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec2& operator *=(float rhs)
 | 
			
		||||
		{
 | 
			
		||||
			x *= rhs; y *= rhs;
 | 
			
		||||
			return *this;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator ==(const Vec2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return x == rhs.x && y == rhs.y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		constexpr bool operator !=(const Vec2& rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return x != rhs.x || y != rhs.y;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Returns the absolute value of the Vector
 | 
			
		||||
		Vec2 abs() const;
 | 
			
		||||
		constexpr Vec2 abs() const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(x < 0 ? -x : x, y < 0 ? -y : 0);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Returns the Normalized Vector
 | 
			
		||||
		// If the length is 0, the resulting Vector is 0,0
 | 
			
		||||
		Vec2 normal() const;
 | 
			
		||||
		Vec2 normal() const
 | 
			
		||||
		{
 | 
			
		||||
			if (x == 0 && y == 0)
 | 
			
		||||
				return Vec2(0, 0);
 | 
			
		||||
 | 
			
		||||
		// Rotates the Vector 90 degrees right (y, -x)
 | 
			
		||||
		Vec2 turn_right() const;
 | 
			
		||||
			const float len = Calc::sqrt((x * x) + (y * y));
 | 
			
		||||
			return Vec2(x / len, y / len);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Rotates the Vector 90 degrees left (-y, x)
 | 
			
		||||
		Vec2 turn_left() const;
 | 
			
		||||
		// Rotates the Vector 90 degrees right (-y, x)
 | 
			
		||||
		constexpr Vec2 turn_right() const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(-y, x);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Rotates the Vector 90 degrees left (y, -x)
 | 
			
		||||
		constexpr Vec2 turn_left() const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(y, -x);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Returns the length of the Vector
 | 
			
		||||
		float length() const;
 | 
			
		||||
		float length() const
 | 
			
		||||
		{
 | 
			
		||||
			return Calc::sqrt((x * x) + (y * y));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Returns the squared length of the Vector
 | 
			
		||||
		float length_squared() const;
 | 
			
		||||
		constexpr float length_squared() const
 | 
			
		||||
		{
 | 
			
		||||
			return (x * x) + (y * y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Gets the perpendicular Vector (-y, x)
 | 
			
		||||
		Vec2 perpendicular() const;
 | 
			
		||||
		constexpr Vec2 perpendicular() const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(-y, x);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Gets the angle, in radians, of the Vector
 | 
			
		||||
		float angle() const;
 | 
			
		||||
		float angle() const
 | 
			
		||||
		{
 | 
			
		||||
			return Calc::atan2(y, x);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		// Calculates the Dot Product between two vectors
 | 
			
		||||
		static float dot(Vec2 a, Vec2 b);
 | 
			
		||||
		static constexpr float dot(Vec2 a, Vec2 b)
 | 
			
		||||
		{
 | 
			
		||||
			return (a.x * b.x + a.y * b.y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Calculates the Dot Product between two vectors
 | 
			
		||||
		static float dot(float x, float y, Vec2 b);
 | 
			
		||||
		static constexpr float dot(float x, float y, Vec2 b)
 | 
			
		||||
		{
 | 
			
		||||
			return (x * b.x + y * b.y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Calculates the Dot Product between two vectors
 | 
			
		||||
		static float dot(float x1, float y1, float x2, float y2);
 | 
			
		||||
		static constexpr float dot(float x1, float y1, float x2, float y2)
 | 
			
		||||
		{
 | 
			
		||||
			return (x1 * x2 + y1 * y2);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Transforms a Vector by the given Matrix
 | 
			
		||||
		static Vec2 transform(const Vec2& vec, const Mat3x2& matrix);
 | 
			
		||||
		static constexpr 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Transforms a Vector by the given Matrix
 | 
			
		||||
		static Vec2 transform(float x, float y, const Mat3x2& matrix);
 | 
			
		||||
		static constexpr 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Transforms a Vector Normal by the given Matrix
 | 
			
		||||
		static Vec2 transform_normal(const Vec2& vec, const Mat3x2& matrix);
 | 
			
		||||
		static constexpr Vec2 transform_normal(const Vec2& vec, const Mat3x2& matrix)
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(
 | 
			
		||||
				vec.x * matrix.m11 + vec.y * matrix.m21,
 | 
			
		||||
				vec.x * matrix.m12 + vec.y * matrix.m22);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Transforms a Vector Normal by the given Matrix
 | 
			
		||||
		static Vec2 transform_normal(float x, float y, const Mat3x2& matrix);
 | 
			
		||||
		static constexpr Vec2 transform_normal(float x, float y, const Mat3x2& matrix)
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(
 | 
			
		||||
				x * matrix.m11 + y * matrix.m21,
 | 
			
		||||
				x * matrix.m12 + y * matrix.m22);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Calculates a Vector value from the given radians
 | 
			
		||||
		static Vec2 from_angle(float radians, float length = 1.0f);
 | 
			
		||||
		static Vec2 from_angle(float radians, float length = 1.0f)
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(
 | 
			
		||||
				Calc::cos(radians) * length, 
 | 
			
		||||
				Calc::sin(radians) * length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Lerps between two Vectors
 | 
			
		||||
		static Vec2 lerp(Vec2 start, Vec2 end, float t);
 | 
			
		||||
		static constexpr 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;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Lerps between two Vectors along a Bezier curve
 | 
			
		||||
		static Vec2 lerp_bezier(Vec2 start, Vec2 b, Vec2 end, float t);
 | 
			
		||||
		static constexpr Vec2 lerp_bezier(Vec2 a, Vec2 b, Vec2 end, float t)
 | 
			
		||||
		{
 | 
			
		||||
			return lerp(lerp(a, b, t), lerp(b, end, t), t);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Lerps between two Vectors along a Bezier curve
 | 
			
		||||
		static Vec2 lerp_bezier(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t);
 | 
			
		||||
		static constexpr Vec2 lerp_bezier(Vec2 a, Vec2 b, Vec2 c, Vec2 end, float t)
 | 
			
		||||
		{
 | 
			
		||||
			return lerp_bezier(lerp(a, b, t), lerp(b, c, t), lerp(c, end, t), t);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Reflects a vector along the given Normal
 | 
			
		||||
		static Vec2 reflect(const Vec2& vector, const Vec2& normal);
 | 
			
		||||
		static constexpr Vec2 reflect(const Vec2& vector, const Vec2& normal)
 | 
			
		||||
		{
 | 
			
		||||
			const 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);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Gets the minimum between two vectors
 | 
			
		||||
		static Vec2 min(const Vec2& a, const Vec2& b);
 | 
			
		||||
		static constexpr Vec2 min(const Vec2& a, const Vec2& b)
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(
 | 
			
		||||
				a.x < b.x ? a.x : b.x,
 | 
			
		||||
				a.y < b.y ? a.y : b.y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Gets the maximum between two vectors
 | 
			
		||||
		static Vec2 max(const Vec2& a, const Vec2& b);
 | 
			
		||||
		static constexpr Vec2 max(const Vec2& a, const Vec2& b)
 | 
			
		||||
		{
 | 
			
		||||
			return Vec2(
 | 
			
		||||
				a.x > b.x ? a.x : b.x,
 | 
			
		||||
				a.y > b.y ? a.y : b.y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// (1, 0)
 | 
			
		||||
		static const Vec2 unit_x;
 | 
			
		||||
@ -137,5 +295,18 @@ namespace Blah
 | 
			
		||||
		// (-0.707, 0.707)
 | 
			
		||||
		static const Vec2 down_left;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	inline const Vec2 Vec2::unit_x     = Vec2(1, 0);
 | 
			
		||||
	inline const Vec2 Vec2::unit_y     = Vec2(0, 1);
 | 
			
		||||
	inline const Vec2 Vec2::right      = Vec2(1, 0);
 | 
			
		||||
	inline const Vec2 Vec2::up         = Vec2(0, -1);
 | 
			
		||||
	inline const Vec2 Vec2::down       = Vec2(0, 1);
 | 
			
		||||
	inline const Vec2 Vec2::left       = Vec2(-1, 0);
 | 
			
		||||
	inline const Vec2 Vec2::zero       = Vec2(0, 0);
 | 
			
		||||
	inline const Vec2 Vec2::one        = Vec2(1, 1);
 | 
			
		||||
	inline const Vec2 Vec2::up_right   = Vec2(0.70710678118f, -0.70710678118f);
 | 
			
		||||
	inline const Vec2 Vec2::up_left    = Vec2(-0.70710678118f, -0.70710678118f);
 | 
			
		||||
	inline const Vec2 Vec2::down_right = Vec2(0.70710678118f, 0.70710678118f);
 | 
			
		||||
	inline const Vec2 Vec2::down_left  = Vec2(-0.70710678118f, 0.70710678118f);
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
@ -9,24 +9,18 @@ namespace Blah
 | 
			
		||||
		float y;
 | 
			
		||||
		float z;
 | 
			
		||||
 | 
			
		||||
		Vec3()
 | 
			
		||||
			: x(0)
 | 
			
		||||
			, y(0)
 | 
			
		||||
			, z(0)
 | 
			
		||||
		{}
 | 
			
		||||
		constexpr Vec3()
 | 
			
		||||
			: x(0), y(0), z(0) {}
 | 
			
		||||
 | 
			
		||||
		Vec3(float x, float y, float z)
 | 
			
		||||
			: x(x)
 | 
			
		||||
			, y(y)
 | 
			
		||||
			, z(z)
 | 
			
		||||
		{}
 | 
			
		||||
		constexpr Vec3(float x, float y, float z)
 | 
			
		||||
			: x(x), y(y), z(z) {}
 | 
			
		||||
 | 
			
		||||
		inline Vec3 operator +(const Vec3 rhs) const
 | 
			
		||||
		constexpr Vec3 operator +(const Vec3 rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		inline Vec3 operator -(const Vec3 rhs) const
 | 
			
		||||
		constexpr Vec3 operator -(const Vec3 rhs) const
 | 
			
		||||
		{
 | 
			
		||||
			return Vec3(x + rhs.x, y + rhs.y, z + rhs.z);
 | 
			
		||||
		}
 | 
			
		||||
@ -38,14 +32,14 @@ namespace Blah
 | 
			
		||||
			return Vec3(x / length, y / length, z / length);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static inline float dot(Vec3 a, Vec3 b)
 | 
			
		||||
		static constexpr float dot(Vec3 a, Vec3 b)
 | 
			
		||||
		{
 | 
			
		||||
			return a.x * b.x +
 | 
			
		||||
				a.y * b.y +
 | 
			
		||||
				a.z * b.z;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		static inline Vec3 cross(Vec3 a, Vec3 b)
 | 
			
		||||
		static constexpr Vec3 cross(Vec3 a, Vec3 b)
 | 
			
		||||
		{
 | 
			
		||||
			return Vec3(
 | 
			
		||||
				a.y * b.z - a.z * b.y,
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,10 @@ namespace Blah
 | 
			
		||||
		float z;
 | 
			
		||||
		float w;
 | 
			
		||||
 | 
			
		||||
		Vec4() : x(0), y(0), z(0), w(0) {}
 | 
			
		||||
		Vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
 | 
			
		||||
		constexpr Vec4() 
 | 
			
		||||
			: x(0), y(0), z(0), w(0) {}
 | 
			
		||||
 | 
			
		||||
		constexpr Vec4(float x, float y, float z, float w)
 | 
			
		||||
			: x(x), y(y), z(z), w(w) {}
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
#include <blah/numerics/calc.h>
 | 
			
		||||
#include <blah/numerics/vec2.h>
 | 
			
		||||
#include <cmath>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,11 +0,0 @@
 | 
			
		||||
#include <blah/numerics/circle.h>
 | 
			
		||||
#include <blah/numerics/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);
 | 
			
		||||
}
 | 
			
		||||
@ -5,93 +5,10 @@
 | 
			
		||||
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((u8)((rgb & 0xFF0000) >> 16))
 | 
			
		||||
	, g((u8)((rgb & 0x00FF00) >> 8))
 | 
			
		||||
	, b((u8)(rgb & 0x0000FF))
 | 
			
		||||
	, a(255) {}
 | 
			
		||||
 | 
			
		||||
Color::Color(int rgb, float alpha)
 | 
			
		||||
	: r((int)(((u8)((rgb & 0xFF0000) >> 16)) * alpha))
 | 
			
		||||
	, g((int)(((u8)((rgb & 0x00FF00) >> 8)) * alpha))
 | 
			
		||||
	, b((int)(((u8)(rgb & 0x0000FF)) * alpha))
 | 
			
		||||
	, a((int)(255 * alpha)) {}
 | 
			
		||||
 | 
			
		||||
Color::Color(u8 r, u8 g, u8 b)
 | 
			
		||||
	: r(r)
 | 
			
		||||
	, g(g)
 | 
			
		||||
	, b(b)
 | 
			
		||||
	, a(255) {}
 | 
			
		||||
 | 
			
		||||
Color::Color(u8 r, u8 g, u8 b, u8 a)
 | 
			
		||||
	: r(r)
 | 
			
		||||
	, g(g)
 | 
			
		||||
	, b(b)
 | 
			
		||||
	, a(a) {}
 | 
			
		||||
 | 
			
		||||
Color::Color(const Vec3& vec3)
 | 
			
		||||
	: r((int)(vec3.x * 255))
 | 
			
		||||
	, g((int)(vec3.y * 255))
 | 
			
		||||
	, b((int)(vec3.z * 255))
 | 
			
		||||
	, a((int)(255)) {}
 | 
			
		||||
 | 
			
		||||
Color::Color(const Vec3& vec3, float alpha)
 | 
			
		||||
	: r((int)(vec3.x * alpha * 255))
 | 
			
		||||
	, g((int)(vec3.y* alpha * 255))
 | 
			
		||||
	, b((int)(vec3.z* alpha * 255))
 | 
			
		||||
	, a((int)(alpha * 255)) {}
 | 
			
		||||
 | 
			
		||||
Color::Color(const Vec4& vec4)
 | 
			
		||||
	: r((int)(vec4.x * 255))
 | 
			
		||||
	, g((int)(vec4.y * 255))
 | 
			
		||||
	, b((int)(vec4.z * 255))
 | 
			
		||||
	, a((int)(vec4.w * 255)) {}
 | 
			
		||||
 | 
			
		||||
Color::Color(const String& value) 
 | 
			
		||||
	: r(0)
 | 
			
		||||
	, g(0)
 | 
			
		||||
	, b(0)
 | 
			
		||||
	, a(255)
 | 
			
		||||
Vec3 Color::to_vec3() const
 | 
			
		||||
{
 | 
			
		||||
	int offset = 0;
 | 
			
		||||
	if (value.length() > 0 && value[0] == '#')
 | 
			
		||||
		offset = 1;
 | 
			
		||||
	else if (value.length() >= 1 && value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
 | 
			
		||||
		offset = 2;
 | 
			
		||||
 | 
			
		||||
	if (value.length() - offset >= 8)
 | 
			
		||||
		a = (LT_HEX_VALUE(value[offset + 6]) << 4) + LT_HEX_VALUE(value[offset + 7]);
 | 
			
		||||
 | 
			
		||||
	if (value.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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 Color::to_rgba() const
 | 
			
		||||
{
 | 
			
		||||
	return
 | 
			
		||||
		((u32)r << 24) |
 | 
			
		||||
		((u32)g << 16) |
 | 
			
		||||
		((u32)b << 8) |
 | 
			
		||||
		(u32)a;
 | 
			
		||||
	return Vec3(r / 255.0f, g / 255.0f, b / 255.0f);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vec4 Color::to_vec4() const
 | 
			
		||||
@ -99,103 +16,28 @@ 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];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String Color::to_hex_rgba() const
 | 
			
		||||
{
 | 
			
		||||
	String str = "00000000";
 | 
			
		||||
	to_hex_rgba(str.cstr());
 | 
			
		||||
	str[0] = hex[(r & 0xF0) >> 4];
 | 
			
		||||
	str[1] = hex[(r & 0x0F) >> 0];
 | 
			
		||||
	str[2] = hex[(g & 0xF0) >> 4];
 | 
			
		||||
	str[3] = hex[(g & 0x0F) >> 0];
 | 
			
		||||
	str[4] = hex[(b & 0xF0) >> 4];
 | 
			
		||||
	str[5] = hex[(b & 0x0F) >> 0];
 | 
			
		||||
	str[6] = hex[(a & 0xF0) >> 4];
 | 
			
		||||
	str[7] = hex[(a & 0x0F) >> 0];
 | 
			
		||||
	return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
String Color::to_hex_rgb() const
 | 
			
		||||
{
 | 
			
		||||
	String str = "000000";
 | 
			
		||||
	to_hex_rgb(str.cstr());
 | 
			
		||||
	str[0] = hex[(r & 0xF0) >> 4];
 | 
			
		||||
	str[1] = hex[(r & 0x0F) >> 0];
 | 
			
		||||
	str[2] = hex[(g & 0xF0) >> 4];
 | 
			
		||||
	str[3] = hex[(g & 0x0F) >> 0];
 | 
			
		||||
	str[4] = hex[(b & 0xF0) >> 4];
 | 
			
		||||
	str[5] = hex[(b & 0x0F) >> 0];
 | 
			
		||||
	return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Color Color::from_rgba(u32 value)
 | 
			
		||||
{
 | 
			
		||||
	return
 | 
			
		||||
	{
 | 
			
		||||
		(u8)((value & 0xFF000000) >> 24),
 | 
			
		||||
		(u8)((value & 0x00FF0000) >> 16),
 | 
			
		||||
		(u8)((value & 0x0000FF00) >> 8),
 | 
			
		||||
		(u8)((value & 0x000000FF))
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Color Color::from_rgb(u32 value)
 | 
			
		||||
{
 | 
			
		||||
	return
 | 
			
		||||
	{
 | 
			
		||||
		(u8)((value & 0xFF0000) >> 16),
 | 
			
		||||
		(u8)((value & 0x00FF00) >> 8),
 | 
			
		||||
		(u8)((value & 0x0000FF))
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Color Color::lerp(Color a, Color b, float amount)
 | 
			
		||||
{
 | 
			
		||||
	if (amount < 0) amount = 0;
 | 
			
		||||
	if (amount > 1) amount = 1;
 | 
			
		||||
 | 
			
		||||
	return Color(
 | 
			
		||||
		(u8)(a.r + (b.r - a.r) * amount),
 | 
			
		||||
		(u8)(a.g + (b.g - a.g) * amount),
 | 
			
		||||
		(u8)(a.b + (b.b - a.b) * amount),
 | 
			
		||||
		(u8)(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=(int rgb)
 | 
			
		||||
{
 | 
			
		||||
	r = (u8)((rgb & 0xFF0000) >> 16);
 | 
			
		||||
	g = (u8)((rgb & 0x00FF00) >> 8);
 | 
			
		||||
	b = (u8)(rgb & 0x0000FF);
 | 
			
		||||
	a = 255;
 | 
			
		||||
	return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Color::operator ==(const Color& rhs) const { return r == rhs.r && g == rhs.g && b == rhs.b && a == rhs.a; }
 | 
			
		||||
bool Color::operator !=(const Color& rhs) const { return r != rhs.r || g != rhs.g || b != rhs.b || a != rhs.a; }
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
@ -5,17 +5,6 @@
 | 
			
		||||
 | 
			
		||||
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));
 | 
			
		||||
@ -142,16 +131,3 @@ bool Line::intersects(const Line& line, Vec2* intersection_point) const
 | 
			
		||||
	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); }
 | 
			
		||||
 | 
			
		||||
@ -5,53 +5,9 @@
 | 
			
		||||
 | 
			
		||||
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)) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Mat3x2::operator !=(const Mat3x2& rhs)
 | 
			
		||||
{
 | 
			
		||||
	return !(*this == rhs);
 | 
			
		||||
	return Calc::sqrt(m11 * m11 + m12 * m12);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Mat3x2 Mat3x2::create_translation(const Vec2& Vec2)
 | 
			
		||||
@ -152,36 +108,4 @@ Mat3x2 Mat3x2::create_transform(const Vec2& position, const Vec2& origin, const
 | 
			
		||||
		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);
 | 
			
		||||
}
 | 
			
		||||
@ -1,51 +0,0 @@
 | 
			
		||||
#include <blah/numerics/vec2.h>
 | 
			
		||||
#include <blah/numerics/mat3x2.h>
 | 
			
		||||
#include <blah/numerics/calc.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 Calc::sqrt((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);
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
#include <blah/numerics/quad.h>
 | 
			
		||||
#include <blah/numerics/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);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -1,166 +1,8 @@
 | 
			
		||||
#include <blah/numerics/rect.h>
 | 
			
		||||
#include <blah/numerics/point.h>
 | 
			
		||||
#include <blah/numerics/rectI.h>
 | 
			
		||||
#include <blah/numerics/vec2.h>
 | 
			
		||||
#include <blah/numerics/calc.h>
 | 
			
		||||
#include <blah/numerics/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);
 | 
			
		||||
@ -216,60 +58,4 @@ Vec2 Rect::intersection_point(const Vec2& line_from, const Vec2& line_to) const
 | 
			
		||||
		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;
 | 
			
		||||
}
 | 
			
		||||
@ -1,245 +0,0 @@
 | 
			
		||||
#include <blah/numerics/vec2.h>
 | 
			
		||||
#include <blah/numerics/mat3x2.h>
 | 
			
		||||
#include <blah/numerics/calc.h>
 | 
			
		||||
 | 
			
		||||
using namespace Blah;
 | 
			
		||||
 | 
			
		||||
Vec2::Vec2() 
 | 
			
		||||
	: x(0)
 | 
			
		||||
	, y(0)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
Vec2::Vec2(float vx, float vy)
 | 
			
		||||
	: x(vx)
 | 
			
		||||
	, y(vy)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
Vec2::Vec2(int vx, float vy)
 | 
			
		||||
	: x(static_cast<float>(vx))
 | 
			
		||||
	, y(vy)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
Vec2::Vec2(float vx, int vy)
 | 
			
		||||
	: x(vx)
 | 
			
		||||
	, y(static_cast<float>(vy))
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
Vec2::Vec2(int vx, int vy)
 | 
			
		||||
	: x(static_cast<float>(vx))
 | 
			
		||||
	, y(static_cast<float>(vy))
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
Vec2::Vec2(Point p)
 | 
			
		||||
	: x(static_cast<float>(p.x))
 | 
			
		||||
	, y(static_cast<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) const
 | 
			
		||||
{
 | 
			
		||||
	return x == rhs.x && y == rhs.y;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Vec2::operator !=(const Vec2& rhs) const
 | 
			
		||||
{
 | 
			
		||||
	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 transform_normal(const Vec2& vec, const Mat3x2& matrix)
 | 
			
		||||
{
 | 
			
		||||
	return Vec2(
 | 
			
		||||
		vec.x * matrix.m11 + vec.y * matrix.m21,
 | 
			
		||||
		vec.x * matrix.m12 + vec.y * matrix.m22);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vec2 transform_normal(float x, float y, const Mat3x2& matrix)
 | 
			
		||||
{
 | 
			
		||||
	return Vec2(
 | 
			
		||||
		x * matrix.m11 + y * matrix.m21,
 | 
			
		||||
		x * matrix.m12 + y * matrix.m22);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vec2 Vec2::from_angle(float radians, float length)
 | 
			
		||||
{
 | 
			
		||||
	return Vec2((float)cos(radians) * length, (float)sin(radians) * length);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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::lerp_bezier(Vec2 start, Vec2 b, Vec2 end, float t)
 | 
			
		||||
{
 | 
			
		||||
	return lerp(lerp(start, b, t), lerp(b, end, t), t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vec2 Vec2::lerp_bezier(Vec2 start, Vec2 b, Vec2 c, Vec2 end, float t)
 | 
			
		||||
{
 | 
			
		||||
	return lerp_bezier(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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vec2 Vec2::min(const Vec2& a, const Vec2& b)
 | 
			
		||||
{
 | 
			
		||||
	return Vec2(
 | 
			
		||||
		a.x < b.x ? a.x : b.x,
 | 
			
		||||
		a.y < b.y ? a.y : b.y);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Vec2 Vec2::max(const Vec2& a, const Vec2& b)
 | 
			
		||||
{
 | 
			
		||||
	return Vec2(
 | 
			
		||||
		a.x > b.x ? a.x : b.x,
 | 
			
		||||
		a.y > b.y ? a.y : b.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