|
|
@ -1,5 +1,7 @@ |
|
|
|
#include "cloth.hpp" |
|
|
|
#include "cloth.hpp" |
|
|
|
#include "connection.hpp" |
|
|
|
#include "connection.hpp" |
|
|
|
|
|
|
|
#include "mouse.hpp" |
|
|
|
|
|
|
|
#include <cmath> |
|
|
|
#include <cstddef> |
|
|
|
#include <cstddef> |
|
|
|
#include <cstdio> |
|
|
|
#include <cstdio> |
|
|
|
#include <vector> |
|
|
|
#include <vector> |
|
|
@ -26,18 +28,12 @@ Cloth* new_cloth( |
|
|
|
bool frozen_point = false; |
|
|
|
bool frozen_point = false; |
|
|
|
for (unsigned int y = 0; y < dimensions.y; y += spacing) {
|
|
|
|
for (unsigned int y = 0; y < dimensions.y; y += spacing) {
|
|
|
|
for (unsigned int x = 0; x < dimensions.x; x += spacing) { |
|
|
|
for (unsigned int x = 0; x < dimensions.x; x += spacing) { |
|
|
|
// if (y == 0 && x == new_cloth->dimensions.x/2) {
|
|
|
|
|
|
|
|
// frozen_point = true;
|
|
|
|
|
|
|
|
// } else {
|
|
|
|
|
|
|
|
// frozen_point = false;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Point* new_point = new Point{ |
|
|
|
Point* new_point = new Point{ |
|
|
|
.x = static_cast<float>(startpos.x + x), |
|
|
|
.pos = Vec2f{static_cast<float>(startpos.x + x), static_cast<float>(startpos.y + y)}, |
|
|
|
.y = static_cast<float>(startpos.y + y), |
|
|
|
|
|
|
|
.mass = 10.0f, |
|
|
|
.mass = 10.0f, |
|
|
|
.frozen = frozen_point, |
|
|
|
.frozen = frozen_point, |
|
|
|
.selected = false, |
|
|
|
.selected = false, |
|
|
|
|
|
|
|
.radius = 2.5, |
|
|
|
}; |
|
|
|
}; |
|
|
|
new_cloth->points.push_back(new_point); |
|
|
|
new_cloth->points.push_back(new_point); |
|
|
|
|
|
|
|
|
|
|
@ -78,58 +74,58 @@ void destroy_cloth(Cloth* cloth) { |
|
|
|
delete cloth; |
|
|
|
delete cloth; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// calculate forces and actually MOVE points
|
|
|
|
// calculate forces, move points and satisfy constraints
|
|
|
|
void cloth_step(Cloth* cloth, Vec2f gravity_vec, float timedelta) { |
|
|
|
void cloth_step(Cloth* cloth, Mouse* mouse, Vec2f gravity_vec, float timedelta) { |
|
|
|
for (Point* p : cloth->points) { |
|
|
|
for (Point* p : cloth->points) { |
|
|
|
if (p->frozen) { |
|
|
|
if (p->frozen) { |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// calculate velocity
|
|
|
|
// handle mouse
|
|
|
|
if (p->y == cloth->constraint_bottom_right.y) { |
|
|
|
// ((x0 - x1)^2 + (y0 - y1)^2)^0.5
|
|
|
|
// if this point's x velocity is too small -> just stop it
|
|
|
|
float distance_to_point = std::sqrt(pow(p->pos.x - mouse->pos.x, 2.0f)+pow(p->pos.y - mouse->pos.y, 2.0f)); |
|
|
|
// else -> handle friction
|
|
|
|
if (distance_to_point <= mouse->cursor_radius_size) { |
|
|
|
if (p->velocity.x <= 0.5) { |
|
|
|
p->selected = true; |
|
|
|
p->velocity.x = 0; |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
p->velocity.x = p->velocity.x*cloth->friction_factor * timedelta; |
|
|
|
p->selected = false; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
|
|
|
|
p->velocity.x = p->velocity.x+(gravity_vec.x/p->mass) * timedelta; |
|
|
|
if (p->selected && mouse->left_button_clicked) { |
|
|
|
p->velocity.y = p->velocity.y+(gravity_vec.y/p->mass) * timedelta; |
|
|
|
p->pos = Vec2f{(float) mouse->pos.x, (float) mouse->pos.y}; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// calculate velocity
|
|
|
|
|
|
|
|
p->velocity.x = (p->velocity.x + (gravity_vec.x/p->mass)) * timedelta; |
|
|
|
|
|
|
|
p->velocity.y = (p->velocity.y + (gravity_vec.y/p->mass)) * timedelta; |
|
|
|
|
|
|
|
|
|
|
|
// move point
|
|
|
|
// move point
|
|
|
|
p->x += p->velocity.x; |
|
|
|
p->pos.x += p->velocity.x; |
|
|
|
p->y += p->velocity.y; |
|
|
|
p->pos.y += p->velocity.y; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// handle constraints, bounces
|
|
|
|
// now handle constraints
|
|
|
|
void satisfy_cloth_constraints(Cloth* cloth) { |
|
|
|
|
|
|
|
for (Point* p : cloth->points) { |
|
|
|
|
|
|
|
// bottom
|
|
|
|
// bottom
|
|
|
|
if (p->y > cloth->constraint_bottom_right.y) { |
|
|
|
if (p->pos.y >= cloth->constraint_bottom_right.y) { |
|
|
|
p->y = cloth->constraint_bottom_right.y; |
|
|
|
p->pos.y = cloth->constraint_bottom_right.y;
|
|
|
|
p->velocity.y = -p->velocity.y*cloth->efficiency_factor; |
|
|
|
p->velocity.x = (p->velocity.x * cloth->friction_factor); |
|
|
|
|
|
|
|
p->velocity.y = -p->velocity.y * cloth->efficiency_factor; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// right
|
|
|
|
// right
|
|
|
|
if (p->x > cloth->constraint_bottom_right.x) { |
|
|
|
if (p->pos.x >= cloth->constraint_bottom_right.x) { |
|
|
|
p->x = cloth->constraint_bottom_right.x; |
|
|
|
p->pos.x = cloth->constraint_bottom_right.x; |
|
|
|
p->velocity.x = -p->velocity.x*cloth->efficiency_factor; |
|
|
|
p->velocity.x = -p->velocity.x * cloth->efficiency_factor; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// left
|
|
|
|
// left
|
|
|
|
if (p->x < cloth->constraint_top_left.x) { |
|
|
|
if (p->pos.x <= cloth->constraint_top_left.x) { |
|
|
|
p->x = cloth->constraint_top_left.x; |
|
|
|
p->pos.x = cloth->constraint_top_left.x; |
|
|
|
p->velocity.x = -p->velocity.x*cloth->efficiency_factor; |
|
|
|
p->velocity.x = -p->velocity.x * cloth->efficiency_factor; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// up
|
|
|
|
// up
|
|
|
|
if (p->y < cloth->constraint_top_left.y) { |
|
|
|
if (p->pos.y <= cloth->constraint_top_left.y) { |
|
|
|
p->y = cloth->constraint_top_left.y; |
|
|
|
p->pos.y = cloth->constraint_top_left.y; |
|
|
|
p->velocity.y = -p->velocity.y*cloth->efficiency_factor; |
|
|
|
p->velocity.y = -p->velocity.y * cloth->efficiency_factor; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |