From d882e111b3ab84cd8be687be5e3b82ce64aee4b6 Mon Sep 17 00:00:00 2001 From: frank Date: Sat, 16 Sep 2023 21:04:43 -0400 Subject: [PATCH] - fix sb::Pad to move the collision box when scaled or translated - add warning about config JSON copy - add setter for sb::Pad::_plane - move point on circle functions from extension to math --- src/Configuration.hpp | 9 ++++++++- src/Pad.hpp | 36 ++++++++++++++++++++++++------------ src/Selection.hpp | 8 ++++++-- src/extension.cpp | 31 ------------------------------- src/extension.hpp | 5 +---- src/math.cpp | 22 ++++++++++++++++++++++ src/math.hpp | 28 ++++++++++++++++++++++++++++ 7 files changed, 89 insertions(+), 50 deletions(-) diff --git a/src/Configuration.hpp b/src/Configuration.hpp index 61c6a24..f57d95c 100644 --- a/src/Configuration.hpp +++ b/src/Configuration.hpp @@ -33,9 +33,16 @@ private: Animation auto_refresher = Animation(std::bind(&Configuration::refresh, this)); fs::file_time_type config_file_modification_time; - nlohmann::json config; std::vector files_to_refresh; + /*! + * @warning This JSON will be copied when the object is copied, and it is potentially a large copy because it can copy an arbitrary amount of + * JSON data. Because a game object by definition has a single configuration, this can be optimized in the future so that the JSON is stored + * in a member of the game object. Arguably it also doesn't make sense to be copying the data because the JSON is expected to change during + * runtime. + */ + nlohmann::json config; + /*! * Fill the config JSON with default values set by the framework. */ diff --git a/src/Pad.hpp b/src/Pad.hpp index 38b5969..ce6943f 100644 --- a/src/Pad.hpp +++ b/src/Pad.hpp @@ -48,7 +48,7 @@ namespace sb using Reaction = std::function; sb::Switch connection; - sb::Plane plane; + sb::Plane _plane; Box box; public: @@ -78,7 +78,7 @@ namespace sb * @param rotation angle in radians to rotate the pad */ Pad(const sb::Plane& plane, glm::vec2 translation = {0.0f, 0.0f}, float scale = 1.0f, float ratio = 1.0f, - Reaction on_state_change = Reaction(), float rotation = 0.0f) : plane(plane) + Reaction on_state_change = Reaction(), float rotation = 0.0f) : _plane(plane) { box.size({2.0f, 2.0f}, true); if (translation != glm::vec2{0.0f, 0.0f}) @@ -96,6 +96,16 @@ namespace sb this->on_state_change(on_state_change); } + /*! + * Assign a new plane to the pad. The existing plane will be replaced. + * + * @param plane plane or plane derivative to represent the pad visually + */ + void plane(const sb::Plane& plane) + { + _plane = plane; + } + /*! * Rotate the pad around its center by 90 degrees. If a count is given, rotate by 90 degrees that many times, so for example, * a count of 3 will be a 270 degree rotation. If the count is negative, rotate -90 degrees. @@ -104,7 +114,7 @@ namespace sb */ void rotate(int count = 1) { - plane.transform(glm::rotate(count * glm::half_pi(), glm::vec3{0.0f, 0.0f, 1.0f})); + _plane.transform(glm::rotate(count * glm::half_pi(), glm::vec3{0.0f, 0.0f, 1.0f})); } /*! @@ -129,8 +139,9 @@ namespace sb { scale.y *= ratio; } + box.size({2.0f, 2.0f}, true); box.scale({scale.x, scale.y}, true); - return plane.scale(scale); + return _plane.scale(scale); } /*! @@ -140,8 +151,9 @@ namespace sb */ const glm::mat4& translate(const glm::vec2& translation) { + box.center({0.0f, 0.0f}); box.move(translation); - return plane.translate({translation.x, translation.y, 0.0f}); + return _plane.translate({translation.x, translation.y, 0.0f}); } /*! @@ -203,23 +215,23 @@ namespace sb */ void draw(GLuint transformation_uniform, glm::mat4 view, glm::mat4 projection, std::optional texture_flag_uniform = std::nullopt) { - if (!plane.textures().empty()) + if (!_plane.textures().empty()) { if (texture_flag_uniform.has_value()) { glUniform1i(texture_flag_uniform.value(), true); } - plane.texture().bind(); + _plane.texture().bind(); } else if (texture_flag_uniform.has_value()) { glUniform1i(texture_flag_uniform.value(), false); } - glm::mat4 mvp = projection * view * plane.transformation(); + glm::mat4 mvp = projection * view * _plane.transformation(); glUniformMatrix4fv(transformation_uniform, 1, GL_FALSE, &mvp[0][0]); - plane.enable(); - glDrawArrays(GL_TRIANGLES, 0, plane.attributes("position")->count()); - plane.disable(); + _plane.enable(); + glDrawArrays(GL_TRIANGLES, 0, _plane.attributes("position")->count()); + _plane.disable(); } /*! @@ -238,7 +250,7 @@ namespace sb */ std::size_t size() const { - return plane.size(); + return _plane.size(); } }; } diff --git a/src/Selection.hpp b/src/Selection.hpp index bc99d5d..e4e805b 100644 --- a/src/Selection.hpp +++ b/src/Selection.hpp @@ -72,13 +72,17 @@ namespace sb offset = container.size() - 1; } - /* Return true if the selection currently points to the location at the beginning of the container. */ + /*! + * @return true if the selection currently points to the location at the beginning of the container + */ bool at_beginning() const { return offset == 0; } - /* Return true if the selection currently points to the location at the end of the container. */ + /*! + * @return true if the selection currently points to the location at the end of the container + */ bool at_end() { return offset >= container.size() - 1; diff --git a/src/extension.cpp b/src/extension.cpp index dc2f105..dc3fc2e 100644 --- a/src/extension.cpp +++ b/src/extension.cpp @@ -17,37 +17,6 @@ void sb::set_magnitude(glm::vec2& vector, float magnitude) vector = glm::normalize(vector) * magnitude; } -/* Return coordinates of a point x, y at specified angle on a circle described by center and radius */ -glm::vec2 sb::point_on_circle(const glm::vec2& center, float radius, float angle) -{ - return {center.x + std::sin(angle) * radius, center.y - std::cos(angle) * radius}; -} - -/* Return a point x, y at specified angle on a circle at the origin with specified radius (default 1) */ -glm::vec2 sb::point_on_circle(float angle, float radius) -{ - return point_on_circle({0, 0}, radius, angle); -} - -/* Fill a pre-initialized vector with points evenly spaced around a circle starting at the angle offset (defaults to 0) */ -void sb::points_on_circle(std::vector& points, int count, float radius, const glm::vec2& center, float offset) -{ - float step = glm::two_pi() / count; - for (int ii = 0; ii < count; ii++) - { - points.push_back(point_on_circle(center, radius, ii * step + offset)); - } -} - -/* Return a vector of count number of points evenly spaced around a circle starting at the angle offset (defaults to 0) */ -std::vector sb::points_on_circle(int count, float radius, const glm::vec2& center, float offset) -{ - std::vector points; - points.reserve(count); - points_on_circle(points, count, radius, center, offset); - return points; -} - Box sb::get_texture_box(SDL_Texture* texture) { int width, height; diff --git a/src/extension.hpp b/src/extension.hpp index b0a93e3..1cae1e2 100644 --- a/src/extension.hpp +++ b/src/extension.hpp @@ -58,10 +58,6 @@ namespace sb enum scaler {scale2x, xbr}; void set_magnitude(glm::vec2&, float); - glm::vec2 point_on_circle(const glm::vec2&, float, float); - glm::vec2 point_on_circle(float, float = 1.0f); - void points_on_circle(std::vector&, int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f); - std::vector points_on_circle(int, float = 1.0f, const glm::vec2& = {0, 0}, float = 0.0f); Box get_texture_box(SDL_Texture*); glm::vec2 fit_and_preserve_aspect(const glm::vec2&, const glm::vec2&); std::vector> get_blinds_boxes(glm::vec2, float = 0.05f, int = 4); @@ -89,6 +85,7 @@ namespace sb std::vector glob(fs::path); fs::path get_next_file_name(fs::path, int = 0, std::string = "", std::string = ""); + /*! * Read the file at path into a string and return the string. * diff --git a/src/math.cpp b/src/math.cpp index c80b243..8fe5592 100644 --- a/src/math.cpp +++ b/src/math.cpp @@ -30,6 +30,28 @@ float sb::angle_ratio(float start, float end) return sb::angle_difference(start, end) / glm::pi(); } +glm::vec2 sb::point_on_circle(const glm::vec2& center, float angle, float radius) +{ + return center + sb::angle_to_vector(angle, radius); +} + +void sb::points_on_circle(std::vector& points, int count, float radius, const glm::vec2& center, float offset) +{ + float step = glm::two_pi() / count; + for (int ii = 0; ii < count; ii++) + { + points.push_back(point_on_circle(center, radius, ii * step + offset)); + } +} + +std::vector sb::points_on_circle(int count, float radius, const glm::vec2& center, float offset) +{ + std::vector points; + points.reserve(count); + points_on_circle(points, count, radius, center, offset); + return points; +} + std::vector sb::bezier(const std::vector& control, int resolution) { std::vector points; diff --git a/src/math.hpp b/src/math.hpp index 4cce54b..69e737c 100644 --- a/src/math.hpp +++ b/src/math.hpp @@ -98,6 +98,34 @@ namespace sb */ float angle_ratio(float start, float end); + /*! + * Return the coordinates of a point on a circle at a given angle. The circle is passed by giving a center and radius. + * + * @param center vector representing the center of the circle + * @param angle angle along the circle, 0 being up, going clockwise + * @param radius radius of the circle + * @return a vector representing a point along the circle's edge at the given angle + */ + glm::vec2 point_on_circle(const glm::vec2& center, float angle, float radius = 1.0f); + + /*! + * Fill a vector with count number of points evenly spaced around a circle starting at the angle offset (defaults to 0). + * + * @param points vector that will be filled with 2D vectors representing the requested points + * @param count number of points + * @param radius radius of the circle + * @param center 2D vector representing the center of the circle + * @param offset start calculating the points offset from 0 degrees (up on the screen) + */ + void points_on_circle(std::vector& points, int count, float radius = 1.0f, const glm::vec2& center = {0.0f, 0.0f}, float offset = 0.0f); + + /*! + * Create and return a vector of count number of points evenly spaced around a circle starting at the angle offset (defaults to 0). + * + * @see points_on_circle(std::vector&, int, float, const glm::vec2&, float) + */ + std::vector points_on_circle(int count, float radius = 1.0f, const glm::vec2& center = {0.0f, 0.0f}, float offset = 0.0f); + /*! * Calculate a 2D bezier curve from four 2D control points. *