1
1
Fork 0
Browse Source

add elastic collisions, accurate friction

thread-physics
alistair 4 years ago
parent
commit
f22a3d0a42
  1. 2
      draw.c
  2. 86
      game.c
  3. 5
      game.h
  4. 3
      main.c

2
draw.c

@ -256,7 +256,7 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) { @@ -256,7 +256,7 @@ int distance_colour(int x, int y, int x2, int y2, int blackpoint) {
}
void update_viewport(double x, double y) {
float xmargin = 0.26;
float xmargin = 0.5;
float ymargin = 0.2;
if (player.physics->position.x - viewport_pos.x > (1-xmargin) * width) {

86
game.c

@ -196,13 +196,12 @@ player_st get_player(int x, int y) { @@ -196,13 +196,12 @@ player_st get_player(int x, int y) {
player.physics->position.x = x;
player.physics->position.y = y;
player.physics->next_position = player.physics->position;
player.physics->obj_elasticity = 0.9;
player.physics->obj_friction = 0.3;
// friction (not in use)
player.physics->glob_friction = 40; // drag coef * area
// collisions
player.physics->obj_elasticity = 0.7;
player.physics->collision_poly_size = 4 + 4;
player.physics->collision_poly = calloc(player.physics->collision_poly_size, sizeof(Vect));
@ -764,9 +763,17 @@ void advance_thing(Body * thing) { @@ -764,9 +763,17 @@ void advance_thing(Body * thing) {
translation.x = translation.y = 0;
int numcols = 0;
uint32_t now = SDL_GetTicks();
uint32_t time_delta = now - thing->last_advance_time ;
if (time_delta > 20) {
printf("ERROR too slow: %d\n", time_delta);
thing->last_advance_time = now;
time_delta = 20;
}
printf("TimeDELTA: %d\n", time_delta);
// collisions
if ((numcols = process_collisions(thing, &translation))) {
double mag = vect_mag(translation);
/*double check = vect_scalar_projection(translation, thing->vel);*/
/*if (check >= 0) {*/
@ -774,42 +781,72 @@ void advance_thing(Body * thing) { @@ -774,42 +781,72 @@ void advance_thing(Body * thing) {
/*translation.y *= -1;*/
/*}*/
// correct position using translation vector.
thing->next_position.x += translation.x;
thing->next_position.y += translation.y;
// make unit vector
double mag = vect_mag(translation);
translation.x = translation.x / mag;
translation.y = translation.y / mag;
// get velocity in direction of collision
mag = vect_scalar_projection(thing->vel, translation);
Vect revert_vel;
revert_vel.x = cos(vect_dir(translation)) * mag;
revert_vel.y = sin(vect_dir(translation)) * mag;
thing->vel.x -= revert_vel.x;
thing->vel.y -= revert_vel.y;
// accel
double norm = 9.81 * thing->obj_mass;
double fric_const = 0.52;
Vect x;
x.y = 0; x.x = 1;
if (vect_scalar_projection(thing->vel, translation) > 0) {
friction.x = translation.y;
friction.y = -translation.x;
// add elasticity
thing->vel.x -= revert_vel.x * sqrt(thing->obj_elasticity);
thing->vel.y -= revert_vel.y * sqrt(thing->obj_elasticity);
// add friction
Vect friction = vect_rotate(revert_vel, M_PI / 2);
double dir = vect_scalar_projection(thing->vel, friction);
if (dir > 0) {
friction = vect_rotate(friction, M_PI);
}
double normal = vect_mag(revert_vel);
printf("norm: %f\n", normal);
if (fabs(thing->vel.x) <= fabs(friction.x)) {
thing->vel.x = 0;
} else {
thing->vel.x += thing->obj_friction * friction.x;
}
if (fabs(thing->vel.y) <= fabs(friction.y)) {
thing->vel.y = 0;
} else {
friction.x = -translation.y;
friction.y = translation.x;
thing->vel.y += thing->obj_friction * friction.y;
}
printf("velocity: %f %f\n", thing->vel.x, thing->vel.y);
/*double norm = 9.81 * thing->obj_mass;*/
/*Vect x;*/
/*x.y = 0; x.x = 1;*/
/*if (vect_scalar_projection(thing->vel, translation) > 0) {*/
/*friction.x = translation.y;*/
/*friction.y = -translation.x;*/
/*} else {*/
/*friction.x = -translation.y;*/
/*friction.y = translation.x;*/
/*}*/
// force
friction.x = friction.x * norm * fric_const;
friction.y = friction.y * norm * fric_const;
/*friction.x = friction.x * norm * fric_const;*/
/*friction.y = friction.y * norm * fric_const;*/
// printf("friction accel: %e %e\n", friction.x, friction.y);
// printf("velocity: %e %e\n", thing->vel.x, thing->vel.y);
set_motor_newtons(thing, M_FRICTION, friction.x, friction.y);
set_motor_max_velocity(thing, M_FRICTION, vect_mag(project_vect(thing->vel, friction)));
/*set_motor_newtons(thing, M_FRICTION, friction.x, friction.y);*/
/*set_motor_max_velocity(thing, M_FRICTION, vect_mag(project_vect(thing->vel, friction)));*/
// restitution force
/*rest.x = 0;*/
@ -855,14 +892,6 @@ void advance_thing(Body * thing) { @@ -855,14 +892,6 @@ void advance_thing(Body * thing) {
}
}
uint32_t now = SDL_GetTicks();
uint32_t time_delta = now - thing->last_advance_time ;
if (time_delta > 18) {
thing->last_advance_time = now;
time_delta = 18;
}
printf("TimeDELTA: %d\n", time_delta);
// motors
for (int i = 0; i < thing->num_motors; i++) {
@ -1078,10 +1107,9 @@ void startgame(SDL_Renderer * ren) { @@ -1078,10 +1107,9 @@ void startgame(SDL_Renderer * ren) {
world = create_world();
SDL_GetRendererOutputSize(ren, &width, &height);
player = get_player(200,300);
player = get_player(200,1300);
world_thing player_world;

5
game.h

@ -92,6 +92,8 @@ typedef struct BodyStruct{ @@ -92,6 +92,8 @@ typedef struct BodyStruct{
// properties
double obj_mass; // kgs
double obj_elasticity; // rho
double obj_friction; // between 0 and 1 (fraction of lateral velocity
// that is removed)
//float x_vel;
//float y_vel;
@ -100,9 +102,6 @@ typedef struct BodyStruct{ @@ -100,9 +102,6 @@ typedef struct BodyStruct{
//float y_acc;
/*------------------*/
// constants
double elasticity;
// collisions
Vect *collision_poly;
Vect *collision_shape;

3
main.c

@ -93,7 +93,7 @@ int game(void) { @@ -93,7 +93,7 @@ int game(void) {
SDL_Thread *physics_thread;
int ignore;
physics_thread = SDL_CreateThread(physics_loop, "Physics", (void *)NULL);
// physics_thread = SDL_CreateThread(physics_loop, "Physics", (void *)NULL);
bool once = true;
startgame(ren);
@ -114,6 +114,7 @@ int game(void) { @@ -114,6 +114,7 @@ int game(void) {
}
/* Redraw Screen */
redraw(ren);
step(10);
}
}

Loading…
Cancel
Save