From d91658aa4668075a5411fb9b9881a7a075e84724 Mon Sep 17 00:00:00 2001 From: Noel Berry Date: Sun, 12 Dec 2021 20:41:23 -0800 Subject: [PATCH] large spatial / numerics refactor to allow double/integer vector types --- CMakeLists.txt | 5 - README.md | 8 +- include/blah.h | 12 +- include/blah/app.h | 2 +- include/blah/containers/str.h | 44 +- include/blah/filesystem.h | 2 +- include/blah/graphics/batch.h | 109 +-- include/blah/graphics/material.h | 18 + include/blah/graphics/renderpass.h | 6 +- include/blah/graphics/spritefont.h | 4 +- include/blah/graphics/subtexture.h | 18 +- include/blah/images/image.h | 9 +- include/blah/images/packer.h | 17 +- include/blah/input.h | 31 +- include/blah/numerics/calc.h | 18 +- include/blah/numerics/circle.h | 26 - include/blah/numerics/color.h | 36 +- include/blah/numerics/line.h | 50 -- include/blah/numerics/mat3x2.h | 133 --- include/blah/numerics/mat4x4.h | 48 - include/blah/numerics/point.h | 117 --- include/blah/numerics/quad.h | 35 - include/blah/numerics/rect.h | 173 ---- include/blah/numerics/rectI.h | 59 -- include/blah/numerics/spatial.h | 1300 +++++++++++++++++++++++++++ include/blah/numerics/vec2.h | 312 ------- include/blah/numerics/vec3.h | 50 -- include/blah/numerics/vec4.h | 18 - include/blah/streams/memorystream.h | 8 +- include/blah/time.h | 4 +- src/app.cpp | 5 +- src/containers/str.cpp | 2 +- src/graphics/batch.cpp | 236 ++--- src/graphics/material.cpp | 101 ++- src/graphics/renderpass.cpp | 10 +- src/graphics/spritefont.cpp | 2 +- src/graphics/subtexture.cpp | 12 +- src/images/image.cpp | 6 +- src/images/packer.cpp | 48 +- src/input.cpp | 56 +- src/internal/graphics_gl.cpp | 4 +- src/internal/platform.h | 6 + src/internal/platform_sdl2.cpp | 15 +- src/internal/platform_win32.cpp | 13 +- src/numerics/calc.cpp | 36 +- src/numerics/color.cpp | 12 +- src/numerics/line.cpp | 133 --- src/numerics/mat3x2.cpp | 95 -- src/numerics/mat4x4.cpp | 161 ---- src/numerics/rect.cpp | 61 -- src/numerics/rectI.cpp | 202 ----- src/streams/memorystream.cpp | 6 +- src/time.cpp | 4 +- 53 files changed, 1842 insertions(+), 2056 deletions(-) delete mode 100644 include/blah/numerics/circle.h delete mode 100644 include/blah/numerics/line.h delete mode 100644 include/blah/numerics/mat3x2.h delete mode 100644 include/blah/numerics/mat4x4.h delete mode 100644 include/blah/numerics/point.h delete mode 100644 include/blah/numerics/quad.h delete mode 100644 include/blah/numerics/rect.h delete mode 100644 include/blah/numerics/rectI.h create mode 100644 include/blah/numerics/spatial.h delete mode 100644 include/blah/numerics/vec2.h delete mode 100644 include/blah/numerics/vec3.h delete mode 100644 include/blah/numerics/vec4.h delete mode 100644 src/numerics/line.cpp delete mode 100644 src/numerics/mat3x2.cpp delete mode 100644 src/numerics/mat4x4.cpp delete mode 100644 src/numerics/rect.cpp delete mode 100644 src/numerics/rectI.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0516abd..d7e1da4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,11 +32,6 @@ add_library(blah src/numerics/calc.cpp src/numerics/color.cpp - src/numerics/line.cpp - src/numerics/mat3x2.cpp - src/numerics/mat4x4.cpp - src/numerics/rect.cpp - src/numerics/rectI.cpp src/streams/bufferstream.cpp src/streams/filestream.cpp diff --git a/README.md b/README.md index 8cb35cb..6bced36 100644 --- a/README.md +++ b/README.md @@ -38,13 +38,13 @@ void render() { App::backbuffer->clear(Color::black); - auto center = Vec2(App::backbuffer->width(), App::backbuffer->height()) / 2; + auto center = Vec2f(App::backbuffer->width(), App::backbuffer->height()) / 2; auto rotation = Time::seconds * Calc::TAU; - auto transform = Mat3x2::create_transform(center, Vec2::zero, Vec2::one, rotation); + auto transform = Mat3x2f::create_transform(center, Vec2::zero, Vec2::one, rotation); batch.push_matrix(transform); - batch.rect(Rect(-32, -32, 64, 64), Color::red); - batch.tex(tex, Vec2(64, 0), Color::white); + batch.rect(Rectf(-32, -32, 64, 64), Color::red); + batch.tex(tex, Vec2f(64, 0), Color::white); batch.pop_matrix(); batch.render(); diff --git a/include/blah.h b/include/blah.h index 06b2328..fb7aa71 100644 --- a/include/blah.h +++ b/include/blah.h @@ -29,19 +29,9 @@ #include "blah/images/packer.h" #include "blah/numerics/calc.h" -#include "blah/numerics/circle.h" +#include "blah/numerics/spatial.h" #include "blah/numerics/color.h" #include "blah/numerics/ease.h" -#include "blah/numerics/line.h" -#include "blah/numerics/mat3x2.h" -#include "blah/numerics/mat4x4.h" -#include "blah/numerics/point.h" -#include "blah/numerics/quad.h" -#include "blah/numerics/rect.h" -#include "blah/numerics/rectI.h" -#include "blah/numerics/vec2.h" -#include "blah/numerics/vec3.h" -#include "blah/numerics/vec4.h" #include "blah/streams/bufferstream.h" #include "blah/streams/filestream.h" diff --git a/include/blah/app.h b/include/blah/app.h index 28d1e57..45b03a6 100644 --- a/include/blah/app.h +++ b/include/blah/app.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include namespace Blah { diff --git a/include/blah/containers/str.h b/include/blah/containers/str.h index 8a5b9c1..dd3d66d 100644 --- a/include/blah/containers/str.h +++ b/include/blah/containers/str.h @@ -165,7 +165,7 @@ namespace Blah // clears and disposes the internal string buffer void dispose(); - ~Str() + virtual ~Str() { if (m_buffer != nullptr && m_buffer != empty_buffer) delete[] m_buffer; @@ -181,10 +181,10 @@ namespace Blah } // returns a pointer to the heap buffer or to our stack allocation - char* data() { return (m_buffer != nullptr ? m_buffer : ((char*)(this) + sizeof(Str))); } + virtual char* data() { return m_buffer; } // returns a pointer to the heap buffer or to our stack allocation - const char* data() const { return (m_buffer != nullptr ? m_buffer : ((char*)(this) + sizeof(Str))); } + virtual const char* data() const { return m_buffer; } // assigns the contents of the string void set(const Str& str) { set(str.cstr(), str.cstr() + str.m_length); } @@ -192,9 +192,10 @@ namespace Blah // assigns the contents of the string void set(const char* start, const char* end = nullptr); + char* m_buffer; + private: static char empty_buffer[1]; - char* m_buffer; int m_length; int m_capacity; int m_local_size; @@ -221,6 +222,10 @@ namespace Blah StrOf& operator=(const Str& rhs) { set(rhs); return *this; } StrOf& operator=(const StrOf& rhs) { set(rhs); return *this; } + // either return stack or heap buffer depending on which is in-use + char* data() override { return m_buffer != nullptr ? m_buffer : m_local_buffer; } + const char* data() const override { return m_buffer != nullptr ? m_buffer : m_local_buffer; } + // creates a string from the format static StrOf fmt(const char* str, ...); }; @@ -251,6 +256,33 @@ namespace Blah return str; } + + struct CaseInsenstiveStringHash + { + std::size_t operator()(const Blah::Str& key) const + { + std::size_t result = 2166136261U; + + for (auto& it : key) + { + if (it >= 'A' && it <= 'Z') + result ^= (static_cast(it) - 'A' + 'a'); + else + result ^= static_cast(it); + result *= 16777619U; + } + + return result; + } + }; + + struct CaseInsenstiveStringCompare + { + bool operator() (const Str& lhs, const Str& rhs) const + { + return lhs.length() == rhs.length() && lhs.starts_with(rhs, true); + } + }; } namespace std @@ -264,7 +296,7 @@ namespace std for (auto& it : key) { - result ^= static_cast(it); + result ^= static_cast(it); result *= 16777619U; } @@ -281,7 +313,7 @@ namespace std for (auto& it : key) { - result ^= static_cast(it); + result ^= static_cast(it); result *= 16777619U; } diff --git a/include/blah/filesystem.h b/include/blah/filesystem.h index b3fdcf0..cecb2c2 100644 --- a/include/blah/filesystem.h +++ b/include/blah/filesystem.h @@ -104,7 +104,7 @@ namespace Blah template FilePath join(const FilePath& a, const FilePath& b, const Args&... args) { - return join(a, join(b, std::forward(args)...)); + return join(a, join(b, args...)); } } } \ No newline at end of file diff --git a/include/blah/graphics/batch.h b/include/blah/graphics/batch.h index 8106c05..d475739 100644 --- a/include/blah/graphics/batch.h +++ b/include/blah/graphics/batch.h @@ -1,9 +1,6 @@ #pragma once #include -#include -#include -#include -#include +#include #include #include #include @@ -53,6 +50,10 @@ namespace Blah const char* sampler_uniform; const char* matrix_uniform; + // Snaps all drawing coordinates to integer values + // This is useful for drawing Pixel Art stuff + bool integerize = false; + // Default Sampler, set on clear TextureSampler default_sampler; @@ -63,23 +64,23 @@ namespace Blah // Pushes a new matrix onto the stack, and uses it for transforming all drawing. // `absolute` means the matrix provided will not be transformed by the current stack. - void push_matrix(const Mat3x2& matrix, bool absolute = false); + void push_matrix(const Mat3x2f& matrix, bool absolute = false); // Pops the matrix from the stack - Mat3x2 pop_matrix(); + Mat3x2f pop_matrix(); // Gets the current matrix from the top of the stackKO - Mat3x2 peek_matrix() const; + Mat3x2f peek_matrix() const; // Pushes a Scissor rectangle. Note this is not transformed by the matrix stack // or other scissors. Each push is screen-space. - void push_scissor(const Rect& scissor); + void push_scissor(const Rectf& scissor); // Pops a Scissor rectangle from the stack - Rect pop_scissor(); + Rectf pop_scissor(); // Gets the current Scissor rectangle from the top of the stack - Rect peek_scissor() const; + Rectf peek_scissor() const; // Pushes a blend mode void push_blend(const BlendMode& blend); @@ -130,7 +131,7 @@ namespace Blah void render(const TargetRef& target = App::backbuffer); // Draws the batch to the given target, with the provided matrix - void render(const TargetRef& target, const Mat4x4& matrix); + void render(const TargetRef& target, const Mat4x4f& matrix); // Clears the batch void clear(); @@ -138,60 +139,60 @@ namespace Blah // Clears and disposes all resources that the batch is using void dispose(); - void line(const Vec2& from, const Vec2& to, float t, Color color); - void line(const Vec2& from, const Vec2& to, float t, Color fromColor, Color toColor); + void line(const Vec2f& from, const Vec2f& to, float t, Color color); + void line(const Vec2f& from, const Vec2f& to, float t, Color fromColor, Color toColor); - void bezier_line(const Vec2& from, const Vec2& b, const Vec2& to, int steps, float t, Color color); - void bezier_line(const Vec2& from, const Vec2& b, const Vec2& c, const Vec2& to, int steps, float t, Color color); + void bezier_line(const Vec2f& from, const Vec2f& b, const Vec2f& to, int steps, float t, Color color); + void bezier_line(const Vec2f& from, const Vec2f& b, const Vec2f& c, const Vec2f& to, int steps, float t, Color color); - void tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color color); - void tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color col0, Color col1, Color col2); - void tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, Color color); - void tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, Color col0, Color col1, Color col2); + void tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, Color color); + void tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, Color col0, Color col1, Color col2); + void tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, Color color); + void tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, Color col0, Color col1, Color col2); - void tri_line(const Vec2& a, const Vec2& b, const Vec2& c, float t, Color color); + void tri_line(const Vec2f& a, const Vec2f& b, const Vec2f& c, float t, Color color); - void rect(const Rect& rect, Color color); - void rect_line(const Rect& rect, float t, Color color); - void rect_rounded(const Rect& rect, float radius, int steps, Color color); - void rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, Color color); - void rect_rounded_line(const Rect& rect, float radius, int steps, float t, Color color); - void rect_rounded_line(const Rect& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, float t, Color color); + void rect(const Rectf& rect, Color color); + void rect_line(const Rectf& rect, float t, Color color); + void rect_rounded(const Rectf& rect, float radius, int steps, Color color); + void rect_rounded(const Rectf& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, Color color); + void rect_rounded_line(const Rectf& rect, float radius, int steps, float t, Color color); + void rect_rounded_line(const Rectf& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, float t, Color color); - void semi_circle(const Vec2& center, float start_radians, float end_radians, float radius, int steps, Color centerColor, Color edgeColor); - void semi_circle(const Vec2& center, float start_radians, float end_radians, float radius, int steps, Color color); - void semi_circle_line(const Vec2& center, float start_radians, float end_radians, float radius, int steps, float t, Color color); + void semi_circle(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, Color centerColor, Color edgeColor); + void semi_circle(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, Color color); + void semi_circle_line(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, float t, Color color); - void circle(const Vec2& center, float radius, int steps, Color color); - void circle(const Vec2& center, float radius, int steps, Color center_color, Color outer_color); - void circle_line(const Vec2& center, float radius, float t, int steps, Color color); + void circle(const Vec2f& center, float radius, int steps, Color color); + void circle(const Vec2f& center, float radius, int steps, Color center_color, Color outer_color); + void circle_line(const Vec2f& center, float radius, float t, int steps, Color color); - void quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, Color color); - void quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, Color col0, Color col1, Color col2, Color col3); - void quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, const Vec2& tex3, Color color); - void quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, const Vec2& tex3, Color col0, Color col1, Color col2, Color col3); - void quad_line(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d, float t, Color color); + void quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, Color color); + void quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, Color col0, Color col1, Color col2, Color col3); + void quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, const Vec2f& tex3, Color color); + void quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, const Vec2f& tex3, Color col0, Color col1, Color col2, Color col3); + void quad_line(const Vec2f& a, const Vec2f& b, const Vec2f& c, const Vec2f& d, float t, Color color); - void arrow_head(const Vec2& point_pos, float radians, float side_len, Color color); - void arrow_head(const Vec2& point_pos, const Vec2& from_pos, float side_len, Color color); + void arrow_head(const Vec2f& point_pos, float radians, float side_len, Color color); + void arrow_head(const Vec2f& point_pos, const Vec2f& from_pos, float side_len, Color color); - void tex(const TextureRef& texture, const Vec2& position = Vec2::zero, Color color = Color::white); - void tex(const TextureRef& texture, const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation, Color color); - void tex(const TextureRef& texture, const Rect& clip, const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation, Color color); + void tex(const TextureRef& texture, const Vec2f& position = Vec2f::zero, Color color = Color::white); + void tex(const TextureRef& texture, const Vec2f& position, const Vec2f& origin, const Vec2f& scale, float rotation, Color color); + void tex(const TextureRef& texture, const Rectf& clip, const Vec2f& position, const Vec2f& origin, const Vec2f& scale, float rotation, Color color); - void tex(const Subtexture& subtexture, const Vec2& position = Vec2::zero, Color color = Color::white); - void tex(const Subtexture& subtexture, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color); - void tex(const Subtexture& subtexture, const Rect& clip, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color); + void tex(const Subtexture& subtexture, const Vec2f& position = Vec2f::zero, Color color = Color::white); + void tex(const Subtexture& subtexture, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color); + void tex(const Subtexture& subtexture, const Rectf& clip, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color); - void str(const SpriteFont& font, const String& text, const Vec2& pos, Color color); - void str(const SpriteFont& font, const String& text, const Vec2& pos, TextAlign align, float size, Color color); + void str(const SpriteFont& font, const String& text, const Vec2f& pos, Color color); + void str(const SpriteFont& font, const String& text, const Vec2f& pos, TextAlign align, float size, Color color); private: struct Vertex { - Vec2 pos; - Vec2 tex; + Vec2f pos; + Vec2f tex; Color col; u8 mult; @@ -210,7 +211,7 @@ namespace Blah TextureRef texture; TextureSampler sampler; bool flip_vertically; - Rect scissor; + Rectf scissor; DrawBatch() : layer(0), @@ -224,15 +225,15 @@ namespace Blah static ShaderRef m_default_shader; MaterialRef m_default_material; MeshRef m_mesh; - Mat3x2 m_matrix; + Mat3x2f m_matrix; ColorMode m_color_mode; u8 m_tex_mult; u8 m_tex_wash; DrawBatch m_batch; Vector m_vertices; Vector m_indices; - Vector m_matrix_stack; - Vector m_scissor_stack; + Vector m_matrix_stack; + Vector m_scissor_stack; Vector m_blend_stack; Vector m_material_stack; Vector m_color_mode_stack; @@ -240,6 +241,6 @@ namespace Blah Vector m_batches; int m_batch_insert; - void render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4& matrix); + void render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4f& matrix); }; } \ No newline at end of file diff --git a/include/blah/graphics/material.h b/include/blah/graphics/material.h index f4099d2..c5c4623 100644 --- a/include/blah/graphics/material.h +++ b/include/blah/graphics/material.h @@ -4,6 +4,7 @@ #include #include #include +#include namespace Blah { @@ -30,6 +31,9 @@ namespace Blah // If the Shader is invalid, it will return an invalid MaterialRef. static MaterialRef create(const ShaderRef& shader); + // Clones the material and returns a new one + MaterialRef clone() const; + // Returns the Shader assigned to the Material. ShaderRef shader() const; @@ -62,6 +66,20 @@ namespace Blah // can be set. void set_value(const char* name, const float* value, i64 length); + // Shorthands to more easily assign uniform values + void set_value(const char* name, float value); + void set_value(const char* name, const Vec2f& value); + void set_value(const char* name, const Vec3f& value); + void set_value(const char* name, const Vec4f& value); + void set_value(const char* name, const Mat3x2f& value); + void set_value(const char* name, const Mat4x4f& value); + void set_value(const char* name, const Vector& value); + void set_value(const char* name, const Vector& value); + void set_value(const char* name, const Vector& value); + void set_value(const char* name, const Vector& value); + void set_value(const char* name, const Vector& value); + void set_value(const char* name, const Vector& value); + // Gets a pointer to the values of the given Uniform, or nullptr if it doesn't exist. const float* get_value(const char* name, i64* length = nullptr) const; diff --git a/include/blah/graphics/renderpass.h b/include/blah/graphics/renderpass.h index 3647cd8..aa6b06b 100644 --- a/include/blah/graphics/renderpass.h +++ b/include/blah/graphics/renderpass.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include #include @@ -57,10 +57,10 @@ namespace Blah bool has_scissor; // The viewport (only used if hasViewport is true) - Rect viewport; + Rectf viewport; // The scissor rectangle (only used if hasScissor is true) - Rect scissor; + Rectf scissor; // First index in the Mesh to draw from i64 index_start; diff --git a/include/blah/graphics/spritefont.h b/include/blah/graphics/spritefont.h index 7165fa6..79a8695 100644 --- a/include/blah/graphics/spritefont.h +++ b/include/blah/graphics/spritefont.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include #include @@ -44,7 +44,7 @@ namespace Blah { Subtexture subtexture; float advance = 0; - Vec2 offset; + Vec2f offset; }; // SpriteFont name diff --git a/include/blah/graphics/subtexture.h b/include/blah/graphics/subtexture.h index fb0faf5..f9ea4cd 100644 --- a/include/blah/graphics/subtexture.h +++ b/include/blah/graphics/subtexture.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include namespace Blah { @@ -12,23 +12,23 @@ namespace Blah TextureRef texture; // Source rectangle, in pixels - Rect source; + Rectf source; // Frame rectangle, in pixels. This describes padding around the image. // This is useful for drawing images that have been trimmed. Ex. if the source // is 32,32, but the original image was 64,64, the frame could be -16,-16,64,64 - Rect frame; + Rectf frame; // `draw_coords` are automatically assigned through `update` method - Vec2 draw_coords[4]; + Vec2f draw_coords[4]; // `tex_coords` are automatically assigned through the `update` method - Vec2 tex_coords[4]; + Vec2f tex_coords[4]; Subtexture(); Subtexture(const TextureRef& texture); - Subtexture(const TextureRef& texture, Rect source); - Subtexture(const TextureRef& texture, Rect source, Rect frame); + Subtexture(const TextureRef& texture, Rectf source); + Subtexture(const TextureRef& texture, Rectf source, Rectf frame); // Returns the width of the image float width() const { return frame.w; } @@ -40,9 +40,9 @@ namespace Blah void update(); // returns resulting source and frame rectangles based on the provided clip rectangle - void crop_info(const Rect& clip, Rect* dest_source, Rect* dest_frame) const; + void crop_info(const Rectf& clip, Rectf* dest_source, Rectf* dest_frame) const; // returns a subtexture cropped to the provided rectangle - Subtexture crop(const Rect& clip) const; + Subtexture crop(const Rectf& clip) const; }; } \ No newline at end of file diff --git a/include/blah/images/image.h b/include/blah/images/image.h index 9c951f0..4c26a1a 100644 --- a/include/blah/images/image.h +++ b/include/blah/images/image.h @@ -1,7 +1,6 @@ #pragma once #include -#include -#include +#include #include namespace Blah @@ -45,7 +44,7 @@ namespace Blah // sets the pixels at the provided rectangle to the given data // data must be at least rect.w * rect.h in size! - void set_pixels(const RectI& rect, Color* data); + void set_pixels(const Recti& rect, Color* data); // saves the image to a png file bool save_png(const FilePath& file) const; @@ -60,10 +59,10 @@ namespace Blah bool save_jpg(Stream& stream, int quality) const; // gets the pixels from the given source rectangle - void get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, RectI source_rect) const; + void get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, Recti source_rect) const; // gets a sub image from this image - Image get_sub_image(const RectI& source_rect); + Image get_sub_image(const Recti& source_rect); private: diff --git a/include/blah/images/packer.h b/include/blah/images/packer.h index 2f1439a..bcc6321 100644 --- a/include/blah/images/packer.h +++ b/include/blah/images/packer.h @@ -1,8 +1,7 @@ #pragma once #include #include -#include -#include +#include #include #include #include @@ -37,13 +36,13 @@ namespace Blah // Packed frame rectangle. // This won't be set until after the packer has run. - RectI frame; + Recti frame; // Packed position and size. // This won't be set until after the packer has run. - RectI packed; + Recti packed; - Entry(u64 id, const RectI& frame) + Entry(u64 id, const Recti& frame) : memory_index(0) , id(id) , page(0) @@ -83,7 +82,7 @@ namespace Blah void add(u64 id, const Image& bitmap); // add a new entry - void add(u64 id, const Image& bitmap, const RectI& source); + void add(u64 id, const Image& bitmap, const Recti& source); // add a new entry void add(u64 id, const FilePath& path); @@ -104,13 +103,13 @@ namespace Blah struct Node { bool used; - RectI rect; + Recti rect; Node* right; Node* down; Node(); Node* Find(int w, int h); - Node* Reset(const RectI& rect); + Node* Reset(const Recti& rect); }; // whether the packer has any changes that require it to run again @@ -123,6 +122,6 @@ namespace Blah Vector m_entries; // adds a new entry - void add_entry(u64 id, int w, int h, const Color* pixels, const RectI& source); + void add_entry(u64 id, int w, int h, const Color* pixels, const Recti& source); }; } \ No newline at end of file diff --git a/include/blah/input.h b/include/blah/input.h index 3e84e61..2c957d4 100644 --- a/include/blah/input.h +++ b/include/blah/input.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include #include @@ -392,13 +392,13 @@ namespace Blah u64 timestamp[Input::max_mouse_buttons]; // mouse position in screen coordinates - Vec2 screen_position; + Vec2f screen_position; // mouse position in pixel coordinates - Vec2 draw_position; + Vec2f draw_position; // mouse position on the window - Vec2 position; + Vec2f position; // mouse wheel value this frame Point wheel; @@ -407,7 +407,7 @@ namespace Blah void on_press(MouseButton button); // invokes a mouse movement - void on_move(const Vec2& position, const Vec2& screen_position); + void on_move(const Vec2f& position, const Vec2f& screen_position); // invokes a key release void on_release(MouseButton button); @@ -686,7 +686,7 @@ namespace Blah {} // Current Value, -1 to 1 - Vec2 value() const; + Vec2f value() const; // Current value, either -1, 0, or 1 Point sign() const; @@ -735,14 +735,18 @@ namespace Blah // Input State for the previous frame extern InputState last_state; + // Key-Repeating intervals + extern float repeat_delay; + extern float repeat_interval; + // Gets the Mouse Position - Vec2 mouse(); + Vec2f mouse(); // Gets the Draw Mouse Position (Mouse Position / Window Size * Draw Size) - Vec2 mouse_draw(); + Vec2f mouse_draw(); // Gets the Mouse Position in Screen Coordinates - Vec2 mouse_screen(); + Vec2f mouse_screen(); // Checks if the given Mouse Button is pressed bool pressed(MouseButton button); @@ -765,6 +769,9 @@ namespace Blah // Checks if the keyboard key was released this frame bool released(Key key); + // Pressed or repeating on-interval + bool repeating(Key key); + // Checks if the Left or Right Ctrl Key is down bool ctrl(); @@ -780,6 +787,12 @@ namespace Blah // returns a string name of the button const char* name_of(Button button); + // gets the string contents of the clipboard + const String& get_clipboard(); + + // sets the string contents of the clipboard + void set_clipboard(const String& text); + // registers a new binding ButtonBindingRef register_binding(const ButtonBinding& binding); diff --git a/include/blah/numerics/calc.h b/include/blah/numerics/calc.h index 37ac382..afe519a 100644 --- a/include/blah/numerics/calc.h +++ b/include/blah/numerics/calc.h @@ -3,8 +3,6 @@ namespace Blah { - struct Vec2; - namespace Calc { constexpr float PI = 3.141592653f; @@ -14,20 +12,8 @@ namespace Blah constexpr float UP = PI / -2; constexpr float DOWN = PI / 2; - float rand_float(float min, float maxExc); - - float rand_float(float maxExc); - - int rand_int(int min, int maxExc); - - int rand_int(int maxExc); - - int rand_int(); - float approach(float t, float target, float delta); - Vec2 approach(const Vec2& t, const Vec2& target, float delta); - float map(float t, float old_min, float old_max, float new_min, float new_max); float clamped_map(float t, float old_min, float old_max, float new_min, float new_max); @@ -40,8 +26,8 @@ namespace Blah float abs(float x); - template - T clamp(T value, T min, T max) { return value < min ? min : (value > max ? max : value); } + template + T clamp(T value, TMin min, TMax max) { return value < min ? static_cast(min) : (value > max ? static_cast(max) : value); } template T min(T a, T b) { return (T)(a < b ? a : b); } diff --git a/include/blah/numerics/circle.h b/include/blah/numerics/circle.h deleted file mode 100644 index 86c0a33..0000000 --- a/include/blah/numerics/circle.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include - -namespace Blah -{ - struct Circle - { - Vec2 center; - float radius; - - constexpr Circle() - : center(), radius(0) {} - - constexpr Circle(Vec2 center, float radius) - : center(center), radius(radius) {} - - constexpr Circle(float x, float y, float radius) - : center(x, y), radius(radius) {} - - 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); - } - }; -} \ No newline at end of file diff --git a/include/blah/numerics/color.h b/include/blah/numerics/color.h index 9c00c31..cfaf334 100644 --- a/include/blah/numerics/color.h +++ b/include/blah/numerics/color.h @@ -1,8 +1,7 @@ #pragma once #include #include -#include -#include +#include #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))) @@ -42,19 +41,19 @@ namespace Blah , b(b) , a(a) {} - constexpr Color(const Vec3& vec3) + constexpr Color(const Vec3f& 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) + constexpr Color(const Vec3f& 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) + constexpr Color(const Vec4f& vec4) : r((int)(vec4.x * 255)) , g((int)(vec4.y * 255)) , b((int)(vec4.z * 255)) @@ -99,15 +98,15 @@ namespace Blah String to_hex_rgb() const; // Converts the Color to a Vec3 (RGB) - constexpr Vec3 to_vec3() const + constexpr Vec3f to_vec3() const { - return Vec3(r / 255.0f, g / 255.0f, b / 255.0f); + return Vec3f(r / 255.0f, g / 255.0f, b / 255.0f); } // Converts the Color to a Vec4 (RGBA) - constexpr Vec4 to_vec4() const + constexpr Vec4f to_vec4() const { - return Vec4(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); + return Vec4f(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f); } // Convers the Color to a u32 @@ -120,6 +119,15 @@ namespace Blah (u32)a; } + // Convers the Color to a u32 + constexpr u32 to_rgb() const + { + return + ((u32)r << 16) | + ((u32)g << 8) | + (u32)b; + } + // Returns a RGBA Color representation of the integer value static constexpr Color from_rgba(u32 value) { @@ -198,16 +206,6 @@ 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 diff --git a/include/blah/numerics/line.h b/include/blah/numerics/line.h deleted file mode 100644 index 301a218..0000000 --- a/include/blah/numerics/line.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include - -namespace Blah -{ - struct Rect; - - struct Line - { - Vec2 a; - Vec2 b; - - 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; - - Vec2 closest_point(const Vec2& pt) const; - bool intersects(const Rect& rect) const; - bool intersects(const Rect& rect, Vec2* out_intersection_point) const; - bool intersects(const Line& line) const; - bool intersects(const Line& line, Vec2* out_intersection_point) 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; - } - - 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); - } - }; -} \ No newline at end of file diff --git a/include/blah/numerics/mat3x2.h b/include/blah/numerics/mat3x2.h deleted file mode 100644 index d0f7e03..0000000 --- a/include/blah/numerics/mat3x2.h +++ /dev/null @@ -1,133 +0,0 @@ -#pragma once - -namespace Blah -{ - struct Vec2; - - struct 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) {} - - 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 constexpr Mat3x2 create_translation(float x, float y) - { - return Mat3x2(1, 0, 0, 1, x, y); - } - - static constexpr Mat3x2 create_scale(float scale) - { - return Mat3x2(scale, 0, 0, scale, 0, 0); - } - - static Mat3x2 create_scale(float x, float y) - { - return Mat3x2(x, 0, 0, y, 0, 0); - } - - static Mat3x2 create_scale(const Vec2& scale); - static Mat3x2 create_scale(float scale, const Vec2& center_point); - static Mat3x2 create_scale(const Vec2& scale, const Vec2& center_point); - static Mat3x2 create_scale(float scale_x, float scale_y, const Vec2& center_point); - - static Mat3x2 create_rotation(float radians); - - static Mat3x2 create_transform(const Vec2& position, const Vec2& origin, const Vec2& scale, float rotation); - - 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); -} \ No newline at end of file diff --git a/include/blah/numerics/mat4x4.h b/include/blah/numerics/mat4x4.h deleted file mode 100644 index 1cdd5f2..0000000 --- a/include/blah/numerics/mat4x4.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once -#include "vec3.h" - -namespace Blah -{ - struct 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; - - 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); - - - static const Mat4x4 identity; - - static Mat4x4 create_ortho(float width, float height, float z_near_plane, float z_far_plane); - static Mat4x4 create_ortho_offcenter(float left, float right, float bottom, float top, float z_near_plane, float z_far_plane); - static Mat4x4 create_perspective(float field_of_view, float ratio, float z_near_plane, float z_far_plane); - static Mat4x4 create_translation(float x, float y, float z); - static Mat4x4 create_scale(float x, float y, float z); - static Mat4x4 create_lookat(Vec3 position, Vec3 target, Vec3 up); - - - Mat4x4 operator* (const Mat4x4& rhs); - }; -} \ No newline at end of file diff --git a/include/blah/numerics/point.h b/include/blah/numerics/point.h deleted file mode 100644 index a66063a..0000000 --- a/include/blah/numerics/point.h +++ /dev/null @@ -1,117 +0,0 @@ -#pragma once -#include - -namespace Blah -{ - struct Point - { - int x; - int y; - - constexpr Point() - : x(0), y(0) {} - - constexpr Point(int x, int y) - : x(x), y(y) {} - - constexpr Point operator +(const Point rhs) const - { - return Point(x + rhs.x, y + rhs.y); - } - - constexpr Point operator -(const Point rhs) const - { - return Point(x - rhs.x, y - rhs.y); - } - - 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; - static const Point right; - static const Point up; - static const Point down; - static const Point left; - 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); -} \ No newline at end of file diff --git a/include/blah/numerics/quad.h b/include/blah/numerics/quad.h deleted file mode 100644 index 94dbc3d..0000000 --- a/include/blah/numerics/quad.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include - -namespace Blah -{ - struct Quad - { - Vec2 a; - Vec2 b; - Vec2 c; - 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) {} - - 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; - } - }; -} \ No newline at end of file diff --git a/include/blah/numerics/rect.h b/include/blah/numerics/rect.h deleted file mode 100644 index a3afee8..0000000 --- a/include/blah/numerics/rect.h +++ /dev/null @@ -1,173 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include - -namespace Blah -{ - struct Rect - { - float x; - float y; - float w; - float h; - - constexpr Rect() - : x(0), y(0), w(0), h(0) {} - - constexpr Rect(float x, float y, float w, float h) - : x(x), y(y), w(w), h(h) {} - - constexpr Rect(Vec2 pos, Vec2 size) - : x(pos.x), y(pos.y), w(size.x), h(size.y) {} - - constexpr Rect(const RectI& r) - : x(static_cast(r.x)), y(static_cast(r.y)), w(static_cast(r.w)), h(static_cast(r.h)) {} - - 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; } - - 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; } - - 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); } - - 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; - } - - Rect overlap_rect(const Rect& other) const; - - bool intersects(const Line& line) const; - bool intersects(const Line& line, Vec2* out_intersection_point) const; - bool intersects(const Vec2& line_from, const Vec2& line_to) const; - bool intersects(const Vec2& line_from, const Vec2& line_to, Vec2* out_intersection_point) const; - - Vec2 intersection_point(const Line& line) const; - Vec2 intersection_point(const Vec2& line_from, const Vec2& line_to) const; - - constexpr Rect scale(float s) const - { - return Rect(x * s, y * s, w * s, h * s); - } - - constexpr Rect scale(float sx, float sy) const - { - return Rect(x * sx, y * sy, w * sx, h * sy); - } - - constexpr Rect inflate(float amount) const - { - return Rect(x - amount, y - amount, w + amount * 2, h + amount * 2); - } - - // 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; - - 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); - } - }; -} diff --git a/include/blah/numerics/rectI.h b/include/blah/numerics/rectI.h deleted file mode 100644 index d05acda..0000000 --- a/include/blah/numerics/rectI.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -namespace Blah -{ - struct Point; - struct Rect; - struct Vec2; - - struct RectI - { - int x; - int y; - int w; - int h; - - RectI(); - RectI(int rx, int ry, int rw, int rh); - RectI(Point pos, Point size); - - int left() const; - int right() const; - int top() const; - int bottom() const; - int center_x() const; - int center_y() const; - - Point center() const; - Point top_left() const; - Point top_right() const; - Point bottom_left() const; - Point bottom_right() const; - - bool overlaps(const RectI& other) const; - RectI overlap_rect(const Rect& against) const; - - bool contains(const Point& pt) const; - bool contains(const Vec2& pt) const; - - /* - 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 Point& pt) const; - char get_sector(const Vec2& pt) const; - - bool operator==(const RectI& rhs) const; - bool operator!=(const RectI& rhs) const; - - RectI operator+(const Point& rhs) const; - RectI operator-(const Point& rhs) const; - RectI operator*(const int& rhs) const; - RectI operator/(const int& rhs) const; - RectI& operator+=(const Point& rhs); - RectI& operator-=(const Point& rhs); - }; -} \ No newline at end of file diff --git a/include/blah/numerics/spatial.h b/include/blah/numerics/spatial.h new file mode 100644 index 0000000..e9b6b8b --- /dev/null +++ b/include/blah/numerics/spatial.h @@ -0,0 +1,1300 @@ +#pragma once +#include +#include + +namespace Blah +{ + static constexpr double epsilon = 0.000001; + + template struct Vec2; + template struct Vec3; + template struct Vec4; + template struct Mat3x2; + template struct Mat4x4; + template struct Rect; + template struct Quad; + template struct Line; + template struct Circle; + + using Vec2f = Vec2; + using Vec2d = Vec2; + using Vec2i = Vec2; + using Point = Vec2; + using Vec3f = Vec3; + using Vec3d = Vec3; + using Vec4f = Vec4; + using Vec4d = Vec4; + using Mat3x2f = Mat3x2; + using Mat3x2d = Mat3x2; + using Mat4x4f = Mat4x4; + using Mat4x4d = Mat4x4; + using Rectf = Rect; + using Rectd = Rect; + using Recti = Rect; + using Quadf = Quad; + using Quadd = Quad; + using Linef = Line; + using Lined = Line; + using Circlef = Circle; + using Circled = Circle; + + template + struct Vec2 + { + T x; + T y; + + constexpr Vec2(); + + template + constexpr Vec2(X x, Y y); + + template + constexpr Vec2(const Vec2& vector); + + constexpr Vec2 operator+(const Vec2& rhs) const; + constexpr Vec2 operator-(const Vec2& rhs) const; + constexpr Vec2 operator/(const T rhs) const; + constexpr Vec2 operator*(const T rhs) const; + constexpr Vec2 operator*(const Vec2& rhs); + constexpr Vec2 operator-() const; + constexpr Vec2& operator+=(const Vec2& rhs); + constexpr Vec2& operator-=(const Vec2& rhs); + constexpr Vec2& operator/=(const Vec2& rhs); + constexpr Vec2& operator*=(const Vec2& rhs); + constexpr Vec2& operator/=(T rhs); + constexpr Vec2& operator*=(T rhs); + constexpr bool operator==(const Vec2& rhs) const; + constexpr bool operator!=(const Vec2& rhs) const; + + constexpr Vec2 abs() const; + Vec2 normal() const; + constexpr Vec2 turn_right() const; + constexpr Vec2 turn_left() const; + T length() const; + constexpr T length_squared() const; + T angle() const; + static constexpr T dot(const Vec2& a, const Vec2& b); + static constexpr Vec2 transform(const Vec2& vec, const Mat3x2& matrix); + static constexpr Vec2 transform_normal(const Vec2& vec, const Mat3x2& matrix); + static Vec2 from_angle(T radians, T length = 1); + static constexpr Vec2 approach(const Vec2& t, const Vec2& target, T delta); + static constexpr Vec2 lerp(const Vec2& a, const Vec2& b, T t); + static constexpr Vec2 lerp_bezier(const Vec2& a, const Vec2& b, const Vec2& end, T t); + static constexpr Vec2 lerp_bezier(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& end, T t); + static constexpr Vec2 reflect(const Vec2& vector, const Vec2& normal); + static constexpr Vec2 min(const Vec2& a, const Vec2& b); + static constexpr Vec2 max(const Vec2& a, const Vec2& b); + + static const Vec2 unit_x; + static const Vec2 unit_y; + static const Vec2 right; + static const Vec2 up; + static const Vec2 down; + static const Vec2 left; + static const Vec2 zero; + static const Vec2 one; + }; + + template const Vec2 Vec2::unit_x = Vec2(1, 0); + template const Vec2 Vec2::unit_y = Vec2(0, 1); + template const Vec2 Vec2::right = Vec2(1, 0); + template const Vec2 Vec2::up = Vec2(0, -1); + template const Vec2 Vec2::down = Vec2(0, 1); + template const Vec2 Vec2::left = Vec2(-1, 0); + template const Vec2 Vec2::zero = Vec2(0, 0); + template const Vec2 Vec2::one = Vec2(1, 1); + + template + struct Vec3 + { + T x; + T y; + T z; + + constexpr Vec3(); + + template + constexpr Vec3(X x, Y y, Z z); + + template + constexpr Vec3(const Vec3& vector); + + constexpr Vec3 operator +(const Vec3& rhs) const; + constexpr Vec3 operator -(const Vec3& rhs) const; + + T length() const; + Vec3 normal() const; + + static constexpr T dot(const Vec3& a, const Vec3& b); + static constexpr Vec3 cross(const Vec3& a, const Vec3& b); + }; + + template + struct Vec4 + { + T x; + T y; + T z; + T w; + + constexpr Vec4(); + + template + constexpr Vec4(X x, Y y, Z z, W w); + + template + constexpr Vec4(const Vec4& vector); + }; + + template + struct Rect + { + T x; + T y; + T w; + T h; + + constexpr Rect(); + constexpr Rect(T x, T y, T w, T h); + + template + constexpr Rect(X x, Y y, W w, H h); + + template + constexpr Rect(const Rect& rect); + + constexpr Rect operator+(const Vec2& rhs) const; + constexpr Rect operator-(const Vec2& rhs) const; + constexpr Rect& operator+=(const Vec2& rhs); + constexpr Rect& operator-=(const Vec2& rhs); + constexpr bool operator==(const Rect& rhs) const; + constexpr bool operator!=(const Rect& rhs) const; + + constexpr T left() const; + constexpr T right() const; + constexpr T top() const; + constexpr T bottom() const; + constexpr Vec2 center() const; + constexpr T center_x() const; + constexpr T center_y() const; + constexpr Vec2 top_left() const; + constexpr Vec2 top_right() const; + constexpr Vec2 bottom_right() const; + constexpr Vec2 bottom_left() const; + constexpr Vec2 center_left() const; + constexpr Vec2 center_right() const; + constexpr Vec2 middle_top() const; + constexpr Vec2 middle_bottom() const; + constexpr Line left_line() const; + constexpr Line right_line() const; + constexpr Line top_line() const; + constexpr Line bottom_line() const; + + constexpr bool contains(const Vec2& pt) const; + constexpr bool overlaps(const Rect& rect) const; + constexpr Rect overlap_rect(const Rect& other) const; + constexpr bool intersects(const Line& line) const; + constexpr bool intersects(const Line& line, Vec2* out_intersection_point) const; + constexpr bool intersects(const Vec2& line_from, const Vec2& line_to) const; + constexpr bool intersects(const Vec2& line_from, const Vec2& line_to, Vec2* out_intersection_point) const; + constexpr Vec2 intersection_point(const Line& line) const; + constexpr Vec2 intersection_point(const Vec2& line_from, const Vec2& line_to) const; + + constexpr Rect scale(T s) const; + constexpr Rect scale(T sx, T sy) const; + constexpr Rect inflate(T amount) const; + + // Rect Sectors: + // 0101 0100 0110 + // 0001 0000 0010 + // 1001 1000 1010 + // 0000 = inside rectangle, all others refer to sectors relative to the rectangle + constexpr u8 get_sector(const Vec2& pt) const; + + static constexpr Rect transform(const Rect& rect, const Mat3x2& matrix); + static constexpr Rect from_points(const Vec2& from, const Vec2& to); + }; + + template + struct Circle + { + Vec2 center; + T radius; + + constexpr Circle(); + constexpr Circle(T x, T y, T radius); + constexpr Circle(const Vec2& center, T radius); + + template + constexpr Circle(const Circle& circle); + + constexpr void project(const Vec2& axis, T* min, T* max) const; + }; + + template + struct Quad + { + Vec2 a; + Vec2 b; + Vec2 c; + Vec2 d; + + constexpr Quad(); + constexpr Quad(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d); + + constexpr void project(const Vec2& axis, T* min, T* max) const; + }; + + template + struct Line + { + Vec2 a; + Vec2 b; + + constexpr Line(); + constexpr Line(const Vec2& a, const Vec2& b); + constexpr Line(T x0, T y0, T x1, T y1); + + constexpr Rect bounds() const; + constexpr Vec2 closest_point(const Vec2& pt) const; + constexpr bool intersects(const Rect& rect, Vec2* out_intersection_point = nullptr) const; + constexpr bool intersects(const Line& line, Vec2* out_intersection_point = nullptr) const; + + constexpr void project(const Vec2& axis, T* min, T* max) const; + + constexpr Line operator +(const Vec2& rhs) const; + constexpr Line operator -(const Vec2& rhs) const; + }; + + template + struct Mat3x2 + { + T m11; + T m12; + T m21; + T m22; + T m31; + T m32; + + constexpr Mat3x2(); + constexpr Mat3x2(T m11, T m12, T m21, T m22, T m31, T m32); + + template + constexpr Mat3x2(const Mat3x2& matrix); + + static const Mat3x2 identity; + + constexpr Mat3x2 invert() const; + T scaling_factor() const; + + static constexpr Mat3x2 create_translation(const Vec2& position); + static constexpr Mat3x2 create_translation(T x, T y); + static constexpr Mat3x2 create_scale(T scale); + static constexpr Mat3x2 create_scale(T x, T y); + static constexpr Mat3x2 create_scale(const Vec2& scale); + static constexpr Mat3x2 create_scale(T scale, const Vec2& center_point); + static constexpr Mat3x2 create_scale(const Vec2& scale, const Vec2& center_point); + static constexpr Mat3x2 create_scale(T scale_x, T scale_y, const Vec2& center_point); + static Mat3x2 create_rotation(T radians); + static Mat3x2 create_transform(const Vec2& position, const Vec2& origin, const Vec2& scale, T rotation); + static constexpr Mat3x2 add(const Mat3x2& a, const Mat3x2& b); + static constexpr Mat3x2 subtract(const Mat3x2& a, const Mat3x2& b); + static constexpr Mat3x2 multiply(const Mat3x2& a, const Mat3x2& b); + + constexpr Mat3x2 operator *(const Mat3x2& rhs) const; + constexpr Mat3x2 operator +(const Mat3x2& rhs) const; + constexpr Mat3x2 operator -(const Mat3x2& rhs) const; + constexpr Mat3x2& operator *=(const Mat3x2& rhs); + constexpr bool operator==(const Mat3x2& rhs); + constexpr bool operator!=(const Mat3x2& rhs); + }; + + template const Mat3x2 Mat3x2::identity = Mat3x2(1, 0, 0, 1, 0, 0); + + template + struct Mat4x4 + { + T m11; + T m12; + T m13; + T m14; + + T m21; + T m22; + T m23; + T m24; + + T m31; + T m32; + T m33; + T m34; + + T m41; + T m42; + T m43; + T m44; + + Mat4x4(); + Mat4x4( + T m11, T m12, T m13, T m14, + T m21, T m22, T m23, T m24, + T m31, T m32, T m33, T m34, + T m41, T m42, T m43, T m44); + + static const Mat4x4 identity; + + static constexpr Mat4x4 create_ortho(T width, T height, T z_near_plane, T z_far_plane); + static constexpr Mat4x4 create_ortho_offcenter(T left, T right, T bottom, T top, T z_near_plane, T z_far_plane); + static Mat4x4 create_perspective(T field_of_view, T ratio, T z_near_plane, T z_far_plane); + static constexpr Mat4x4 create_translation(T x, T y, T z); + static constexpr Mat4x4 create_scale(T x, T y, T z); + static Mat4x4 create_lookat(const Vec3& position, const Vec3& target, const Vec3& up); + + constexpr Mat4x4 operator* (const Mat4x4& rhs); + }; + + template 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); + + template + constexpr Vec2::Vec2() + : x(0), y(0) {} + + template + template + constexpr Vec2::Vec2(X x, Y y) + : x(static_cast(x)), y(static_cast(y)) {} + + template + template + constexpr Vec2::Vec2(const Vec2& vector) + : x(static_cast(vector.x)), y(static_cast(vector.y)) {} + + template + constexpr Vec2 Vec2::operator+(const Vec2& rhs) const { + return Vec2(x + rhs.x, y + rhs.y); + } + template + constexpr Vec2 Vec2::operator-(const Vec2& rhs) const { + return Vec2(x - rhs.x, y - rhs.y); + } + + template + constexpr Vec2 Vec2::operator-() const { + return Vec2(-x, -y); + } + + template + constexpr Vec2 Vec2::operator/(const T rhs) const { + return Vec2(x / rhs, y / rhs); + } + + template + constexpr Vec2 Vec2::operator* (const T rhs) const { + return Vec2(x * rhs, y * rhs); + } + + template + constexpr Vec2 Vec2::operator *(const Vec2& rhs) { + return Vec2(x * rhs.x, y * rhs.y); + } + + template + constexpr Vec2& Vec2::operator += (const Vec2& rhs) { + x += rhs.x; + y += rhs.y; + return *this; + } + + template + constexpr Vec2& Vec2::operator -= (const Vec2& rhs) { + x -= rhs.x; + y -= rhs.y; + return *this; + } + + template + constexpr Vec2& Vec2::operator /= (T rhs) { + x /= rhs; + y /= rhs; + return *this; + } + + template + constexpr Vec2& Vec2::operator *= (const Vec2 & rhs) { + x *= rhs.x; + y *= rhs.y; + return this; + } + + template + constexpr Vec2& Vec2::operator *=(T rhs) { + x *= rhs; + y *= rhs; + return *this; + } + + template + constexpr bool Vec2::operator ==(const Vec2& rhs) const { + return std::abs(x - rhs.x) < epsilon && std::abs(y - rhs.y) < epsilon; + } + + template + constexpr bool Vec2::operator !=(const Vec2& rhs) const { + return !(*this == rhs); + } + + template + constexpr Vec2 Vec2::abs() const { + return Vec2(std::abs(x), std::abs(y)); + } + + template + Vec2 Vec2::normal() const { + auto len = std::sqrt(x * x + y * y); + return Vec2(x / len, y / len); + } + + template + constexpr Vec2 Vec2::turn_right() const { + return Vec2(-y, x); + } + + template + constexpr Vec2 Vec2::turn_left() const { + return Vec2(y, -x); + } + + template + T Vec2::length() const { + return std::sqrt(x * x + y * y); + } + + template + constexpr T Vec2::length_squared() const { + return x * x + y * y; + } + + template + T Vec2::angle() const { + return std::atan2(y, x); + } + + template + constexpr T Vec2::dot(const Vec2& a, const Vec2& b) { + return a.x * b.x + a.y * b.y; + } + + template + constexpr 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); + } + + template + constexpr Vec2 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); + } + + template + Vec2 Vec2::from_angle(T radians, T length) { + return Vec2( + std::cos(radians) * length, + std::sin(radians) * length); + } + + template + constexpr Vec2 Vec2::approach(const Vec2& value, const Vec2& target, T delta) { + if ((value - target).length_squared() <= delta * delta) + return target; + return value + (target - value).normal() * delta; + } + + template + constexpr Vec2 Vec2::lerp(const Vec2& a, const Vec2& b, T t) { + if (t == 0) + return a; + else if (t == 1) + return b; + else + return a + (b - a) * t; + } + + template + constexpr Vec2 Vec2::lerp_bezier(const Vec2& a, const Vec2& b, const Vec2& end, T t) { + return lerp(lerp(a, b, t), lerp(b, end, t), t); + } + + template + constexpr Vec2 Vec2::lerp_bezier(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& end, T t) { + return lerp_bezier(lerp(a, b, t), lerp(b, c, t), lerp(c, end, t), t); + } + + template + constexpr Vec2 Vec2::reflect(const Vec2& vector, const Vec2& normal) { + auto dot = vector.x * normal.x + vector.y * normal.y; + return Vec2( + vector.x - 2 * dot * normal.x, + vector.y - 2 * dot * normal.y); + } + + template + constexpr Vec2 Vec2::min(const Vec2& a, const Vec2& b) { + return Vec2(std::fmin(a.x, b.x), std::fmin(a.y, b.y)); + } + + template + constexpr Vec2 Vec2::max(const Vec2& a, const Vec2& b) { + return Vec2(std::fmax(a.x, b.x), std::fmax(a.y, b.y)); + } + + template + template + constexpr Vec3::Vec3(X x, Y y, Z z) + : x(static_cast(x)), y(static_cast(y)), z(static_cast(z)) {} + + template + template + constexpr Vec3::Vec3(const Vec3& vector) + : x(static_cast(vector.x)), y(static_cast(vector.y)), z(static_cast(vector.z)) {} + + template + constexpr Vec3 Vec3::operator+(const Vec3& rhs) const { + return Vec3(x + rhs.x, y + rhs.y, z + rhs.z); + } + + template + constexpr Vec3 Vec3::operator-(const Vec3& rhs) const { + return Vec3(x - rhs.x, y - rhs.y, z - rhs.z); + } + + template + T Vec3::length() const { + return std::sqrt(x * x + y * y + z * z); + } + + template + Vec3 Vec3::normal() const { + return Vec3(x, y, z) / length(); + } + + template + constexpr T Vec3::dot(const Vec3& a, const Vec3& b) { + return a.x * b.x + a.y * b.y + a.z * b.z; + } + + template + constexpr Vec3 Vec3::cross(const Vec3& a, const Vec3& b) { + return Vec3( + a.y * b.z - a.z * b.y, + a.z * b.x - a.x * b.z, + a.x * b.y - a.y * b.x); + } + + template + template + constexpr Vec4::Vec4(X x, Y y, Z z, W w) + : x(static_cast(x)), y(static_cast(y)), z(static_cast(z)), w(static_cast(w)) {} + + template + template + constexpr Vec4::Vec4(const Vec4& vector) + : x(static_cast(vector.x)), y(static_cast(vector.y)), z(static_cast(vector.z)), w(static_cast(vector.w)) {} + + template + constexpr Rect::Rect() + : x(0), y(0), w(0), h(0) {} + + template + constexpr Rect::Rect(T x, T y, T w, T h) + : x(x), y(y), w(w), h(h) {} + + template + template + constexpr Rect::Rect(X x, Y y, W w, H h) + : x(static_cast(x)), y(static_cast(y)), w(static_cast(w)), h(static_cast(h)) {} + + template + template + constexpr Rect::Rect(const Rect& rect) + : x(static_cast(rect.x)), y(static_cast(rect.y)), w(static_cast(rect.w)), h(static_cast(rect.h)) {} + + template + constexpr Rect Rect::operator+(const Vec2& rhs) const { + return Rect(x + rhs.x, y + rhs.y, w, h); + } + + template + constexpr Rect Rect::operator-(const Vec2& rhs) const { + return Rect(x - rhs.x, y - rhs.y, w, h); + } + + template + constexpr Rect& Rect::operator+=(const Vec2& rhs) { + x += rhs.x; + y += rhs.y; + return *this; + } + + template + constexpr Rect& Rect::operator-=(const Vec2& rhs) { + x -= rhs.x; + y -= rhs.y; + return *this; + } + + template + constexpr bool Rect::operator==(const Rect& rhs) const { + return std::abs(x - rhs.x) < epsilon && std::abs(y - rhs.y) < epsilon && std::abs(w - rhs.w) < epsilon && std::abs(h - rhs.h) < epsilon; + } + + template + constexpr bool Rect::operator!=(const Rect& rhs) const { + return !(*this == rhs); + } + + template + constexpr T Rect::left() const { return x; } + template + constexpr T Rect::right() const { return x + w; } + template + constexpr T Rect::top() const { return y; } + template + constexpr T Rect::bottom() const { return y + h; } + + template + constexpr Vec2 Rect::center() const { return Vec2(x + w / 2, y + h / 2); } + template + constexpr T Rect::center_x() const { return x + w / 2; } + template + constexpr T Rect::center_y() const { return y + h / 2; } + + template + constexpr Vec2 Rect::top_left() const { return Vec2(x, y); } + template + constexpr Vec2 Rect::top_right() const { return Vec2(x + w, y); } + template + constexpr Vec2 Rect::bottom_right() const { return Vec2(x + w, y + h); } + template + constexpr Vec2 Rect::bottom_left() const { return Vec2(x, y + h); } + + template + constexpr Vec2 Rect::center_left() const { return Vec2(x, y + h / 2); } + template + constexpr Vec2 Rect::center_right() const { return Vec2(x + w, y + h / 2); } + template + constexpr Vec2 Rect::middle_top() const { return Vec2(x + w / 2, y); } + template + constexpr Vec2 Rect::middle_bottom() const { return Vec2(x + w / 2, y + h); } + + template + constexpr Line Rect::left_line() const { return Line(left(), top(), left(), bottom()); } + template + constexpr Line Rect::right_line() const { return Line(right(), top(), right(), bottom()); } + template + constexpr Line Rect::top_line() const { return Line(left(), top(), right(), top()); } + template + constexpr Line Rect::bottom_line() const { return Line(left(), bottom(), right(), bottom()); } + + template + constexpr bool Rect::contains(const Vec2& pt) const { + return pt.x >= x && pt.x < x + w && pt.y >= y && pt.y < y + h; + } + + template + constexpr 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; + } + + template + constexpr Rect Rect::overlap_rect(const Rect& against) const { + Rect result; + + if (x + w >= against.x && x < against.x + against.w) + { + result.x = std::fmax(x, against.x); + result.w = std::fmin(x + w, against.x + against.w) - result.x; + } + + if (y + h >= against.y && y < against.y + against.h) + { + result.y = std::fmax(y, against.y); + result.h = std::fmin(y + h, against.y + against.h) - result.y; + } + + return result; + } + + template + constexpr bool Rect::intersects(const Line& line) const { + return line.intersects(*this); + } + + template + constexpr bool Rect::intersects(const Line& line, Vec2* out_intersection_point) const { + return line.intersects(*this, out_intersection_point); + } + + template + constexpr bool Rect::intersects(const Vec2& line_from, const Vec2& line_to) const { + return intersects(Line(line_from, line_to)); + } + + template + constexpr 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); + } + + template + constexpr Vec2 Rect::intersection_point(const Line& line) const { + Vec2 ret; + if (line.intersects(*this, &ret)) + return ret; + return Vec2::zero; + } + + template + constexpr 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; + return Vec2::zero; + } + + template + constexpr Rect Rect::scale(T s) const { + return Rect(x * s, y * s, w * s, h * s); + } + + template + constexpr Rect Rect::scale(T sx, T sy) const { + return Rect(x * sx, y * sy, w * sx, h * sy); + } + + template + constexpr Rect Rect::inflate(T amount) const { + return Rect(x - amount, y - amount, w + amount * 2, h + amount * 2); + } + + template + constexpr u8 Rect::get_sector(const Vec2& pt) const + { + u8 result = 0; + if (pt.x < left()) + result |= 0b0001; + else if (pt.x >= right()) + result |= 0b0010; + if (pt.y < top()) + result |= 0b0100; + else if (pt.y >= bottom()) + result |= 0b1000; + return result; + } + + template + constexpr 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)); + } + + template + constexpr Rect Rect::from_points(const Vec2& from, const Vec2& to) { + auto min = Vec2::min(from, to); + auto max = Vec2::max(from, to); + return Rect(min.x, min.y, max.x - min.x, max.y - min.y); + } + + template + constexpr Quad::Quad() + : a(), b(), c(), d() {} + + template + constexpr Quad::Quad(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d) + : a(a), b(b), c(c), d(d) {} + + template + constexpr void Quad::project(const Vec2& axis, T* min, T* max) const { + T 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; + } + + template + constexpr Circle::Circle() + : center(0, 0), radius(0) {} + template + constexpr Circle::Circle(T x, T y, T radius) + : center(x, y), radius(radius) {} + template + constexpr Circle::Circle(const Vec2& center, T radius) + : center(center), radius(radius) {} + + template + template + constexpr Circle::Circle(const Circle& circle) + : center(Vec2(static_cast(circle.center.x), static_cast(circle.center.y))), radius(static_cast(circle.radius)) {} + + template + constexpr void Circle::project(const Vec2& axis, T* min, T* max) const + { + *min = Vec2::dot(center - axis * radius, axis); + *max = Vec2::dot(center + axis * radius, axis); + } + + template + constexpr Line::Line() + : a(0, 0), b(0, 0) {} + + template + constexpr Line::Line(T x0, T y0, T x1, T y1) + : a(x0, y0), b(x1, y1) {} + + template + constexpr Line::Line(const Vec2& a, const Vec2& b) + : a(a), b(b) {} + + template + constexpr Rect Line::bounds() const { + return Rect::from_points(a, b); + } + + template + constexpr Vec2 Line::closest_point(const Vec2& pt) const { + auto v = b - a; + auto w = pt - a; + auto t = Vec2::dot(w, v) / (v.x * v.x + v.y * v.y); + if (t < 0) t = 0; + else if (t > 1) t = 1; + return v * t + a; + } + + template + constexpr bool Line::intersects(const Rect& rect, Vec2* out_intersection_point) const + { + u8 ca = rect.get_sector(a); + u8 cb = rect.get_sector(b); + + if (ca == cb || (ca & cb) != 0) + return false; + + u8 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; + } + + template + constexpr bool Line::intersects(const Line& line, Vec2* out_intersection_point) const + { + Vec2 e = b - a; + Vec2 d = line.b - line.a; + T 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 > -epsilon && e_dot_d_perp < epsilon) + return false; + + Vec2 c = line.a - a; + T t = (c.x * d.y - c.y * d.x) / e_dot_d_perp; + if (t < 0 || t > 1) + return false; + + T u = (c.x * e.y - c.y * e.x) / e_dot_d_perp; + if (u < 0 || u > 1) + return false; + + if (out_intersection_point) + *out_intersection_point = (e * t) + a; + + return true; + } + + template + constexpr void Line::project(const Vec2& axis, T* min, T* max) const { + T 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; + } + + template + constexpr Line Line::operator+(const Vec2& rhs) const { + return Line(a + rhs, b + rhs); + } + + template + constexpr Line Line::operator-(const Vec2& rhs) const { + return Line(a - rhs, b - rhs); + } + + template + constexpr Mat3x2::Mat3x2() + : m11(0), m12(0), m21(0), m22(0), m31(0), m32(0) {} + + template + constexpr Mat3x2::Mat3x2(T m11, T m12, T m21, T m22, T m31, T m32) + : m11(m11), m12(m12), m21(m21), m22(m22), m31(m31), m32(m32) {} + + template + template + constexpr Mat3x2::Mat3x2(const Mat3x2& m) + : m11(static_cast(m.m11)), m12(static_cast(m.m12)) + , m21(static_cast(m.m21)), m22(static_cast(m.m22)) + , m31(static_cast(m.m31)), m32(static_cast(m.m32)) {} + + template + constexpr Mat3x2 Mat3x2::invert() const { + auto det = (m11 * m22) - (m21 * m12); + auto inv_det = 1 / det; + + return Mat3x2 + ( + m22 * inv_det, + -m12 * inv_det, + -m21 * inv_det, + m11 * inv_det, + (m21 * m32 - m31 * m22) * inv_det, + (m31 * m12 - m11 * m32) * inv_det + ); + } + + template + T Mat3x2::scaling_factor() const { + return std::sqrt(m11 * m11 + m12 * m12); + } + + template + constexpr Mat3x2 Mat3x2::create_translation(const Vec2& position) { + return Mat3x2(1, 0, 0, 1, position.x, position.y); + } + + template + constexpr Mat3x2 Mat3x2::create_translation(T x, T y) { + return Mat3x2(1, 0, 0, 1, x, y); + } + + template + constexpr Mat3x2 Mat3x2::create_scale(T scale) { + return Mat3x2(scale, 0, 0, scale, 0, 0); + } + + template + constexpr Mat3x2 Mat3x2::create_scale(T x, T y) { + return Mat3x2(x, 0, 0, y, 0, 0); + } + + template + constexpr Mat3x2 Mat3x2::create_scale(const Vec2& scale) { + return Mat3x2(scale.x, 0, 0, scale.y, 0, 0); + } + + template + constexpr Mat3x2 Mat3x2::create_scale(T scale, const Vec2& center_point) { + auto tx = center_point.x * (1 - scale); + auto ty = center_point.y * (1 - scale); + + Mat3x2 result; + result.m11 = scale; + result.m12 = 0; + result.m21 = 0; + result.m22 = scale; + result.m31 = tx; + result.m32 = ty; + return result; + } + + template + constexpr Mat3x2 Mat3x2::create_scale(const Vec2& scale, const Vec2& center_point) { + auto tx = center_point.x * (1 - scale.x); + auto ty = center_point.y * (1 - scale.y); + + Mat3x2 result; + result.m11 = scale.x; + result.m12 = 0; + result.m21 = 0; + result.m22 = scale.y; + result.m31 = tx; + result.m32 = ty; + return result; + } + + template + constexpr Mat3x2 Mat3x2::create_scale(T scale_x, T scale_y, const Vec2& center_point) { + auto tx = center_point.x * (1 - scale_x); + auto ty = center_point.y * (1 - scale_y); + + Mat3x2 result; + result.m11 = scale_x; + result.m12 = 0; + result.m21 = 0; + result.m22 = scale_y; + result.m31 = tx; + result.m32 = ty; + return result; + } + + template + Mat3x2 Mat3x2::create_rotation(T radians) { + auto c = std::cos(radians); + auto s = std::sin(radians); + return Mat3x2(c, s, -s, c, 0, 0); + } + + template + Mat3x2 Mat3x2::create_transform(const Vec2& position, const Vec2& origin, const Vec2& scale, T 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; + } + + template + constexpr 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); + } + + template + constexpr 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); + } + + template + constexpr 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); + } + + template + constexpr Mat3x2 Mat3x2::operator *(const Mat3x2& rhs) const { + return multiply(*this, rhs); + } + + template + constexpr Mat3x2 Mat3x2::operator +(const Mat3x2& rhs) const { + return add(*this, rhs); + } + + template + constexpr Mat3x2 Mat3x2::operator -(const Mat3x2& rhs) const { + return subtract(*this, rhs); + } + + template + constexpr Mat3x2& Mat3x2::operator *=(const Mat3x2& rhs) { + *this = multiply(*this, rhs); + return *this; + } + + template + constexpr bool Mat3x2::operator==(const Mat3x2& rhs) { + return + std::abs(m11 - rhs.m11) < epsilon && + std::abs(m12 - rhs.m12) < epsilon && + std::abs(m21 - rhs.m21) < epsilon && + std::abs(m22 - rhs.m22) < epsilon && + std::abs(m31 - rhs.m31) < epsilon && + std::abs(m32 - rhs.m32) < epsilon; + } + + template + constexpr bool Mat3x2::operator!=(const Mat3x2& rhs) { + return !(*this == rhs); + } + + template + 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) {} + + template + Mat4x4::Mat4x4( + T m11, T m12, T m13, T m14, + T m21, T m22, T m23, T m24, + T m31, T m32, T m33, T m34, + T m41, T m42, T m43, T 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) {} + + template + constexpr Mat4x4 Mat4x4::create_ortho(T width, T height, T z_near_plane, T z_far_plane) { + Mat4x4 result = identity; + result.m11 = 2 / width; + result.m12 = result.m13 = result.m14 = 0; + result.m22 = -2 / height; + result.m21 = result.m23 = result.m24 = 0; + result.m33 = 1 / (z_near_plane - z_far_plane); + result.m31 = result.m32 = result.m34 = 0; + result.m41 = result.m42 = 0; + result.m43 = z_near_plane / (z_near_plane - z_far_plane); + result.m44 = 1; + return result; + } + + template + constexpr Mat4x4 Mat4x4::create_ortho_offcenter(T left, T right, T bottom, T top, T z_near_plane, T z_far_plane) { + Mat4x4 result = identity; + result.m11 = 2 / (right - left); + result.m12 = result.m13 = result.m14 = 0; + result.m22 = 2 / (top - bottom); + result.m21 = result.m23 = result.m24 = 0; + result.m33 = 1 / (z_near_plane - z_far_plane); + result.m31 = result.m32 = result.m34 = 0; + 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; + return result; + } + + template + Mat4x4 Mat4x4::create_perspective(T field_of_view, T ratio, T z_near_plane, T z_far_plane) { + auto scale_x = 1 / std::tan(field_of_view * 0.5); + auto scale_y = scale_x / ratio; + + Mat4x4 result; + result.m11 = scale_y; + result.m12 = result.m13 = result.m14 = 0; + result.m22 = scale_x; + result.m21 = result.m23 = result.m24 = 0; + result.m31 = result.m32 = 0; + result.m33 = z_far_plane / (z_near_plane - z_far_plane); + result.m34 = -1; + result.m41 = result.m42 = result.m44 = 0; + result.m43 = z_near_plane * z_far_plane / (z_near_plane - z_far_plane); + return result; + } + + template + constexpr Mat4x4 Mat4x4::create_translation(T x, T y, T z) { + Mat4x4 result = identity; + result.m41 = x; + result.m42 = y; + result.m43 = z; + return result; + } + + template + constexpr Mat4x4 Mat4x4::create_scale(T x, T y, T z) { + Mat4x4 result = identity; + result.m11 = x; + result.m22 = y; + result.m33 = z; + return result; + } + + template + Mat4x4 Mat4x4::create_lookat(const Vec3& position, const Vec3& target, const Vec3& up) { + auto zaxis = (position - target).normal(); + auto xaxis = Vec3::cross(up, zaxis).normal(); + auto yaxis = Vec3::cross(zaxis, xaxis); + + Mat4x4 result; + result.m11 = xaxis.x; + result.m12 = yaxis.x; + result.m13 = zaxis.x; + result.m14 = 0.0f; + result.m21 = xaxis.y; + result.m22 = yaxis.y; + result.m23 = zaxis.y; + result.m24 = 0.0f; + result.m31 = xaxis.z; + result.m32 = yaxis.z; + result.m33 = zaxis.z; + result.m34 = 0.0f; + result.m41 = -Vec3::dot(xaxis, position); + result.m42 = -Vec3::dot(yaxis, position); + result.m43 = -Vec3::dot(zaxis, position); + result.m44 = 1.0f; + return result; + } + + template + constexpr 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; + } +} \ No newline at end of file diff --git a/include/blah/numerics/vec2.h b/include/blah/numerics/vec2.h deleted file mode 100644 index afe4110..0000000 --- a/include/blah/numerics/vec2.h +++ /dev/null @@ -1,312 +0,0 @@ -#pragma once -#include -#include -#include - -namespace Blah -{ - struct Vec2 - { - float x; - float y; - - 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(x)), y(y) {} - - constexpr Vec2(float x, int y) - : x(x), y(static_cast(y)) {} - - constexpr Vec2(int x, int y) - : x(static_cast(x)), y(static_cast(y)) {} - - constexpr Vec2(const Point& p) - : x(static_cast(p.x)), y(static_cast(p.y)) {} - - 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 - 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 - { - if (x == 0 && y == 0) - return Vec2(0, 0); - - const float len = Calc::sqrt((x * x) + (y * y)); - return Vec2(x / len, y / len); - } - - // 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 - { - return Calc::sqrt((x * x) + (y * y)); - } - - // Returns the squared length of the Vector - constexpr float length_squared() const - { - return (x * x) + (y * y); - } - - // Gets the perpendicular Vector (-y, x) - constexpr Vec2 perpendicular() const - { - return Vec2(-y, x); - } - - // Gets the angle, in radians, of the Vector - float angle() const - { - return Calc::atan2(y, x); - } - - // Calculates the Dot Product between two vectors - 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 constexpr float dot(float x, float y, Vec2 b) - { - return (x * b.x + y * b.y); - } - - // Calculates the Dot Product between two vectors - 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 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 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 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 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) - { - return Vec2( - Calc::cos(radians) * length, - Calc::sin(radians) * length); - } - - // Lerps between two Vectors - 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 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 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 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 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 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; - - // (0, 1) - static const Vec2 unit_y; - - // (1, 0) - static const Vec2 right; - - // (0, -1) - static const Vec2 up; - - // (0, 1) - static const Vec2 down; - - // (-1, 0) - static const Vec2 left; - - // (0, 0) - static const Vec2 zero; - - // (1, 1) - static const Vec2 one; - - // (0.707, -0.707) - static const Vec2 up_right; - - // (-0.707, -0.707) - static const Vec2 up_left; - - // (0.707, 0.707) - static const Vec2 down_right; - - // (-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); - -} \ No newline at end of file diff --git a/include/blah/numerics/vec3.h b/include/blah/numerics/vec3.h deleted file mode 100644 index d2aee3d..0000000 --- a/include/blah/numerics/vec3.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once -#include "calc.h" - -namespace Blah -{ - struct Vec3 - { - float x; - float y; - float z; - - constexpr Vec3() - : x(0), y(0), z(0) {} - - constexpr Vec3(float x, float y, float z) - : x(x), y(y), z(z) {} - - constexpr Vec3 operator +(const Vec3 rhs) const - { - return Vec3(x + rhs.x, y + rhs.y, z + rhs.z); - } - - constexpr Vec3 operator -(const Vec3 rhs) const - { - return Vec3(x + rhs.x, y + rhs.y, z + rhs.z); - } - - inline Vec3 normal() const - { - float ls = x * x + y * y + z * z; - float length = (float)Calc::sqrt(ls); - return Vec3(x / length, y / length, z / length); - } - - static constexpr float dot(Vec3 a, Vec3 b) - { - return a.x * b.x + - a.y * b.y + - a.z * b.z; - } - - static constexpr Vec3 cross(Vec3 a, Vec3 b) - { - return Vec3( - a.y * b.z - a.z * b.y, - a.z * b.x - a.x * b.z, - a.x * b.y - a.y * b.x); - } - }; -} \ No newline at end of file diff --git a/include/blah/numerics/vec4.h b/include/blah/numerics/vec4.h deleted file mode 100644 index 5c40863..0000000 --- a/include/blah/numerics/vec4.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -namespace Blah -{ - struct Vec4 - { - float x; - float y; - float z; - float 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) {} - }; -} \ No newline at end of file diff --git a/include/blah/streams/memorystream.h b/include/blah/streams/memorystream.h index b4bfc0b..d464232 100644 --- a/include/blah/streams/memorystream.h +++ b/include/blah/streams/memorystream.h @@ -9,7 +9,7 @@ namespace Blah { public: MemoryStream(); - MemoryStream(char* data, size_t length); + MemoryStream(unsigned char* data, size_t length); MemoryStream(MemoryStream&& ms) noexcept; MemoryStream& operator=(MemoryStream&& ms) noexcept; ~MemoryStream() override { m_data = nullptr; m_length = m_position = 0; } @@ -22,15 +22,15 @@ namespace Blah bool is_writable() const override; void close() override; - char* data(); - const char* data() const; + unsigned char* data(); + const unsigned char* data() const; protected: size_t read_data(void* ptr, size_t length) override; size_t write_data(const void* ptr, size_t length) override; private: - char* m_data; + unsigned char* m_data; size_t m_length; size_t m_position; }; diff --git a/include/blah/time.h b/include/blah/time.h index 9064f51..6e9bcee 100644 --- a/include/blah/time.h +++ b/include/blah/time.h @@ -53,8 +53,8 @@ namespace Blah public: Stopwatch(); void reset(); - u64 microseconds(); - u64 milliseconds(); + u64 microseconds() const; + u64 milliseconds() const; private: u64 start_time; diff --git a/src/app.cpp b/src/app.cpp index ee41b30..99b9793 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "internal/platform.h" #include "internal/graphics.h" @@ -142,6 +141,10 @@ bool App::run(const Config* c) // input Input::init(); + // prepare by updating input & platform once + Input::update_state(); + Platform::update(Input::state); + // startup if (app_config.on_startup != nullptr) app_config.on_startup(); diff --git a/src/containers/str.cpp b/src/containers/str.cpp index 0e35831..8b30f6a 100644 --- a/src/containers/str.cpp +++ b/src/containers/str.cpp @@ -218,7 +218,7 @@ Str& Str::append_utf16(const u16* start, const u16* end, bool swap_endian) const u16 surrogate_min = 0xd800u; const u16 surrogate_max = 0xdbffu; - while (start != end) + while ((end == nullptr && *start != 0) || (end != nullptr && start != end)) { u16 next = (*start++); if (swap_endian) diff --git a/src/graphics/batch.cpp b/src/graphics/batch.cpp index 7f6d13c..cddcafa 100644 --- a/src/graphics/batch.cpp +++ b/src/graphics/batch.cpp @@ -128,25 +128,22 @@ namespace namespace { - static Vec2 batch_shape_intersection(const Vec2& p0, const Vec2& p1, const Vec2& q0, const Vec2& q1) + static Vec2f batch_shape_intersection(const Vec2f& p0, const Vec2f& p1, const Vec2f& q0, const Vec2f& q1) { const auto aa = p1 - p0; const auto bb = q0 - q1; const auto cc = q0 - p0; const auto t = (bb.x * cc.y - bb.y * cc.x) / (aa.y * bb.x - aa.x * bb.y); - return Vec2(p0.x + t * (p1.x - p0.x), p0.y + t * (p1.y - p0.y)); + return Vec2f(p0.x + t * (p1.x - p0.x), p0.y + t * (p1.y - p0.y)); } } -#define MAKE_VERTEX(vert, mat, px, py, tx, ty, c, m, w, f) \ - (vert)->pos.x = ((px) * (mat).m11) + ((py) * (mat).m21) + (mat).m31; \ - (vert)->pos.y = ((px) * (mat).m12) + ((py) * (mat).m22) + (mat).m32; \ - (vert)->tex.x = tx; \ - if (m_batch.flip_vertically) \ - (vert)->tex.y = 1.0f - (ty); \ - else \ - (vert)->tex.y = ty; \ +#define MAKE_VERTEX(vert, mat, px, py, tx, ty, c, m, w, f, cast) \ + (vert)->pos.x = cast(((px) * (mat).m11) + ((py) * (mat).m21) + (mat).m31); \ + (vert)->pos.y = cast(((px) * (mat).m12) + ((py) * (mat).m22) + (mat).m32); \ + (vert)->tex.x = (tx); \ + (vert)->tex.y = m_batch.flip_vertically ? 1.0f - (ty) : (ty); \ (vert)->col = c; \ (vert)->mult = m; \ (vert)->wash = w; \ @@ -163,10 +160,17 @@ namespace *_i++ = (u32)m_vertices.size() + 2; \ *_i++ = (u32)m_vertices.size() + 3; \ Vertex* _v = m_vertices.expand(4); \ - MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \ - MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash); _v++; \ - MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash); _v++; \ - MAKE_VERTEX(_v, m_matrix, px3, py3, tx3, ty3, col3, mult, fill, wash); \ + if (integerize) { \ + MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash, std::round); _v++; \ + MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash, std::round); _v++; \ + MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash, std::round); _v++; \ + MAKE_VERTEX(_v, m_matrix, px3, py3, tx3, ty3, col3, mult, fill, wash, std::round); \ + } else { \ + MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash, float); _v++; \ + MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash, float); _v++; \ + MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash, float); _v++; \ + MAKE_VERTEX(_v, m_matrix, px3, py3, tx3, ty3, col3, mult, fill, wash, float); \ + } \ } #define PUSH_TRIANGLE(px0, py0, px1, py1, px2, py2, tx0, ty0, tx1, ty1, tx2, ty2, col0, col1, col2, mult, fill, wash) \ @@ -177,9 +181,15 @@ namespace *_i++ = (u32)m_vertices.size() + 1; \ *_i++ = (u32)m_vertices.size() + 2; \ Vertex* _v = m_vertices.expand(3); \ - MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash); _v++; \ - MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash); _v++; \ - MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash); \ + if (integerize) { \ + MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash, std::floor); _v++; \ + MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash, std::floor); _v++; \ + MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash, std::floor); \ + } else { \ + MAKE_VERTEX(_v, m_matrix, px0, py0, tx0, ty0, col0, mult, fill, wash, float); _v++; \ + MAKE_VERTEX(_v, m_matrix, px1, py1, tx1, ty1, col1, mult, fill, wash, float); _v++; \ + MAKE_VERTEX(_v, m_matrix, px2, py2, tx2, ty2, col2, mult, fill, wash, float); \ + } \ } #define INSERT_BATCH() \ @@ -213,7 +223,7 @@ Batch::~Batch() dispose(); } -void Batch::push_matrix(const Mat3x2& matrix, bool absolute) +void Batch::push_matrix(const Mat3x2f& matrix, bool absolute) { m_matrix_stack.push_back(m_matrix); if (absolute) @@ -222,33 +232,33 @@ void Batch::push_matrix(const Mat3x2& matrix, bool absolute) m_matrix = matrix * m_matrix; } -Mat3x2 Batch::pop_matrix() +Mat3x2f Batch::pop_matrix() { auto was = m_matrix; m_matrix = m_matrix_stack.pop(); return was; } -Mat3x2 Batch::peek_matrix() const +Mat3x2f Batch::peek_matrix() const { return m_matrix; } -void Batch::push_scissor(const Rect& scissor) +void Batch::push_scissor(const Rectf& scissor) { m_scissor_stack.push_back(m_batch.scissor); SET_BATCH_VAR(scissor); } -Rect Batch::pop_scissor() +Rectf Batch::pop_scissor() { - Rect was = m_batch.scissor; - Rect scissor = m_scissor_stack.pop(); + Rectf was = m_batch.scissor; + Rectf scissor = m_scissor_stack.pop(); SET_BATCH_VAR(scissor); return was; } -Rect Batch::peek_scissor() const +Rectf Batch::peek_scissor() const { return m_batch.scissor; } @@ -388,10 +398,10 @@ void Batch::render(const TargetRef& target) else size = Point(target->width(), target->height()); - render(target, Mat4x4::create_ortho_offcenter(0, (float)size.x, (float)size.y, 0, 0.01f, 1000.0f)); + render(target, Mat4x4f::create_ortho_offcenter(0, (float)size.x, (float)size.y, 0, 0.01f, 1000.0f)); } -void Batch::render(const TargetRef& target, const Mat4x4& matrix) +void Batch::render(const TargetRef& target, const Mat4x4f& matrix) { // nothing to draw if ((m_batches.size() <= 0 && m_batch.elements <= 0) || m_indices.size() <= 0) @@ -422,7 +432,7 @@ void Batch::render(const TargetRef& target, const Mat4x4& matrix) pass.target = target; pass.mesh = m_mesh; pass.has_viewport = false; - pass.viewport = Rect(); + pass.viewport = Rectf(); pass.instance_count = 0; pass.depth = Compare::None; pass.cull = Cull::None; @@ -443,7 +453,7 @@ void Batch::render(const TargetRef& target, const Mat4x4& matrix) render_single_batch(pass, m_batch, matrix); } -void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4& matrix) +void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4x4f& matrix) { // get the material pass.material = b.material; @@ -462,7 +472,7 @@ void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4 pass.material->set_sampler(0, b.sampler); // assign the matrix uniform - pass.material->set_value(matrix_uniform, &matrix.m11, 16); + pass.material->set_value(matrix_uniform, matrix); pass.blend = b.blend; pass.has_scissor = b.scissor.w >= 0 && b.scissor.h >= 0; @@ -475,7 +485,7 @@ void Batch::render_single_batch(RenderPass& pass, const DrawBatch& b, const Mat4 void Batch::clear() { - m_matrix = Mat3x2::identity; + m_matrix = Mat3x2f::identity; m_color_mode = ColorMode::Normal; m_tex_mult = 255; m_tex_wash = 0; @@ -522,22 +532,22 @@ void Batch::dispose() m_mesh.reset(); } -void Batch::line(const Vec2& from, const Vec2& to, float t, Color color) +void Batch::line(const Vec2f& from, const Vec2f& to, float t, Color color) { line(from, to, t, color, color); } -void Batch::line(const Vec2& from, const Vec2& to, float t, Color fromColor, Color toColor) +void Batch::line(const Vec2f& from, const Vec2f& to, float t, Color fromColor, Color toColor) { if (from.x == to.x && from.y == to.y) return; - Vec2 normal = (to - from).normal(); - Vec2 perp = Vec2(normal.y, -normal.x); - Vec2 pos0 = from + perp * t * 0.5f; - Vec2 pos1 = to + perp * t * 0.5f; - Vec2 pos2 = to - perp * t * 0.5f; - Vec2 pos3 = from - perp * t * 0.5f; + Vec2f normal = (to - from).normal(); + Vec2f perp = Vec2f(normal.y, -normal.x); + Vec2f pos0 = from + perp * t * 0.5f; + Vec2f pos1 = to + perp * t * 0.5f; + Vec2f pos2 = to - perp * t * 0.5f; + Vec2f pos3 = from - perp * t * 0.5f; PUSH_QUAD( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, @@ -546,14 +556,14 @@ void Batch::line(const Vec2& from, const Vec2& to, float t, Color fromColor, Col 0, 0, 255); } -void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& to, int steps, float t, Color color) +void Batch::bezier_line(const Vec2f& from, const Vec2f& b, const Vec2f& to, int steps, float t, Color color) { - Vec2 prev = from; + Vec2f prev = from; float add = 1.0f / steps; for (int i = 1; i < steps; i++) { - Vec2 at = Vec2::lerp_bezier(from, b, to, add * i); + Vec2f at = Vec2f::lerp_bezier(from, b, to, add * i); line(prev, at, t, color); prev = at; } @@ -561,14 +571,14 @@ void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& to, int ste line(prev, to, t, color); } -void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& c, const Vec2& to, int steps, float t, Color color) +void Batch::bezier_line(const Vec2f& from, const Vec2f& b, const Vec2f& c, const Vec2f& to, int steps, float t, Color color) { - Vec2 prev = from; + Vec2f prev = from; float add = 1.0f / steps; for (int i = 1; i < steps; i++) { - Vec2 at = Vec2::lerp_bezier(from, b, c, to, add * i); + Vec2f at = Vec2f::lerp_bezier(from, b, c, to, add * i); line(prev, at, t, color); prev = at; } @@ -576,7 +586,7 @@ void Batch::bezier_line(const Vec2& from, const Vec2& b, const Vec2& c, const Ve line(prev, to, t, color); } -void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color color) +void Batch::tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, Color color) { PUSH_TRIANGLE( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, @@ -585,7 +595,7 @@ void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color colo 0, 0, 255); } -void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color col0, Color col1, Color col2) +void Batch::tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, Color col0, Color col1, Color col2) { PUSH_TRIANGLE( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, @@ -594,7 +604,7 @@ void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, Color col0 0, 0, 255); } -void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, Color color) +void Batch::tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, Color color) { PUSH_TRIANGLE( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, @@ -603,7 +613,7 @@ void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2 m_tex_mult, m_tex_wash, 0); } -void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, Color col0, Color col1, Color col2) +void Batch::tri(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, Color col0, Color col1, Color col2) { PUSH_TRIANGLE( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, @@ -612,7 +622,7 @@ void Batch::tri(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2 m_tex_mult, m_tex_wash, 0); } -void Batch::tri_line(const Vec2& a, const Vec2& b, const Vec2& c, float t, Color color) +void Batch::tri_line(const Vec2f& a, const Vec2f& b, const Vec2f& c, float t, Color color) { // TODO: // Detect if the thickness of the line fills the entire shape @@ -635,7 +645,7 @@ void Batch::tri_line(const Vec2& a, const Vec2& b, const Vec2& c, float t, Color quad(cc, c, a, aa, color); } -void Batch::rect(const Rect& rect, Color color) +void Batch::rect(const Rectf& rect, Color color) { PUSH_QUAD( rect.x, rect.y, @@ -647,7 +657,7 @@ void Batch::rect(const Rect& rect, Color color) 0, 0, 255); } -void Batch::rect_line(const Rect& rect, float t, Color color) +void Batch::rect_line(const Rectf& rect, float t, Color color) { if (t >= rect.w || t >= rect.h) { @@ -693,12 +703,12 @@ void Batch::rect_line(const Rect& rect, float t, Color color) } } -void Batch::rect_rounded(const Rect& rect, float radius, int steps, Color color) +void Batch::rect_rounded(const Rectf& rect, float radius, int steps, Color color) { rect_rounded(rect, radius, steps, radius, steps, radius, steps, radius, steps, color); } -void Batch::rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, Color color) +void Batch::rect_rounded(const Rectf& rect, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, Color color) { // clamp rtl = Calc::min(Calc::min(Calc::max(0.0f, rtl), rect.w / 2.0f), rect.h / 2.0f); @@ -713,10 +723,10 @@ void Batch::rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr, else { // get corners - Rect tl = Rect(rect.top_left(), Vec2(rtl, rtl)); - Rect tr = Rect(rect.top_right() + Vec2(-rtr, 0.0f), Vec2(rtr, rtr)); - Rect bl = Rect(rect.bottom_left() + Vec2(0.0f, -rbl), Vec2(rbl, rbl)); - Rect br = Rect(rect.bottom_right() + Vec2(-rbr, -rbr), Vec2(rbr, rbr)); + Rectf tl = Rectf(rect.x, rect.y, rtl, rtl); + Rectf tr = Rectf(rect.x + rect.w - rtr, rect.y, rtr, rtr); + Rectf bl = Rectf(rect.x, rect.y + rect.h - rbl, rbl, rbl); + Rectf br = Rectf(rect.x + rect.w - rbr, rect.y + rect.h - rbr, rbr, rbr); // rounded corners semi_circle(tl.bottom_right(), Calc::UP, Calc::LEFT, rtl, rtl_steps, color); @@ -733,12 +743,12 @@ void Batch::rect_rounded(const Rect& rect, float rtl, int rtl_steps, float rtr, } } -void Batch::rect_rounded_line(const Rect & rect, float radius, int steps, float t, Color color) +void Batch::rect_rounded_line(const Rectf & rect, float radius, int steps, float t, Color color) { rect_rounded_line(rect, radius, steps, radius, steps, radius, steps, radius, steps, t, color); } -void Batch::rect_rounded_line(const Rect& r, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, float t, Color color) +void Batch::rect_rounded_line(const Rectf& r, float rtl, int rtl_steps, float rtr, int rtr_steps, float rbr, int rbr_steps, float rbl, int rbl_steps, float t, Color color) { // clamp rtl = Calc::min(Calc::min(Calc::max(0.0f, rtl), r.w / 2.0f), r.h / 2.0f); @@ -753,42 +763,42 @@ void Batch::rect_rounded_line(const Rect& r, float rtl, int rtl_steps, float rtr else { // rounded corners - semi_circle_line(Vec2(r.x + rtl, r.y + rtl), Calc::UP, Calc::LEFT, rtl, rtl_steps, t, color); - semi_circle_line(Vec2(r.x + r.w - rtr, r.y + rtr), Calc::UP, Calc::UP + Calc::TAU * 0.25f, rtr, rtr_steps, t, color); - semi_circle_line(Vec2(r.x + rbl, r.y + r.h - rbl), Calc::DOWN, Calc::LEFT, rbl, rbl_steps, t, color); - semi_circle_line(Vec2(r.x + r.w - rbr, r.y + r.h - rbr), Calc::DOWN, Calc::RIGHT, rbr, rbr_steps, t, color); + semi_circle_line(Vec2f(r.x + rtl, r.y + rtl), Calc::UP, Calc::LEFT, rtl, rtl_steps, t, color); + semi_circle_line(Vec2f(r.x + r.w - rtr, r.y + rtr), Calc::UP, Calc::UP + Calc::TAU * 0.25f, rtr, rtr_steps, t, color); + semi_circle_line(Vec2f(r.x + rbl, r.y + r.h - rbl), Calc::DOWN, Calc::LEFT, rbl, rbl_steps, t, color); + semi_circle_line(Vec2f(r.x + r.w - rbr, r.y + r.h - rbr), Calc::DOWN, Calc::RIGHT, rbr, rbr_steps, t, color); // connect sides that aren't touching if (r.h > rtl + rbl) - rect(Rect(r.x, r.y + rtl, t, r.h - rtl - rbl), color); + rect(Rectf(r.x, r.y + rtl, t, r.h - rtl - rbl), color); if (r.h > rtr + rbr) - rect(Rect(r.x + r.w - t, r.y + rtr, t, r.h - rtr - rbr), color); + rect(Rectf(r.x + r.w - t, r.y + rtr, t, r.h - rtr - rbr), color); if (r.w > rtl + rtr) - rect(Rect(r.x + rtl, r.y, r.w - rtl - rtr, t), color); + rect(Rectf(r.x + rtl, r.y, r.w - rtl - rtr, t), color); if (r.w > rbl + rbr) - rect(Rect(r.x + rbl, r.y + r.h - t, r.w - rbl - rbr, t), color); + rect(Rectf(r.x + rbl, r.y + r.h - t, r.w - rbl - rbr, t), color); } } -void Batch::semi_circle(const Vec2& center, float start_radians, float end_radians, float radius, int steps, Color centerColor, Color edgeColor) +void Batch::semi_circle(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, Color centerColor, Color edgeColor) { - Vec2 last = Vec2::from_angle(start_radians, radius); + Vec2f last = Vec2f::from_angle(start_radians, radius); float add = Calc::angle_diff(start_radians, end_radians); for (int i = 1; i <= steps; i++) { - Vec2 next = Vec2::from_angle(start_radians + add * (i / (float)steps), radius); + Vec2f next = Vec2f::from_angle(start_radians + add * (i / (float)steps), radius); tri(center + last, center + next, center, edgeColor, edgeColor, centerColor); last = next; } } -void Batch::semi_circle(const Vec2& center, float start_radians, float end_radians, float radius, int steps, Color color) +void Batch::semi_circle(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, Color color) { semi_circle(center, start_radians, end_radians, radius, steps, color, color); } -void Batch::semi_circle_line(const Vec2& center, float start_radians, float end_radians, float radius, int steps, float t, Color color) +void Batch::semi_circle_line(const Vec2f& center, float start_radians, float end_radians, float radius, int steps, float t, Color color) { if (t >= radius) { @@ -798,13 +808,13 @@ void Batch::semi_circle_line(const Vec2& center, float start_radians, float end_ { const auto add = Calc::angle_diff(start_radians, end_radians); - Vec2 last_inner = Vec2::from_angle(start_radians, radius - t); - Vec2 last_outer = Vec2::from_angle(start_radians, radius); + Vec2f last_inner = Vec2f::from_angle(start_radians, radius - t); + Vec2f last_outer = Vec2f::from_angle(start_radians, radius); for (int i = 1; i <= steps; i++) { - const auto next_inner = Vec2::from_angle(start_radians + add * (i / (float)steps), radius - t); - const auto next_outer = Vec2::from_angle(start_radians + add * (i / (float)steps), radius); + const auto next_inner = Vec2f::from_angle(start_radians + add * (i / (float)steps), radius - t); + const auto next_outer = Vec2f::from_angle(start_radians + add * (i / (float)steps), radius); quad(center + last_inner, center + last_outer, center + next_outer, center + next_inner, color); @@ -814,19 +824,19 @@ void Batch::semi_circle_line(const Vec2& center, float start_radians, float end_ } } -void Batch::circle(const Vec2& center, float radius, int steps, Color color) +void Batch::circle(const Vec2f& center, float radius, int steps, Color color) { circle(center, radius, steps, color, color); } -void Batch::circle(const Vec2& center, float radius, int steps, Color center_color, Color outer_color) +void Batch::circle(const Vec2f& center, float radius, int steps, Color center_color, Color outer_color) { - Vec2 last = Vec2(center.x + radius, center.y); + Vec2f last = Vec2f(center.x + radius, center.y); for (int i = 1; i <= steps; i++) { const auto radians = (i / (float)steps) * Calc::TAU; - const auto next = Vec2(center.x + Calc::cos(radians) * radius, center.y + Calc::sin(radians) * radius); + const auto next = Vec2f(center.x + Calc::cos(radians) * radius, center.y + Calc::sin(radians) * radius); tri(last, next, center, outer_color, outer_color, center_color); @@ -834,7 +844,7 @@ void Batch::circle(const Vec2& center, float radius, int steps, Color center_col } } -void Batch::circle_line(const Vec2& center, float radius, float t, int steps, Color color) +void Batch::circle_line(const Vec2f& center, float radius, float t, int steps, Color color) { if (t >= radius) { @@ -842,16 +852,16 @@ void Batch::circle_line(const Vec2& center, float radius, float t, int steps, Co } else { - Vec2 last_inner = Vec2(center.x + radius - t, center.y); - Vec2 last_outer = Vec2(center.x + radius, center.y); + Vec2f last_inner = Vec2f(center.x + radius - t, center.y); + Vec2f last_outer = Vec2f(center.x + radius, center.y); for (int i = 1; i <= steps; i++) { const auto radians = (i / (float)steps) * Calc::TAU; - const auto normal = Vec2(Calc::cos(radians), Calc::sin(radians)); + const auto normal = Vec2f(Calc::cos(radians), Calc::sin(radians)); - const auto next_inner = Vec2(center.x + normal.x * (radius - t), center.y + normal.y * (radius - t)); - const auto next_outer = Vec2(center.x + normal.x * radius, center.y + normal.y * radius); + const auto next_inner = Vec2f(center.x + normal.x * (radius - t), center.y + normal.y * (radius - t)); + const auto next_outer = Vec2f(center.x + normal.x * radius, center.y + normal.y * radius); quad(last_inner, last_outer, next_outer, next_inner, color); @@ -861,7 +871,7 @@ void Batch::circle_line(const Vec2& center, float radius, float t, int steps, Co } } -void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, Color color) +void Batch::quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, Color color) { PUSH_QUAD( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, @@ -870,7 +880,7 @@ void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec 0, 0, 255); } -void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, Color col0, Color col1, Color col2, Color col3) +void Batch::quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, Color col0, Color col1, Color col2, Color col3) { PUSH_QUAD( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, @@ -879,7 +889,7 @@ void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec 0, 0, 255); } -void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, const Vec2& tex3, Color color) +void Batch::quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, const Vec2f& tex3, Color color) { PUSH_QUAD( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, @@ -888,7 +898,7 @@ void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec m_tex_mult, m_tex_wash, 0); } -void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec2& pos3, const Vec2& tex0, const Vec2& tex1, const Vec2& tex2, const Vec2& tex3, Color col0, Color col1, Color col2, Color col3) +void Batch::quad(const Vec2f& pos0, const Vec2f& pos1, const Vec2f& pos2, const Vec2f& pos3, const Vec2f& tex0, const Vec2f& tex1, const Vec2f& tex2, const Vec2f& tex3, Color col0, Color col1, Color col2, Color col3) { PUSH_QUAD( pos0.x, pos0.y, pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y, @@ -897,7 +907,7 @@ void Batch::quad(const Vec2& pos0, const Vec2& pos1, const Vec2& pos2, const Vec m_tex_mult, m_tex_wash, 0); } -void Batch::quad_line(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d, float t, Color color) +void Batch::quad_line(const Vec2f& a, const Vec2f& b, const Vec2f& c, const Vec2f& d, float t, Color color) { // TODO: // Detect if the thickness of the line fills the entire shape @@ -924,22 +934,22 @@ void Batch::quad_line(const Vec2& a, const Vec2& b, const Vec2& c, const Vec2& d quad(dd, d, a, aa, color); } -void Batch::arrow_head(const Vec2& point_pos, float radians, float side_len, Color color) +void Batch::arrow_head(const Vec2f& point_pos, float radians, float side_len, Color color) { - arrow_head(point_pos, point_pos - Vec2::from_angle(radians), side_len, color); + arrow_head(point_pos, point_pos - Vec2f::from_angle(radians), side_len, color); } -void Batch::arrow_head(const Vec2& point_pos, const Vec2& from_pos, float side_len, Color color) +void Batch::arrow_head(const Vec2f& point_pos, const Vec2f& from_pos, float side_len, Color color) { float height = sqrtf(side_len * side_len - powf(side_len / 2, 2)); - Vec2 dir = (point_pos - from_pos).normal(); - Vec2 perp = dir.perpendicular(); - Vec2 base = point_pos - dir * height; + Vec2f dir = (point_pos - from_pos).normal(); + Vec2f perp = dir.turn_right(); + Vec2f base = point_pos - dir * height; tri(point_pos, base + perp * side_len / 2, base - perp * side_len / 2, color); } -void Batch::tex(const TextureRef& texture, const Vec2& pos, Color color) +void Batch::tex(const TextureRef& texture, const Vec2f& pos, Color color) { set_texture(texture); @@ -953,9 +963,9 @@ void Batch::tex(const TextureRef& texture, const Vec2& pos, Color color) m_tex_mult, m_tex_wash, 0); } -void Batch::tex(const TextureRef& texture, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color) +void Batch::tex(const TextureRef& texture, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color) { - push_matrix(Mat3x2::create_transform(pos, origin, scale, rotation)); + push_matrix(Mat3x2f::create_transform(pos, origin, scale, rotation)); set_texture(texture); @@ -971,9 +981,9 @@ void Batch::tex(const TextureRef& texture, const Vec2& pos, const Vec2& origin, pop_matrix(); } -void Batch::tex(const TextureRef& texture, const Rect& clip, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color) +void Batch::tex(const TextureRef& texture, const Rectf& clip, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color) { - push_matrix(Mat3x2::create_transform(pos, origin, scale, rotation)); + push_matrix(Mat3x2f::create_transform(pos, origin, scale, rotation)); set_texture(texture); @@ -993,7 +1003,7 @@ void Batch::tex(const TextureRef& texture, const Rect& clip, const Vec2& pos, co pop_matrix(); } -void Batch::tex(const Subtexture& sub, const Vec2& pos, Color color) +void Batch::tex(const Subtexture& sub, const Vec2f& pos, Color color) { if (!sub.texture) { @@ -1024,9 +1034,9 @@ void Batch::tex(const Subtexture& sub, const Vec2& pos, Color color) } } -void Batch::tex(const Subtexture& sub, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color) +void Batch::tex(const Subtexture& sub, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color) { - push_matrix(Mat3x2::create_transform(pos, origin, scale, rotation)); + push_matrix(Mat3x2f::create_transform(pos, origin, scale, rotation)); if (!sub.texture) { @@ -1059,24 +1069,24 @@ void Batch::tex(const Subtexture& sub, const Vec2& pos, const Vec2& origin, cons pop_matrix(); } -void Batch::tex(const Subtexture& sub, const Rect& clip, const Vec2& pos, const Vec2& origin, const Vec2& scale, float rotation, Color color) +void Batch::tex(const Subtexture& sub, const Rectf& clip, const Vec2f& pos, const Vec2f& origin, const Vec2f& scale, float rotation, Color color) { tex(sub.crop(clip), pos, origin, scale, rotation, color); } -void Batch::str(const SpriteFont& font, const String& text, const Vec2& pos, Color color) +void Batch::str(const SpriteFont& font, const String& text, const Vec2f& pos, Color color) { str(font, text, pos, TextAlign::TopLeft, font.size, color); } -void Batch::str(const SpriteFont& font, const String& text, const Vec2& pos, TextAlign align, float size, Color color) +void Batch::str(const SpriteFont& font, const String& text, const Vec2f& pos, TextAlign align, float size, Color color) { push_matrix( - Mat3x2::create_scale(size / font.size) * - Mat3x2::create_translation(pos) + Mat3x2f::create_scale(size / font.size) * + Mat3x2f::create_translation(pos) ); - Vec2 offset; + Vec2f offset; if ((align & TextAlign::Left) == TextAlign::Left) offset.x = 0; @@ -1119,7 +1129,7 @@ void Batch::str(const SpriteFont& font, const String& text, const Vec2& pos, Tex // draw it, if the subtexture exists if (ch.subtexture.texture) { - Vec2 at = offset + ch.offset; + Vec2f at = offset + ch.offset; if (i > 0 && text[i - 1] != '\n') at.x += font.get_kerning(last, next); diff --git a/src/graphics/material.cpp b/src/graphics/material.cpp index 3ad36cc..2d6610c 100644 --- a/src/graphics/material.cpp +++ b/src/graphics/material.cpp @@ -6,7 +6,7 @@ using namespace Blah; namespace { - int calc_uniform_size(const UniformInfo& uniform) + int blah_calc_uniform_size(const UniformInfo& uniform) { int components = 0; @@ -27,16 +27,6 @@ namespace } } -MaterialRef Material::create(const ShaderRef& shader) -{ - BLAH_ASSERT(shader, "The provided shader is invalid"); - - if (shader) - return MaterialRef(new Material(shader)); - - return MaterialRef(); -} - Material::Material(const ShaderRef& shader) { BLAH_ASSERT(shader, "Material is being created with an invalid shader"); @@ -64,12 +54,31 @@ Material::Material(const ShaderRef& shader) continue; } - float_size += calc_uniform_size(uniform); + float_size += blah_calc_uniform_size(uniform); } m_data.expand(float_size); } +MaterialRef Material::create(const ShaderRef& shader) +{ + BLAH_ASSERT(shader, "The provided shader is invalid"); + + if (shader) + return MaterialRef(new Material(shader)); + + return MaterialRef(); +} + +MaterialRef Material::clone() const +{ + auto copy = MaterialRef(new Material(m_shader)); + copy->m_textures = m_textures; + copy->m_samplers = m_samplers; + copy->m_data = m_data; + return copy; +} + ShaderRef Material::shader() const { return m_shader; @@ -293,7 +302,7 @@ void Material::set_value(const char* name, const float* value, i64 length) if (strcmp(uniform.name, name) == 0) { - auto max = calc_uniform_size(uniform); + auto max = blah_calc_uniform_size(uniform); if (length > max) { Log::warn("Exceeding length of Uniform '%s' (%i / %i)", name, length, max); @@ -304,13 +313,73 @@ void Material::set_value(const char* name, const float* value, i64 length) return; } - offset += calc_uniform_size(uniform); + offset += blah_calc_uniform_size(uniform); index++; } Log::warn("No Uniform '%s' exists", name); } +void Material::set_value(const char* name, float value) +{ + set_value(name, &value, 1); +} + +void Material::set_value(const char* name, const Vec2f& value) +{ + set_value(name, &value.x, 2); +} + +void Material::set_value(const char* name, const Vec3f& value) +{ + set_value(name, &value.x, 3); +} + +void Material::set_value(const char* name, const Vec4f& value) +{ + set_value(name, &value.x, 4); +} + +void Material::set_value(const char* name, const Mat3x2f& value) +{ + set_value(name, &value.m11, 6); +} + +void Material::set_value(const char* name, const Mat4x4f& value) +{ + set_value(name, &value.m11, 16); +} + +void Material::set_value(const char* name, const Vector& value) +{ + set_value(name, value.data(), value.size()); +} + +void Material::set_value(const char* name, const Vector& value) +{ + set_value(name, (float*)value.data(), value.size() * 2); +} + +void Material::set_value(const char* name, const Vector& value) +{ + set_value(name, (float*)value.data(), value.size() * 3); +} + +void Material::set_value(const char* name, const Vector& value) +{ + set_value(name, (float*)value.data(), value.size() * 4); +} + +void Material::set_value(const char* name, const Vector& value) +{ + set_value(name, (float*)value.data(), value.size() * 6); +} + +void Material::set_value(const char* name, const Vector& value) +{ + set_value(name, (float*)value.data(), value.size() * 16); +} + const float* Material::get_value(const char* name, i64* length) const { BLAH_ASSERT(m_shader, "Material Shader is invalid"); @@ -327,12 +396,12 @@ const float* Material::get_value(const char* name, i64* length) const if (strcmp(uniform.name, name) == 0) { if (length != nullptr) - *length = calc_uniform_size(uniform); + *length = blah_calc_uniform_size(uniform); return m_data.begin() + offset; } index++; - offset += calc_uniform_size(uniform); + offset += blah_calc_uniform_size(uniform); } Log::warn("No Uniform '%s' exists", name); diff --git a/src/graphics/renderpass.cpp b/src/graphics/renderpass.cpp index c72d53f..9914ceb 100644 --- a/src/graphics/renderpass.cpp +++ b/src/graphics/renderpass.cpp @@ -12,8 +12,8 @@ RenderPass::RenderPass() material = MaterialRef(); has_viewport = false; has_scissor = false; - viewport = Rect(); - scissor = Rect(); + viewport = Rectf(); + scissor = Rectf(); index_start = 0; index_count = 0; instance_count = 0; @@ -66,7 +66,7 @@ void RenderPass::perform() } // get the total drawable size - auto draw_size = Vec2(pass.target->width(), pass.target->height()); + auto draw_size = Vec2f(pass.target->width(), pass.target->height()); // Validate Viewport if (!pass.has_viewport) @@ -78,12 +78,12 @@ void RenderPass::perform() } else { - pass.viewport = pass.viewport.overlap_rect(Rect(0, 0, draw_size.x, draw_size.y)); + pass.viewport = pass.viewport.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y)); } // Validate Scissor if (pass.has_scissor) - pass.scissor = pass.scissor.overlap_rect(Rect(0, 0, draw_size.x, draw_size.y)); + pass.scissor = pass.scissor.overlap_rect(Rectf(0, 0, draw_size.x, draw_size.y)); // perform render Graphics::render(pass); diff --git a/src/graphics/spritefont.cpp b/src/graphics/spritefont.cpp index 4459877..94b2652 100644 --- a/src/graphics/spritefont.cpp +++ b/src/graphics/spritefont.cpp @@ -213,7 +213,7 @@ void SpriteFont::rebuild(const Font& font, float size, const CharSet& charset) // add character auto ch = font.get_character(glyph, scale); m_characters[i].advance = ch.advance; - m_characters[i].offset = Vec2(ch.offset_x, ch.offset_y); + m_characters[i].offset = Vec2f(ch.offset_x, ch.offset_y); // pack glyph if (ch.has_glyph) diff --git a/src/graphics/subtexture.cpp b/src/graphics/subtexture.cpp index 3580a41..92168de 100644 --- a/src/graphics/subtexture.cpp +++ b/src/graphics/subtexture.cpp @@ -6,12 +6,12 @@ using namespace Blah; Subtexture::Subtexture() {} Subtexture::Subtexture(const TextureRef& texture) - : Subtexture(texture, Rect(0, 0, (float)texture->width(), (float)texture->height())) {} + : Subtexture(texture, Rectf(0, 0, (float)texture->width(), (float)texture->height())) {} -Subtexture::Subtexture(const TextureRef& texture, Rect source) - : Subtexture(texture, source, Rect(0, 0, source.w, source.h)) {} +Subtexture::Subtexture(const TextureRef& texture, Rectf source) + : Subtexture(texture, source, Rectf(0, 0, source.w, source.h)) {} -Subtexture::Subtexture(const TextureRef& texture, Rect source, Rect frame) +Subtexture::Subtexture(const TextureRef& texture, Rectf source, Rectf frame) : texture(texture), source(source), frame(frame) { update(); @@ -44,7 +44,7 @@ void Subtexture::update() } } -void Subtexture::crop_info(const Rect& clip, Rect* dest_source, Rect* dest_frame) const +void Subtexture::crop_info(const Rectf& clip, Rectf* dest_source, Rectf* dest_frame) const { *dest_source = (clip + source.top_left() + frame.top_left()).overlap_rect(source); @@ -54,7 +54,7 @@ void Subtexture::crop_info(const Rect& clip, Rect* dest_source, Rect* dest_frame dest_frame->h = clip.h; } -Subtexture Subtexture::crop(const Rect& clip) const +Subtexture Subtexture::crop(const Rectf& clip) const { Subtexture dst; dst.texture = texture; diff --git a/src/images/image.cpp b/src/images/image.cpp index d0f74f8..7934f49 100644 --- a/src/images/image.cpp +++ b/src/images/image.cpp @@ -193,7 +193,7 @@ void Image::premultiply() } } -void Image::set_pixels(const RectI& rect, Color* data) +void Image::set_pixels(const Recti& rect, Color* data) { for (int y = 0; y < rect.h; y++) { @@ -257,7 +257,7 @@ bool Image::save_jpg(Stream& stream, int quality) const return false; } -void Image::get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, RectI source_rect) const +void Image::get_pixels(Color* dest, const Point& dest_pos, const Point& dest_size, Recti source_rect) const { // can't be outside of the source image if (source_rect.x < 0) source_rect.x = 0; @@ -279,7 +279,7 @@ void Image::get_pixels(Color* dest, const Point& dest_pos, const Point& dest_siz } } -Image Image::get_sub_image(const RectI& source_rect) +Image Image::get_sub_image(const Recti& source_rect) { Image img(source_rect.w, source_rect.h); get_pixels(img.pixels, Point::zero, Point(img.width, img.height), source_rect); diff --git a/src/images/packer.cpp b/src/images/packer.cpp index 0d71224..bbfe31a 100644 --- a/src/images/packer.cpp +++ b/src/images/packer.cpp @@ -43,15 +43,15 @@ Packer::~Packer() void Packer::add(u64 id, int width, int height, const Color* pixels) { - add_entry(id, width, height, pixels, RectI(0, 0, width, height)); + add_entry(id, width, height, pixels, Recti(0, 0, width, height)); } void Packer::add(u64 id, const Image& image) { - add_entry(id, image.width, image.height, image.pixels, RectI(0, 0, image.width, image.height)); + add_entry(id, image.width, image.height, image.pixels, Recti(0, 0, image.width, image.height)); } -void Packer::add(u64 id, const Image& image, const RectI& source) +void Packer::add(u64 id, const Image& image, const Recti& source) { add_entry(id, image.width, image.height, image.pixels, source); } @@ -61,11 +61,11 @@ void Packer::add(u64 id, const FilePath& path) add(id, Image(path.cstr())); } -void Packer::add_entry(u64 id, int w, int h, const Color* pixels, const RectI& source) +void Packer::add_entry(u64 id, int w, int h, const Color* pixels, const Recti& source) { m_dirty = true; - Entry entry(id, RectI(0, 0, source.w, source.h)); + Entry entry(id, Recti(0, 0, source.w, source.h)); // trim int top = source.y, left = source.x, right = source.x, bottom = source.y; @@ -115,7 +115,6 @@ void Packer::add_entry(u64 id, int w, int h, const Color* pixels, const RectI& s entry.packed.w = (right - left); entry.packed.h = (bottom - top); - // create pixel data entry.memory_index = m_buffer.position(); @@ -189,7 +188,7 @@ void Packer::pack() int from = packed; int index = 0; - Node* root = nodes[index++].Reset(RectI(0, 0, sources[from]->packed.w + padding * 2 + spacing, sources[from]->packed.h + padding * 2 + spacing)); + Node* root = nodes[index++].Reset(Recti(0, 0, sources[from]->packed.w + padding * 2 + spacing, sources[from]->packed.h + padding * 2 + spacing)); while (packed < count) { @@ -217,18 +216,18 @@ void Packer::pack() // grow right if (shouldGrowRight || (!shouldGrowDown && canGrowRight)) { - Node* next = nodes[index++].Reset(RectI(0, 0, root->rect.w + w, root->rect.h)); + Node* next = nodes[index++].Reset(Recti(0, 0, root->rect.w + w, root->rect.h)); next->used = true; next->down = root; - next->right = node = nodes[index++].Reset(RectI(root->rect.w, 0, w, root->rect.h)); + next->right = node = nodes[index++].Reset(Recti(root->rect.w, 0, w, root->rect.h)); root = next; } // grow down else { - Node* next = nodes[index++].Reset(RectI(0, 0, root->rect.w, root->rect.h + h)); + Node* next = nodes[index++].Reset(Recti(0, 0, root->rect.w, root->rect.h + h)); next->used = true; - next->down = node = nodes[index++].Reset(RectI(0, root->rect.h, root->rect.w, h)); + next->down = node = nodes[index++].Reset(Recti(0, root->rect.h, root->rect.w, h)); next->right = root; root = next; } @@ -241,8 +240,8 @@ void Packer::pack() // add node->used = true; - node->down = nodes[index++].Reset(RectI(node->rect.x, node->rect.y + h, node->rect.w, node->rect.h - h)); - node->right = nodes[index++].Reset(RectI(node->rect.x + w, node->rect.y, node->rect.w - w, h)); + node->down = nodes[index++].Reset(Recti(node->rect.x, node->rect.y + h, node->rect.w, node->rect.h - h)); + node->right = nodes[index++].Reset(Recti(node->rect.x + w, node->rect.y, node->rect.w - w, h)); sources[packed]->packed.x = node->rect.x + padding; sources[packed]->packed.y = node->rect.y + padding; @@ -276,21 +275,26 @@ void Packer::pack() sources[i]->page = page; if (!sources[i]->empty) { - RectI dst = sources[i]->packed; + Recti dst = sources[i]->packed; Color* src = (Color*)(m_buffer.data() + sources[i]->memory_index); // TODO: // Optimize this? if (padding > 0) { - pages[page].set_pixels(RectI(dst.x - padding, dst.y, dst.w, dst.h), src); - pages[page].set_pixels(RectI(dst.x + padding, dst.y, dst.w, dst.h), src); - pages[page].set_pixels(RectI(dst.x, dst.y - padding, dst.w, dst.h), src); - pages[page].set_pixels(RectI(dst.x, dst.y + padding, dst.w, dst.h), src); + Image& image = pages[page]; + for (int x = -padding; x < dst.w + padding * 2; x++) + for (int y = -padding; y < dst.h + padding * 2; y++) + { + int sx = (x < 0 ? 0 : (x > dst.w - 1 ? dst.w - 1 : x)); + int sy = (y < 0 ? 0 : (y > dst.h - 1 ? dst.h - 1 : y)); + image.pixels[dst.x + x + (dst.y + y) * image.width] = src[sx + sy * dst.w]; + } + } + else + { + pages[page].set_pixels(dst, src); } - - pages[page].set_pixels(dst, src); - } } } @@ -335,7 +339,7 @@ Packer::Node* Packer::Node::Find(int w, int h) return nullptr; } -Packer::Node* Packer::Node::Reset(const RectI& rect) +Packer::Node* Packer::Node::Reset(const Recti& rect) { used = false; this->rect = rect; diff --git a/src/input.cpp b/src/input.cpp index 16ef4f5..097f4ed 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -2,9 +2,9 @@ #include #include #include -#include #include #include "internal/input.h" +#include "internal/platform.h" #include using namespace Blah; @@ -16,11 +16,15 @@ namespace Vector> g_buttons; Vector> g_axes; Vector> g_sticks; + String g_clipboard; } InputState Blah::Input::state; InputState Blah::Input::last_state; +float Blah::Input::repeat_delay = 0.35f; +float Blah::Input::repeat_interval = 0.025f; + void Input::init() { g_empty_controller.name = "Disconnected"; @@ -68,6 +72,9 @@ void Input::update_state() controller.released[j] = false; } } + + // get clipboard + g_clipboard = Platform::get_clipboard(); } void Input::update_bindings() @@ -112,7 +119,7 @@ void Input::update_bindings() } } -void MouseState::on_move(const Vec2& pos, const Vec2& screen_pos) +void MouseState::on_move(const Vec2f& pos, const Vec2f& screen_pos) { position = pos; screen_position = screen_pos; @@ -223,17 +230,17 @@ bool KeyboardState::alt() return down[Key::LeftAlt] || down[Key::RightAlt]; } -Vec2 Input::mouse() +Vec2f Input::mouse() { return state.mouse.position; } -Vec2 Input::mouse_draw() +Vec2f Input::mouse_draw() { return state.mouse.draw_position; } -Vec2 Input::mouse_screen() +Vec2f Input::mouse_screen() { return state.mouse.screen_position; } @@ -273,6 +280,26 @@ bool Input::released(Key key) return state.keyboard.released[key]; } +bool Input::repeating(Key key) +{ + if (state.keyboard.pressed[key]) + return true; + + if (state.keyboard.down[key]) + { + double timestamp = state.keyboard.timestamp[key] / (double)Time::ticks_per_second; + double current_time = Time::ticks / (double)Time::ticks_per_second; + + if (current_time > timestamp + Input::repeat_delay) + { + if (Time::on_interval(current_time - timestamp, Time::delta, Input::repeat_interval, 0.0f)) + return true; + } + } + + return false; +} + bool Input::ctrl() { return state.keyboard.ctrl(); @@ -312,6 +339,17 @@ const char* Input::name_of(Button button) return "Unknown"; } +const String& Input::get_clipboard() +{ + return g_clipboard; +} + +void Input::set_clipboard(const String& text) +{ + g_clipboard = text; + return Platform::set_clipboard(text); +} + ButtonBindingRef Input::register_binding(const ButtonBinding& binding) { auto result = std::make_shared(binding); @@ -730,17 +768,17 @@ void AxisBinding::clear() positive.clear(); } -Vec2 StickBinding::value() const +Vec2f StickBinding::value() const { - Vec2 result = Vec2(x.value(), y.value()); + Vec2f result = Vec2f(x.value(), y.value()); if (round_threshold > 0 && result.length() < round_threshold) - return Vec2::zero; + return Vec2f::zero; return result; } Point StickBinding::sign() const { - Vec2 result = value(); + Vec2f result = value(); return Point((int)Calc::sign(result.x), (int)Calc::sign(result.y)); } diff --git a/src/internal/graphics_gl.cpp b/src/internal/graphics_gl.cpp index b9879c6..a24c119 100644 --- a/src/internal/graphics_gl.cpp +++ b/src/internal/graphics_gl.cpp @@ -1420,7 +1420,7 @@ namespace Blah // Viewport { - Rect viewport = pass.viewport; + Rectf viewport = pass.viewport; viewport.y = size.y - viewport.y - viewport.h; gl.Viewport((GLint)viewport.x, (GLint)viewport.y, (GLint)viewport.w, (GLint)viewport.h); @@ -1434,7 +1434,7 @@ namespace Blah } else { - Rect scissor = pass.scissor; + Rectf scissor = pass.scissor; scissor.y = size.y - scissor.y - scissor.h; if (scissor.w < 0) diff --git a/src/internal/platform.h b/src/internal/platform.h index a49d990..d24893b 100644 --- a/src/internal/platform.h +++ b/src/internal/platform.h @@ -88,6 +88,12 @@ namespace Blah // opens a directory in the OS file explorer / finder void dir_explore(const char* path); + // sets the contents of the clipboard + void set_clipboard(const char* text); + + // gets the contents of the clipboard into the given string + const char* get_clipboard(); + // OpenGL Methods void* gl_get_func(const char* name); void* gl_context_create(); diff --git a/src/internal/platform_sdl2.cpp b/src/internal/platform_sdl2.cpp index 9ef6e7a..df55ca2 100644 --- a/src/internal/platform_sdl2.cpp +++ b/src/internal/platform_sdl2.cpp @@ -261,8 +261,8 @@ void Platform::update(InputState& state) SDL_GetGlobalMouseState(&x, &y); state.mouse.on_move( - Vec2((float)(x - win_x), (float)(y - win_y)), - Vec2((float)x, (float)y)); + Vec2f((float)(x - win_x), (float)(y - win_y)), + Vec2f((float)x, (float)y)); } // poll normal events @@ -722,6 +722,17 @@ void Platform::dir_explore(const char* path) #endif +// clipboard +void Platform::set_clipboard(const char* text) +{ + SDL_SetClipboardText(text); +} + +const char* Platform::get_clipboard() +{ + return SDL_GetClipboardText(); +} + void* Platform::gl_get_func(const char* name) { return SDL_GL_GetProcAddress(name); diff --git a/src/internal/platform_win32.cpp b/src/internal/platform_win32.cpp index 8b9a16f..5e3d355 100644 --- a/src/internal/platform_win32.cpp +++ b/src/internal/platform_win32.cpp @@ -360,7 +360,7 @@ LRESULT CALLBACK Blah::win32_window_procedure(HWND hwnd, UINT msg, WPARAM wParam return 0; case WM_MOUSEMOVE: - g_platform.input_state->mouse.on_move(Vec2((float)((u16)lParam), (float)(lParam >> 16)), Vec2::zero); + g_platform.input_state->mouse.on_move(Vec2f((float)((u16)lParam), (float)(lParam >> 16)), Vec2f::zero); return 0; case WM_MOUSEWHEEL: @@ -628,6 +628,17 @@ FileRef Platform::file_open(const char* path, FileMode mode) return FileRef(new Win32File(result)); } +// clipboard +void Platform::set_clipboard(const char* text) +{ + BLAH_ASSERT(false, "Not Implemented Yet"); +} + +const char* Platform::get_clipboard() +{ + BLAH_ASSERT(false, "Not Implemented Yet"); +} + void* Platform::gl_get_func(const char* name) { // this check is taken from https://www.khronos.org/opengl/wiki/Load_OpenGL_Functions diff --git a/src/numerics/calc.cpp b/src/numerics/calc.cpp index 32e8734..a2b952f 100644 --- a/src/numerics/calc.cpp +++ b/src/numerics/calc.cpp @@ -1,49 +1,15 @@ #include -#include +#include #include #include 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 delta) { return t < target ? min(t + delta, target) : max(t - delta, target); } -Vec2 Calc::approach(const Vec2& t, const Vec2& target, float delta) -{ - if ((target - t).length() <= delta) - return target; - return t + (target - t).normal() * delta; -} - 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); diff --git a/src/numerics/color.cpp b/src/numerics/color.cpp index 52d46f8..c953546 100644 --- a/src/numerics/color.cpp +++ b/src/numerics/color.cpp @@ -30,4 +30,14 @@ String Color::to_hex_rgb() const str[4] = hex[(b & 0xF0) >> 4]; str[5] = hex[(b & 0x0F) >> 0]; return str; -} \ No newline at end of file +} + +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); \ No newline at end of file diff --git a/src/numerics/line.cpp b/src/numerics/line.cpp deleted file mode 100644 index d4313ec..0000000 --- a/src/numerics/line.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include -#include -#include - -using namespace Blah; - -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.0f, 1.0f); - - 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; -} diff --git a/src/numerics/mat3x2.cpp b/src/numerics/mat3x2.cpp deleted file mode 100644 index 74412d6..0000000 --- a/src/numerics/mat3x2.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include - -using namespace Blah; - -float Mat3x2::scaling_factor() const -{ - return Calc::sqrt(m11 * m11 + m12 * m12); -} - -Mat3x2 Mat3x2::create_translation(const Vec2& position) -{ - return create_translation(position.x, position.y); -} - -Mat3x2 Mat3x2::create_scale(const Vec2& scale) -{ - return create_scale(scale.x, scale.y); -} - -Mat3x2 Mat3x2::create_scale(float scale, const Vec2& center_point) -{ - Mat3x2 result; - - float tx = center_point.x * (1 - scale); - float ty = center_point.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(const Vec2& scale, const Vec2& center_point) -{ - Mat3x2 result; - - float tx = center_point.x * (1 - scale.x); - float ty = center_point.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 scale_x, float scale_y, const Vec2& center_point) -{ - Mat3x2 result; - - float tx = center_point.x * (1 - scale_x); - float ty = center_point.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_rotation(float radians) -{ - float c = Calc::cos(radians); - float s = Calc::sin(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; -} \ No newline at end of file diff --git a/src/numerics/mat4x4.cpp b/src/numerics/mat4x4.cpp deleted file mode 100644 index d4b4fbb..0000000 --- a/src/numerics/mat4x4.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include -#include - -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_perspective(float field_of_view, float ratio, float z_near_plane, float z_far_plane) -{ - float yScale = 1.0f / (float)Calc::tan(field_of_view * 0.5f); - float xScale = yScale / ratio; - - Mat4x4 result; - - result.m11 = xScale; - result.m12 = result.m13 = result.m14 = 0.0f; - - result.m22 = yScale; - result.m21 = result.m23 = result.m24 = 0.0f; - - result.m31 = result.m32 = 0.0f; - result.m33 = z_far_plane / (z_near_plane - z_far_plane); - result.m34 = -1.0f; - - result.m41 = result.m42 = result.m44 = 0.0f; - result.m43 = z_near_plane * z_far_plane / (z_near_plane - z_far_plane); - - 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::create_lookat(Vec3 position, Vec3 target, Vec3 up) -{ - Vec3 zaxis = (position - target).normal(); - Vec3 xaxis = Vec3::cross(up, zaxis).normal(); - Vec3 yaxis = Vec3::cross(zaxis, xaxis); - - Mat4x4 result; - - result.m11 = xaxis.x; - result.m12 = yaxis.x; - result.m13 = zaxis.x; - result.m14 = 0.0f; - result.m21 = xaxis.y; - result.m22 = yaxis.y; - result.m23 = zaxis.y; - result.m24 = 0.0f; - result.m31 = xaxis.z; - result.m32 = yaxis.z; - result.m33 = zaxis.z; - result.m34 = 0.0f; - result.m41 = -Vec3::dot(xaxis, position); - result.m42 = -Vec3::dot(yaxis, position); - result.m43 = -Vec3::dot(zaxis, position); - result.m44 = 1.0f; - - 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; -} \ No newline at end of file diff --git a/src/numerics/rect.cpp b/src/numerics/rect.cpp deleted file mode 100644 index 0a66e88..0000000 --- a/src/numerics/rect.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include - -using namespace Blah; - -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; -} \ No newline at end of file diff --git a/src/numerics/rectI.cpp b/src/numerics/rectI.cpp deleted file mode 100644 index 9464c9d..0000000 --- a/src/numerics/rectI.cpp +++ /dev/null @@ -1,202 +0,0 @@ -#include -#include -#include -#include -#include - -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; -} - -int RectI::left() const -{ - return x; -} - -int RectI::right() const -{ - return x + w; -} - -int RectI::top() const -{ - return y; -} - -int RectI::bottom() const -{ - return y + h; -} - -int RectI::center_x() const -{ - return x + w / 2; -} - -int RectI::center_y() const -{ - return y + h / 2; -} - -Point RectI::center() const -{ - return Point(x + w / 2, y + h / 2); -} - -Point RectI::top_left() const -{ - return Point(x, y); -} - -Point RectI::top_right() const -{ - return Point(x + w, y); -} - -Point RectI::bottom_left() const -{ - return Point(x, y + h); -} - -Point RectI::bottom_right() const -{ - return Point(x + w, y + h); -} - -bool RectI::overlaps(const RectI& other) const -{ - return x < other.x + other.w - && other.x < x + w - && y < other.y + other.h - && other.y < y + h; -} - -RectI RectI::overlap_rect(const Rect& against) const -{ - RectI result = *this; - - if (x + w >= against.x && x < against.x + against.w) - { - result.x = Calc::max(x, (int)against.x); - result.w = Calc::min(x + w, (int)(against.x + against.w)) - result.x; - } - - if (y + h >= against.y && y < against.y + against.h) - { - result.y = Calc::max(y, (int)against.y); - result.h = Calc::min(y + h, (int)(against.y + against.h)) - result.y; - } - - return result; -} - -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; -} - -bool RectI::operator==(const RectI& rhs) const -{ - return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h; -} - -bool RectI::operator!=(const RectI& rhs) const -{ - return !(*this == rhs); -} - -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 int& rhs) const -{ - return RectI(x * rhs, y * rhs, w * rhs, h * rhs); -} - -RectI RectI::operator/(const int& rhs) const -{ - return RectI(x / rhs, y / rhs, w / rhs, h / rhs); -} - -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; -} diff --git a/src/streams/memorystream.cpp b/src/streams/memorystream.cpp index 0d92739..ff17eed 100644 --- a/src/streams/memorystream.cpp +++ b/src/streams/memorystream.cpp @@ -6,7 +6,7 @@ using namespace Blah; MemoryStream::MemoryStream() : m_data(nullptr), m_length(0), m_position(0) {} -MemoryStream::MemoryStream(char* data, size_t length) +MemoryStream::MemoryStream(unsigned char* data, size_t length) : m_data(data), m_length(length), m_position(0) {} MemoryStream::MemoryStream(MemoryStream&& src) noexcept @@ -89,12 +89,12 @@ void MemoryStream::close() m_data = nullptr; m_length = m_position = 0; } -char* MemoryStream::data() +unsigned char* MemoryStream::data() { return m_data; } -const char* MemoryStream::data() const +const unsigned char* MemoryStream::data() const { return m_data; } diff --git a/src/time.cpp b/src/time.cpp index 50671a9..6b916f4 100644 --- a/src/time.cpp +++ b/src/time.cpp @@ -65,12 +65,12 @@ void Stopwatch::reset() start_time = std::chrono::duration_cast(system_clock::now().time_since_epoch()).count(); } -u64 Stopwatch::milliseconds() +u64 Stopwatch::milliseconds() const { return microseconds() / 1000; } -u64 Stopwatch::microseconds() +u64 Stopwatch::microseconds() const { return std::chrono::duration_cast(system_clock::now().time_since_epoch()).count() - start_time; }