28 #define MAX_TURN_LIMIT 0.2618f // about 15 degrees
30 #define ROTVEL_TOL 0.1 // Amount of rotvel is decreased if over cap
31 #define ROTVEL_CAP 14.0 // Rotational velocity cap for live objects
32 #define DEAD_ROTVEL_CAP 16.3 // Rotational velocity cap for dead objects
34 #define MAX_SHIP_SPEED 500 // Maximum speed allowed after whack or shockwave
35 #define RESET_SHIP_SPEED 440 // Speed that a ship is reset to after exceeding MAX_SHIP_SPEED
37 #define SW_ROT_FACTOR 5 // increase in rotational time constant in shockwave
38 #define SW_BLAST_DURATION 2000 // maximum duration of shockwave
39 #define REDUCED_DAMP_FACTOR 10 // increase in side_slip and acceleration time constants (scaled according to reduced damp time)
40 #define REDUCED_DAMP_VEL 30 // change in velocity at which reduced_damp_time is 2000 ms
41 #define REDUCED_DAMP_TIME 2000 // ms (2.0 sec)
42 #define WEAPON_SHAKE_TIME 500 // ms (0.5 sec) viewer shake time after hit by weapon (implemented via afterburner shake)
43 #define SPECIAL_WARP_T_CONST 0.651 // special warp time constant (loose 99 % of excess speed in 3 sec)
46 float velocity_ramp (
float v_in,
float v_goal,
float time_const,
float t);
47 float glide_ramp (
float v_in,
float v_goal,
float ramp_time_const,
float accel_mult,
float t);
108 void apply_physics(
float damping,
float desired_vel,
float initial_vel,
float t,
float * new_vel,
float * delta_pos )
110 if ( damping < 0.0001
f ) {
112 *delta_pos = desired_vel*
t;
114 *new_vel = desired_vel;
117 dv = initial_vel - desired_vel;
118 e = (
float)exp( -t/damping );
120 *delta_pos = (1.0f - e)*dv*damping + desired_vel*t;
122 *new_vel = dv*e + desired_vel;
138 Viewer_physics_info =
p;
156 float shock_amplitude;
158 float shock_fraction_time_left;
165 shock_amplitude = 0.0f;
231 &new_vel.
xyz.x, NULL );
234 &new_vel.
xyz.y, NULL );
237 &new_vel.
xyz.z, NULL );
246 t1.
h = 0.0f; t1.
b = 0.0f;
247 t2.
p = 0.0f; t2.
b = 0.0f;
267 vec3d local_desired_vel;
326 int special_warp_in =
FALSE;
329 special_warp_in =
TRUE;
337 float deficeit = temp.
xyz.z - local_v_in.
xyz.z;
338 local_v_out.
xyz.z = local_v_in.
xyz.z + deficeit * (1.0f - exp_factor);
339 local_disp.
xyz.z = (local_v_in.
xyz.z * sim_time) + deficeit * (sim_time - (
float(
SPECIAL_WARP_T_CONST) * (1.0f - exp_factor)));
357 if (special_warp_in) {
397 NULL, &predicted_pos->
xyz.x );
400 NULL, &predicted_pos->
xyz.y );
403 NULL, &predicted_pos->
xyz.z );
410 predicted_vel = &pi->
vel;
413 &predicted_vel->
xyz.x, NULL );
416 &predicted_vel->
xyz.y, NULL );
419 &predicted_vel->
xyz.z, NULL );
428 &predicted_vel->
xyz.x, &predicted_pos->
xyz.x );
431 &predicted_vel->
xyz.y, &predicted_pos->
xyz.y );
434 &predicted_vel->
xyz.z, &predicted_pos->
xyz.z );
443 #define BANK_WHEN_TURN
452 float ramp_time_const;
460 if ( wash_rot && Wash_on ) {
467 else if (ci->
pitch < -1.0f ) ci->
pitch = -1.0f;
478 if (ci->
bank > 1.0f ) ci->
bank = 1.0f;
479 else if (ci->
bank < -1.0f ) ci->
bank = -1.0f;
498 vec3d tmp_vec, new_rotvel;
499 matrix tmp_mat, eyemat, rotvelmat;
508 new_rotvel.
xyz.x = tmp_vec.
xyz.x;
520 #ifdef BANK_WHEN_TURN
567 float reduced_damp_ramp_time_expansion;
570 reduced_damp_ramp_time_expansion = 1.0f + (
REDUCED_DAMP_FACTOR-1) * reduced_damp_fraction_time_left;
572 reduced_damp_ramp_time_expansion = 1.0f;
578 if ( goal_vel.
xyz.x > 0.0f ) {
583 }
else if ( goal_vel.
xyz.x < 0.0f ) {
593 ramp_time_const *= reduced_damp_ramp_time_expansion;
598 if ( goal_vel.
xyz.y > 0.0f ) {
603 }
else if ( goal_vel.
xyz.y < 0.0f ) {
613 ramp_time_const *= reduced_damp_ramp_time_expansion;
623 if ( goal_vel.
xyz.z > 0.0f ) {
634 }
else if ( goal_vel.
xyz.z < 0.0f ) {
645 ramp_time_const *= reduced_damp_ramp_time_expansion;
651 float dynamic_glide_cap_goal = 0.0;
671 float curGlideCap = 0.0f;
680 float cap_decay_threshold = 0.95f;
681 float cap_decay_amount = 0.2f;
686 if (goal_vel.
xyz.x == 0.0f)
688 if (goal_vel.
xyz.y == 0.0f)
690 if (goal_vel.
xyz.z == 0.0f)
702 if (goal_vel.
xyz.z >= 0.0f)
721 if ( currentmag > curGlideCap ) {
774 #define WHACK_LIMIT 0.001f
775 #define ROTVEL_WHACK_CONST 0.12
778 vec3d local_torque, torque;
834 delta_v = v_goal - v_in;
838 if (dist < ramp_time_const/3)
839 ramp_time_const = dist / 3;
842 if ( ramp_time_const < 0.0001
f ) {
849 decay_factor = (
float)exp(- t / ramp_time_const);
851 return (v_in + delta_v * (1.0
f - decay_factor) );
857 float glide_ramp (
float v_in,
float v_goal,
float ramp_time_const,
float accel_mult,
float t)
859 if (v_goal == 0.0
f) {
867 float delta_v = 0.0f;
868 if (accel_mult < 0.0
f) {
870 delta_v =
MAX(
MIN(v_goal - v_in, v_goal), 0.0
f);
873 delta_v =
MIN(
MAX(v_goal - v_in, v_goal), 0.0
f);
877 delta_v = v_goal * accel_mult;
881 float decay_factor = (ramp_time_const > 0.0f) ? (1.0
f - (
float)exp(-t / ramp_time_const)) : 1.0
f;
882 return delta_v * decay_factor;
901 #define STD_PRESSURE 1000 // amplitude of standard shockwave blasts
902 #define MIN_RADIUS 10 // radius within which full rotvel and shake applied
903 #define MAX_RADIUS 50 // radius at which no rotvel or shake applied
904 #define MAX_ROTVEL 0.4 // max rotational velocity
905 #define MAX_SHAKE 0.1 // max rotational amplitude of shake
906 #define MAX_VEL 8 // max vel from shockwave
910 vec3d local_torque, temp_torque, torque;
945 if ( normal.
xyz.x < 0.0f )
950 vm_vec_cross( &temp_torque, &impact_vec, direction_vec );
954 if ( normal.
xyz.y < 0.0f )
959 vm_vec_cross( &temp_torque, &impact_vec, direction_vec );
963 if ( normal.
xyz.z < 0.0f )
968 vm_vec_cross( &temp_torque, &impact_vec, direction_vec );
1006 nprintf((
"Physics",
"speed reset in physics_apply_shock [speed: %f]\n",
vm_vec_mag(&pi->
vel)));
1025 #define ROTVEL_COLLIDE_WHACK_CONST 1.0
1028 vec3d body_delta_rotvel;
1034 vm_vec_rotate( &body_delta_rotvel, world_delta_rotvel, orient );
1054 nprintf((
"Physics",
"speed reset in physics_collide_whack [speed: %f]\n",
vm_vec_mag(&pi->
vel)));
1066 if ( 0 == pi->
flags )
1072 int change_made = 0;
1116 int reduced_damp_decay_time;
1124 if ( time_left > 0 ) {
1126 int new_time = reduced_damp_decay_time + time_left;
1141 avd_movement::avd_movement() : Pc(0.0
f), Vc(0.0
f), TSi(0), Pi(0.0
f), Vi(0.0
f), Pf(0.0
f), Tf(0.0
f), Tai(0.0
f), Taf(0.0
f), Vf(0.0
f), Vm(0.0
f), Ai(0.0
f), Af(0.0
f)
1176 if(Position != NULL)
1178 if(Velocity != NULL)
1185 this->
get(time, Position, Velocity);
1191 Pi = Pf = Pc = position;
1194 void avd_movement::setAVD(
float final_position,
float total_movement_time,
float starting_accleration_time,
float ending_acceleration_time,
float final_velocity)
1199 Pf = final_position;
1200 Tf = total_movement_time;
1201 Tai = starting_accleration_time;
1202 Taf = ending_acceleration_time;
1203 Vf = final_velocity;
1222 Vm = (Pf-Pi-0.5f*(Vi*Tai)-0.5
f*(Vf*Taf)) / (Tf - 0.5
f*Tai - 0.5
f*Taf);
1232 Tf = total_movement_time;
1234 Taf = ending_acceleration_time;
1235 Vf = final_velocity;
1243 Pf = Pi + Pf*(Tf - Taf) + Vm*Taf + 0.5
f*Af*(Taf*Taf);
1263 Pc = Pf + Vf*(Time-Tf);
1278 if(t >= 0.0
f && Tai > 0.0
f)
1284 Pc = Pc + Vi*Tc + 0.5f*Ai*(Tc*Tc);
1288 if(t >= Tai && (Tai+Taf) < Tf)
1299 if(t >= (Tf-Taf) && Taf > 0.0f)
1306 Pc = Pc + Vm*Tc + 0.5f*Af*(Tc*Tc);
int timestamp(int delta_ms)
void physics_predict_pos_and_vel(physics_info *pi, float delta_time, vec3d *predicted_vel, vec3d *predicted_pos)
int is_valid_matrix(const matrix *m)
void setVD(float total_movement_time, float ending_acceleration_time, float final_velocity)
float vm_vec_mag_quick(const vec3d *v)
matrix * vm_matrix_x_matrix(matrix *dest, const matrix *src0, const matrix *src1)
float vm_vec_mag(const vec3d *v)
float afterburner_forward_accel_time_const
void physics_set_viewer(physics_info *p, int dir)
matrix * vm_angles_2_matrix(matrix *m, const angles *a)
float side_slip_time_const
void get(float Time, float *Position, float *Velocity)
struct vec3d::@225::@227 xyz
#define PF_SPECIAL_WARP_IN
matrix * vm_copy_transpose(matrix *dest, const matrix *src)
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
float afterburner_reverse_accel
void physics_set_rotvel_and_saturate(float *dest, float delta)
float booster_forward_accel_time_const
GLenum GLenum GLenum GLenum GLenum scale
float glide_ramp(float v_in, float v_goal, float ramp_time_const, float accel_mult, float t)
void physics_apply_shock(vec3d *direction_vec, float pressure, physics_info *pi, matrix *orient, vec3d *min, vec3d *max, float radius)
void apply_physics(float damping, float desired_vel, float initial_vel, float t, float *new_vel, float *delta_pos)
float vm_vec_mag_squared(const vec3d *v)
void ship_get_eye(vec3d *eye_pos, matrix *eye_orient, object *obj, bool do_slew, bool from_origin)
#define IS_VEC_NULL_SQ_SAFE(v)
float forward_decel_time_const
#define PF_SPECIAL_WARP_OUT
void physics_sim_vel(vec3d *position, physics_info *pi, float sim_time, matrix *orient)
void physics_collide_whack(vec3d *impulse, vec3d *world_delta_rotvel, physics_info *pi, matrix *orient, bool is_landing)
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
void vm_vec_add2(vec3d *dest, const vec3d *src)
struct matrix::@228::@230 vec
void vm_vec_scale(vec3d *dest, float s)
int timestamp_until(int stamp)
void physics_sim_editor(vec3d *position, matrix *orient, physics_info *pi, float sim_time)
ai_profile_t * ai_profile
float slide_decel_time_const
void physics_sim_rot(matrix *orient, physics_info *pi, float sim_time)
bool Flight_controls_follow_eyepoint_orientation
void vm_orthogonalize_matrix(matrix *m_src)
void physics_init(physics_info *pi)
#define ROTVEL_WHACK_CONST
float vm_vec_normalize_safe(vec3d *v)
void setAVD(float final_position, float total_movement_time, float starting_accleration_time, float ending_acceleration_time, float final_velocity)
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
#define REDUCED_DAMP_TIME
vec3d afterburner_max_vel
#define vm_vec_make(v, _x, _y, _z)
int Physics_viewer_direction
void vm_vec_copy_scale(vec3d *dest, const vec3d *src, float s)
#define PHYSICS_VIEWER_FRONT
float forward_cruise_percent
int is_valid_vec(const vec3d *vec)
void physics_read_flying_controls(matrix *orient, physics_info *pi, control_info *ci, float sim_time, vec3d *wash_rot)
int check_rotvel_limit(physics_info *pi)
void physics_sim(vec3d *position, matrix *orient, physics_info *pi, float sim_time)
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
#define AIPF2_GLIDE_DECAY_REQUIRES_THRUST
#define REDUCED_DAMP_FACTOR
void physics_predict_pos(physics_info *pi, float delta_time, vec3d *predicted_pos)
float Physics_viewer_bank
physics_info * Viewer_physics_info
float forward_accel_time_const
float vm_vec_copy_normalize(vec3d *dest, const vec3d *src)
void physics_apply_whack(vec3d *impulse, vec3d *pos, physics_info *pi, matrix *orient, float mass)
float slide_accel_time_const
float afterburner_max_reverse_vel
#define timestamp_elapsed(stamp)
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
#define WEAPON_SHAKE_TIME
float velocity_ramp(float v_in, float v_goal, float time_const, float t)
float shockwave_shake_amp
#define SPECIAL_WARP_T_CONST
#define PF_AFTERBURNER_ON
vec3d * vm_vec_cross(vec3d *dest, const vec3d *src0, const vec3d *src1)
void physics_sim_rot_editor(matrix *orient, physics_info *pi, float sim_time)
void physics_predict_vel(physics_info *pi, float delta_time, vec3d *predicted_vel)
#define timestamp_valid(stamp)
#define SW_BLAST_DURATION
void update_reduced_damp_timestamp(physics_info *pi, float impulse)
float vm_vec_normalize(vec3d *v)