diff options
author | max-001 <maxsmits21@kpnmail.nl> | 2024-12-09 14:14:03 +0100 |
---|---|---|
committer | max-001 <maxsmits21@kpnmail.nl> | 2024-12-09 14:14:03 +0100 |
commit | 857e408d6d3a8631b61ebd283b337819783f092c (patch) | |
tree | eb201efe09f033187c2ce9c51f68f0239e548a5d /src/crepe | |
parent | cdaf587006053874c2e286a7541e6a2b246ce2b3 (diff) |
Implemented oval path
Diffstat (limited to 'src/crepe')
-rw-r--r-- | src/crepe/api/AI.cpp | 46 | ||||
-rw-r--r-- | src/crepe/api/AI.h | 14 |
2 files changed, 60 insertions, 0 deletions
diff --git a/src/crepe/api/AI.cpp b/src/crepe/api/AI.cpp index 49f6b92..00e5b37 100644 --- a/src/crepe/api/AI.cpp +++ b/src/crepe/api/AI.cpp @@ -27,4 +27,50 @@ void AI::make_circle_path(float radius, vec2 center, float start_angle, bool clo } } +void AI::make_oval_path(float radius_x, float radius_y, vec2 center, float start_angle, + bool clockwise, float rotation) { + float max_radius = std::max(radius_x, radius_y); + // The step size is determined by the radius (step size is in radians) + float step = 400.0f / max_radius; + // Force at least 16 steps (in case of a small radius) + if (step > 2 * M_PI / 16) { + step = 2 * M_PI / 16; + } + // The path node distance is determined by the step size and the radius + path_node_distance = max_radius * step * 0.75f; + + auto rotate_point = [rotation](vec2 point, vec2 center) { + float s = sin(rotation); + float c = cos(rotation); + + // Translate point back to origin + point.x -= center.x; + point.y -= center.y; + + // Rotate point + float xnew = point.x * c - point.y * s; + float ynew = point.x * s + point.y * c; + + // Translate point back + point.x = xnew + center.x; + point.y = ynew + center.y; + + return point; + }; + + if (clockwise) { + for (float i = start_angle; i < 2 * M_PI + start_angle; i += step) { + vec2 point = {static_cast<float>(center.x + radius_x * cos(i)), + static_cast<float>(center.y + radius_y * sin(i))}; + path.push_back(rotate_point(point, center)); + } + } else { + for (float i = start_angle; i > start_angle - 2 * M_PI; i -= step) { + vec2 point = {static_cast<float>(center.x + radius_x * cos(i)), + static_cast<float>(center.y + radius_y * sin(i))}; + path.push_back(rotate_point(point, center)); + } + } +} + } // namespace crepe diff --git a/src/crepe/api/AI.h b/src/crepe/api/AI.h index 0dccd5f..c95924d 100644 --- a/src/crepe/api/AI.h +++ b/src/crepe/api/AI.h @@ -81,6 +81,20 @@ public: */ void make_circle_path(float radius, vec2 center = {0, 0}, float start_angle = 0, bool clockwise = true); + /** + * \brief Make an oval path (for the path following behavior) + * + * \note The path is not relative to the entity's position (it is an absolute path) + * + * \param radius_x The x radius of the oval (in game units) + * \param radius_y The y radius of the oval (in game units) + * \param center The center of the oval (in game units) + * \param start_angle The start angle of the oval (in radians) + * \param clockwise The direction of the oval + * \param rotation The rotation of the oval (in radians) + */ + void make_oval_path(float radius_x, float radius_y, vec2 center = {0, 0}, + float start_angle = 0, bool clockwise = true, float rotation = 0); public: //! The maximum force that can be applied to the entity (higher values will make the entity adjust faster) |