/* * physics.c * * Calculate what happens * * (c) 2008 Thomas White * * thrust3d - a silly game * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "types.h" #include "model.h" #include "game.h" #include "utils.h" /* Acceleration due to gravity in metres per millisecond per millisecond */ #define GRAVITY (9.81e-6) /* Acceleration due to booster rocket, metres per ms per ms */ #define THRUST (GRAVITY*2) /* Acceleration due to forwards/backwards thrusters, m per ms per ms */ #define FTHRUST (GRAVITY*0.5) /* Air friction in (m per ms per ms) per (m per ms) */ #define FRICTION 0.0008 /* Lander craft turning speed in radians per ms per ms */ #define YAWTHRUST (M_PI/3000000) /* Conversion factor between friction and 'yawthrust' */ #define TORQUE 1 static void physics_process(ModelInstance *obj, Uint32 dt) { /* Air friction */ if ( obj->vx > 0.0 ) { obj->vx -= FRICTION * dt * obj->vx; if ( obj->vx < 0.0 ) obj->vx = 0.0; } else { obj->vx += FRICTION * dt * -obj->vx; if ( obj->vx > 0.0 ) obj->vx = 0.0; } if ( obj->vy > 0.0 ) { obj->vy -= FRICTION * dt * obj->vy; if ( obj->vy < 0.0 ) obj->vy = 0.0; } else { obj->vy += FRICTION * dt * -obj->vy; if ( obj->vy > 0.0 ) obj->vy = 0.0; } if ( obj->vz > 0.0 ) { obj->vz -= FRICTION * dt * obj->vz; if ( obj->vz < 0.0 ) obj->vz = 0.0; } else { obj->vz += FRICTION * dt * -obj->vz; if ( obj->vz > 0.0 ) obj->vz = 0.0; } if ( obj->yawspeed > 0.0 ) { obj->yawspeed -= FRICTION * dt * obj->yawspeed * TORQUE; if ( obj->yawspeed < 0.0 ) obj->yawspeed = 0.0; } else { obj->yawspeed += FRICTION * dt * -obj->yawspeed * TORQUE; if ( obj->yawspeed > 0.0 ) obj->yawspeed = 0.0; } /* Gravity */ if ( obj->attribs & OBJ_GRAVITY ) obj->vz -= GRAVITY * dt; /* Take a step */ obj->x += obj->vx * dt; obj->y += obj->vy * dt; obj->z += obj->vz * dt; obj->yaw += obj->yawspeed * dt; if ( obj->yaw < -M_PI ) obj->yaw += 2*M_PI; if ( obj->yaw > M_PI ) obj->yaw -= 2*M_PI; } void physics_step(Game *game) { int i, j; Uint32 dt, t; t = SDL_GetTicks(); dt = t - game->tlast; /* Handle things specific to the lander craft */ if ( game->thrusting ) { game->lander->vz += THRUST * dt; } if ( game->forward ) { game->lander->vx += sinf(game->lander->yaw) * FTHRUST * dt; game->lander->vy += cosf(game->lander->yaw) * FTHRUST * dt; } else if ( game->reverse ) { game->lander->vx -= sinf(game->lander->yaw) * FTHRUST * dt; game->lander->vy -= cosf(game->lander->yaw) * FTHRUST * dt; } if ( game->turn_left ) { game->lander->yawspeed -= YAWTHRUST * dt; /* -ve yaw is "left" */ } if ( game->turn_right ) { game->lander->yawspeed += YAWTHRUST *dt; /* +ve yaw is "right" */ } physics_process(game->lander, dt); game_check_handoff(game); for ( j=0; jnum_rooms; j++ ) { Room *room; room = game->rooms[j]; if ( room == NULL ) return; for ( i=0; inum_objects; i++ ) { ModelInstance *obj; obj = room->objects[i]; if ( obj == NULL ) continue; physics_process(obj, dt); } } //game->view_angle = deg2rad(30.0 - 30.0 * game->lander->vz/0.015); game->tlast = t; }