|
|
|
@ -146,6 +146,8 @@ void get_new_physics(Body **phys) {
@@ -146,6 +146,8 @@ void get_new_physics(Body **phys) {
|
|
|
|
|
// friction
|
|
|
|
|
add_motor(physics, 0.0, 0.0); |
|
|
|
|
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC_RAW, &physics->last_advance_time); |
|
|
|
|
|
|
|
|
|
physics->updateCollisionPoly = default_update_collision_poly; |
|
|
|
|
*phys = physics;
|
|
|
|
|
return; |
|
|
|
@ -197,7 +199,7 @@ player_st get_player(int x, int y) {
@@ -197,7 +199,7 @@ player_st get_player(int x, int y) {
|
|
|
|
|
player.physics->position.y = y; |
|
|
|
|
player.physics->next_position = player.physics->position; |
|
|
|
|
player.physics->obj_elasticity = 0.9; |
|
|
|
|
player.physics->obj_friction = 0.3; |
|
|
|
|
player.physics->obj_friction = 0.2; |
|
|
|
|
|
|
|
|
|
// friction (not in use)
|
|
|
|
|
player.physics->glob_friction = 40; // drag coef * area
|
|
|
|
@ -537,10 +539,15 @@ void set_motor_max_velocity(Body *thing, int motorID, double max) {
@@ -537,10 +539,15 @@ void set_motor_max_velocity(Body *thing, int motorID, double max) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void set_motor_timeout(Body *thing, int motorID, uint32_t timeout) { |
|
|
|
|
thing->motors[motorID].timeout = timeout; |
|
|
|
|
thing->motors[motorID].stop = false; |
|
|
|
|
clock_gettime(CLOCK_MONOTONIC_RAW, &thing->motors[motorID].timeout); |
|
|
|
|
thing->motors[motorID].timeout.tv_nsec += 1000000 * timeout; |
|
|
|
|
thing->motors[motorID].timeout.tv_sec
|
|
|
|
|
= thing->motors[motorID].timeout.tv_nsec * 0.000000001; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void set_motor_newtons(Body *thing, int motorID, double x, double y) { |
|
|
|
|
thing->motors[motorID].stop = false; |
|
|
|
|
thing->motors[motorID].x =x; |
|
|
|
|
thing->motors[motorID].y =y; |
|
|
|
|
} |
|
|
|
@ -557,9 +564,11 @@ void add_motor(Body *thing, double x, double y) {
@@ -557,9 +564,11 @@ void add_motor(Body *thing, double x, double y) {
|
|
|
|
|
memset(&motor, 0, sizeof(Motor)); |
|
|
|
|
motor.x = x; |
|
|
|
|
motor.y = y; |
|
|
|
|
motor.stop = false; |
|
|
|
|
motor.stop = true; |
|
|
|
|
|
|
|
|
|
motor.timeout.tv_sec = 3600000000000 * 0.000000001; |
|
|
|
|
motor.timeout.tv_nsec = 3600000000000; |
|
|
|
|
|
|
|
|
|
motor.timeout = -1; |
|
|
|
|
motor.max_velocity = 999899; |
|
|
|
|
|
|
|
|
|
motor.update_motor = default_motor_curve; |
|
|
|
@ -724,7 +733,6 @@ int process_collisions(Body *thing, Vect *trans) {
@@ -724,7 +733,6 @@ int process_collisions(Body *thing, Vect *trans) {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
printf("Tested %d collisions\n", num); |
|
|
|
|
|
|
|
|
|
if (!num_cols) { |
|
|
|
|
thing->colliding = false; |
|
|
|
@ -743,12 +751,10 @@ int process_collisions(Body *thing, Vect *trans) {
@@ -743,12 +751,10 @@ int process_collisions(Body *thing, Vect *trans) {
|
|
|
|
|
void advance_thing(Body * thing) { |
|
|
|
|
// TODO: fix ordering of collision detection + physics sim so that collisions
|
|
|
|
|
// are less bad.
|
|
|
|
|
|
|
|
|
|
thing->acc.x = 0; |
|
|
|
|
thing->acc.y = 0; |
|
|
|
|
|
|
|
|
|
set_motor_newtons(thing, M_FRICTION, 0,0); |
|
|
|
|
set_motor_max_velocity(thing, M_FRICTION, 0); |
|
|
|
|
|
|
|
|
|
if (!thing->dynamics) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
@ -763,18 +769,30 @@ void advance_thing(Body * thing) {
@@ -763,18 +769,30 @@ 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); |
|
|
|
|
/*uint32_t now = SDL_GetTicks();*/ |
|
|
|
|
/*uint32_t time_delta = now - thing->last_advance_time ;*/ |
|
|
|
|
struct timespec now; |
|
|
|
|
clock_gettime(CLOCK_MONOTONIC_RAW, &now); |
|
|
|
|
if (now.tv_nsec >= 1000000000) { |
|
|
|
|
now.tv_nsec -= 1000000000; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
double time_delta = now.tv_nsec - thing->last_advance_time.tv_nsec; |
|
|
|
|
if (now.tv_nsec < thing->last_advance_time.tv_nsec) { |
|
|
|
|
time_delta = now.tv_nsec - (thing->last_advance_time.tv_nsec - 1000000000); |
|
|
|
|
} |
|
|
|
|
time_delta *= 0.000001; // convert to ms from ns
|
|
|
|
|
|
|
|
|
|
if (time_delta > 19) { |
|
|
|
|
printf("ERROR too slow: %f\n", time_delta); |
|
|
|
|
thing->last_advance_time = now; |
|
|
|
|
time_delta = 20; |
|
|
|
|
time_delta = 19; |
|
|
|
|
} |
|
|
|
|
printf("TimeDELTA: %d\n", time_delta); |
|
|
|
|
printf("TimeDELTA: %f\n", time_delta); |
|
|
|
|
thing->last_advance_time = now; |
|
|
|
|
|
|
|
|
|
// collisions
|
|
|
|
|
if ((numcols = process_collisions(thing, &translation))) { |
|
|
|
|
|
|
|
|
|
/*double check = vect_scalar_projection(translation, thing->vel);*/ |
|
|
|
|
/*if (check >= 0) {*/ |
|
|
|
|
/*translation.x *= -1;*/ |
|
|
|
@ -806,27 +824,27 @@ void advance_thing(Body * thing) {
@@ -806,27 +824,27 @@ void advance_thing(Body * thing) {
|
|
|
|
|
thing->vel.y -= revert_vel.y * sqrt(thing->obj_elasticity); |
|
|
|
|
|
|
|
|
|
// add friction
|
|
|
|
|
|
|
|
|
|
if (vect_mag(translation) < 0.1) { |
|
|
|
|
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); |
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 { |
|
|
|
|
thing->vel.y += thing->obj_friction * friction.y;
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (fabs(thing->vel.x) <= fabs(friction.x)) { |
|
|
|
|
thing->vel.x = 0; |
|
|
|
|
} else { |
|
|
|
|
thing->vel.x += thing->obj_friction * friction.x;
|
|
|
|
|
printf("velocity: %f %f\n", thing->vel.x, thing->vel.y); |
|
|
|
|
} |
|
|
|
|
if (fabs(thing->vel.y) <= fabs(friction.y)) { |
|
|
|
|
thing->vel.y = 0; |
|
|
|
|
} else { |
|
|
|
|
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;*/ |
|
|
|
@ -891,12 +909,13 @@ void advance_thing(Body * thing) {
@@ -891,12 +909,13 @@ void advance_thing(Body * thing) {
|
|
|
|
|
thing->vel.y -= corr_mag * sin(angle); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// motors
|
|
|
|
|
for (int i = 0; i < thing->num_motors; i++) { |
|
|
|
|
if (thing->motors[i].timeout < now
|
|
|
|
|
if (thing->motors[i].timeout.tv_nsec < now.tv_nsec
|
|
|
|
|
&& thing->motors[i].timeout.tv_sec < now.tv_sec
|
|
|
|
|
|| thing->motors[i].stop) { |
|
|
|
|
printf("%ld %ld %d\n", thing->motors[i].timeout.tv_nsec, now.tv_nsec, thing->motors[i].stop); |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
if (thing->motors[i].update_motor) { |
|
|
|
@ -925,8 +944,8 @@ void advance_thing(Body * thing) {
@@ -925,8 +944,8 @@ void advance_thing(Body * thing) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// accelerate based on accel
|
|
|
|
|
thing->vel.x += thing->acc.x * (float)time_delta; |
|
|
|
|
thing->vel.y += thing->acc.y * (float)time_delta; |
|
|
|
|
thing->vel.x += thing->acc.x * (double)time_delta; |
|
|
|
|
thing->vel.y += thing->acc.y * (double)time_delta; |
|
|
|
|
|
|
|
|
|
double velocity = sqrt((double)(thing->vel.x * thing->vel.x + thing->vel.y * thing->vel.y)); |
|
|
|
|
printf("\nvels %e %e\n\n", thing->vel.x, thing->vel.y); |
|
|
|
@ -956,10 +975,10 @@ void advance_thing(Body * thing) {
@@ -956,10 +975,10 @@ void advance_thing(Body * thing) {
|
|
|
|
|
|
|
|
|
|
double oldx = thing->position.x; |
|
|
|
|
double oldy = thing->position.y; |
|
|
|
|
thing->position = thing->next_position; |
|
|
|
|
thing->next_position.x += (thing->vel.x * 1/2 * (double)time_delta);
|
|
|
|
|
thing->next_position.y += (thing->vel.y * 1/2 * (double)time_delta);
|
|
|
|
|
thing->last_advance_time = now; // in milliseconds
|
|
|
|
|
thing->position = thing->next_position; |
|
|
|
|
//thing->last_advance_time = now; // in milliseconds
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1004,15 +1023,17 @@ void advance_things(void) {
@@ -1004,15 +1023,17 @@ void advance_things(void) {
|
|
|
|
|
advance_thing(world.things[i].wall->physics); |
|
|
|
|
break; |
|
|
|
|
case FLOOR: |
|
|
|
|
for (int k = 0; k < world.things[i].floor->numPolys; k++) { |
|
|
|
|
advance_thing(world.things[i].floor->polys[k].physics); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
/*for (int k = 0; k < world.things[i].floor->numPolys; k++) {*/ |
|
|
|
|
/*advance_thing(world.things[i].floor->polys[k].physics);*/ |
|
|
|
|
/*}*/ |
|
|
|
|
/*break;*/ |
|
|
|
|
case CEILING: |
|
|
|
|
for (int k = 0; k < world.things[i].floor->numPolys; k++) { |
|
|
|
|
advance_thing(world.things[i].floor->polys[k].physics); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
/*for (int k = 0; k < world.things[i].floor->numPolys; k++) {*/ |
|
|
|
|
/*advance_thing(world.things[i].floor->polys[k].physics);*/ |
|
|
|
|
/*}*/ |
|
|
|
|
/*break;*/ |
|
|
|
|
case PROJECTILE: |
|
|
|
|
if ((numcols = process_collisions(world.things[i].projectile->physics, |
|
|
|
|
&translation))) { |
|
|
|
@ -1120,19 +1141,13 @@ void startgame(SDL_Renderer * ren) {
@@ -1120,19 +1141,13 @@ void startgame(SDL_Renderer * ren) {
|
|
|
|
|
|
|
|
|
|
add_to_world(player_world); |
|
|
|
|
|
|
|
|
|
world_thing wall_world; |
|
|
|
|
int wall_nodes[] = {500, 100, 200, 100, 100, 200, 900, 200}; |
|
|
|
|
wall_world.wall = get_long_wall(4, wall_nodes); |
|
|
|
|
wall_world.kind = STATIC_WALL_W; |
|
|
|
|
add_to_world(wall_world); |
|
|
|
|
|
|
|
|
|
viewport_pos.x = 700; |
|
|
|
|
viewport_pos.y = 0; |
|
|
|
|
|
|
|
|
|
get_room(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
float get_abs(float x,float y) { |
|
|
|
|
double get_abs(double x,double y) { |
|
|
|
|
return (sqrt(x*x + y*y)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|