From 6403b87fb09ae1b75120fcd4f73edc35fd68a39f Mon Sep 17 00:00:00 2001 From: Gitea Date: Tue, 31 May 2022 14:27:25 +0300 Subject: [PATCH] Constraints --- .gitignore | 2 +- src/app.cpp | 7 +++---- src/cloth.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++++-- src/cloth.hpp | 3 ++- src/main.cpp | 2 +- src/point.hpp | 7 ++++--- 6 files changed, 56 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 3ed4e45..f2e44a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -./cloth_sim \ No newline at end of file +cloth_sim \ No newline at end of file diff --git a/src/app.cpp b/src/app.cpp index dcaf4b7..42b30c7 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -68,14 +68,13 @@ void app_update(App* app) { return; } - compute_cloth_forces(app->cloth, app->conf.gravity); - - app->conf.gravity = Vec2f{app->conf.gravity.x-0.0005f, app->conf.gravity.y-0.001f}; - int updated_window_w; int updated_window_h; SDL_GetWindowSize(app->window->sdl_win, &updated_window_w, &updated_window_h); app->window->dimensions = Vec2{(unsigned int) updated_window_w, (unsigned int) updated_window_h}; + + compute_cloth_forces(app->cloth, app->conf.gravity); + satisfy_cloth_constraints(app->cloth, Vec2{0, 0}, Vec2{app->window->dimensions.x-5, app->window->dimensions.y-5}); } void destroy_app(App* app) { diff --git a/src/cloth.cpp b/src/cloth.cpp index a99b5d5..cdefa93 100644 --- a/src/cloth.cpp +++ b/src/cloth.cpp @@ -11,9 +11,24 @@ Cloth* new_cloth(Vec2 startpos, Vec2 dimensions, unsigned int spacing) { new_cloth->points = std::vector(); new_cloth->connections = std::vector(); + bool frozen_point = false; for (unsigned int y = 0; y < dimensions.y; y += spacing) { + if (y == 0) { + frozen_point = true; + } else { + frozen_point = false; + } + for (unsigned int x = 0; x < dimensions.x; x += spacing) { - Point* new_point = new Point{static_cast(startpos.x + x), static_cast(startpos.y + y), startpos.x + x, startpos.y + y, false}; + Point* new_point = new Point{ + .x = static_cast(startpos.x + x), + .y = static_cast(startpos.y + y), + .prev_x = static_cast(startpos.x + x), + .prev_y = static_cast(startpos.y + y), + .mass = 10.0f, + .frozen = frozen_point, + .selected = false, + }; new_cloth->points.push_back(new_point); if (x > 0) { @@ -55,7 +70,35 @@ void destroy_cloth(Cloth* cloth) { void compute_cloth_forces(Cloth* cloth, Vec2f gravity_vec) { for (Point* p : cloth->points) { + if (p->frozen) { + continue; + } p->x += gravity_vec.x; - p->y += gravity_vec.y; + p->y += gravity_vec.y; + } +} + + +void satisfy_cloth_constraints(Cloth* cloth, Vec2 top_left, Vec2 bottom_right) { + for (Point* p : cloth->points) { + // bottom + if (p->y > bottom_right.y) { + p->y = bottom_right.y; + } + + // right + if (p->x > bottom_right.x) { + p->x = bottom_right.x; + } + + // left + if (p->x < top_left.x) { + p->x = top_left.x; + } + + // up + if (p->y < top_left.y) { + p->y = top_left.y; + } } } \ No newline at end of file diff --git a/src/cloth.hpp b/src/cloth.hpp index bca4de2..74040a7 100644 --- a/src/cloth.hpp +++ b/src/cloth.hpp @@ -14,4 +14,5 @@ struct Cloth { Cloth* new_cloth(Vec2 startpos, Vec2 dimensions, unsigned int spacing); void destroy_cloth(Cloth* cloth); -void compute_cloth_forces(Cloth* cloth, Vec2f gravity_vec); \ No newline at end of file +void compute_cloth_forces(Cloth* cloth, Vec2f gravity_vec); +void satisfy_cloth_constraints(Cloth* cloth, Vec2 top_left, Vec2 bottom_right); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f9e8c4c..ea7b930 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -68,7 +68,7 @@ int main(const int argc, char** argv) { .cloth_startpos = Vec2{50, 50}, .cloth_dimensions = Vec2{400, 400}, .cloth_spacing = 20, - .gravity = Vec2f{0.3f, 0.8f}, + .gravity = Vec2f{0.0f, 1.5f}, .background_color = RGB{80, 100, 255}, .point_color = RGB{10, 10, 10}, .point_selected_color = RGB{200, 40, 12}, diff --git a/src/point.hpp b/src/point.hpp index 3e1a15c..3b3b666 100644 --- a/src/point.hpp +++ b/src/point.hpp @@ -12,8 +12,9 @@ struct Point { float x; float y; - unsigned int prev_x; - unsigned int prev_y; - unsigned int mass; + float prev_x; + float prev_y; + float mass; + bool frozen; bool selected; }; \ No newline at end of file