1 /* 2 * Copyright (C) Volition, Inc. 1999. All rights reserved. 3 * 4 * All source code herein is the property of Volition, Inc. You may not sell 5 * or otherwise commercially exploit the source or things you created based on the 6 * source. 7 * 8 */ 9 10 11 12 #ifndef _PHYSICS_H 13 #define _PHYSICS_H 14 15 #include "math/vecmat.h" 16 17 18 #define PF_ACCELERATES (1 << 0) 19 #define PF_USE_VEL (1 << 1) // Use velocity present in physics_info struct, don't call physics_sim_vel. 20 #define PF_AFTERBURNER_ON (1 << 2) // Afterburner currently engaged. 21 #define PF_SLIDE_ENABLED (1 << 3) // Allow descent style sliding 22 #define PF_REDUCED_DAMP (1 << 4) // Allows reduced damping on z (for death, shockwave) (CAN be reset in physics) 23 #define PF_IN_SHOCKWAVE (1 << 5) // Indicates whether object has recently been hit by shockwave (used to enable shake) 24 #define PF_DEAD_DAMP (1 << 6) // Makes forward damping same as sideways (NOT reset in physics) 25 #define PF_AFTERBURNER_WAIT (1 << 7) // true when afterburner cannot be used. replaces variable used in afterburner code 26 #define PF_CONST_VEL (1 << 8) // Use velocity in phys_info struct. Optimize weapons in phys_sim 27 #define PF_WARP_IN (1 << 9) // Use when ship is warping in 28 #define PF_SPECIAL_WARP_IN (1 << 10) // Use when ship is warping in and we want to slow the ship faster than normal game physics 29 #define PF_WARP_OUT (1 << 11) // Use when ship is warping out 30 #define PF_SPECIAL_WARP_OUT (1 << 12) // Use when ship is warping out and we want to slow the ship faster than normal game physics 31 #define PF_BOOSTER_ON (1 << 13) 32 #define PF_GLIDING (1 << 14) 33 #define PF_FORCE_GLIDE (1 << 15) 34 #define PF_NEWTONIAN_DAMP (1 << 16) // SUSHI: Whether or not to use newtonian dampening 35 #define PF_NO_DAMP (1 << 17) // Goober5000 - don't damp velocity changes in physics; used for instantaneous acceleration 36 37 //information for physics sim for an object 38 typedef struct physics_info { 39 uint flags; //misc physics flags 40 41 float mass; //the mass of this object 42 vec3d center_of_mass; // Goober5000 - this is never ever used by physics; currently physics assumes the center of an object is the center of mass 43 matrix I_body_inv; // inverse moment of inertia tensor (used to calculate rotational effects) 44 45 float rotdamp; // for players, the exponential time constant applied to rotational velocity changes 46 // for AI ships and missiles, the polynomial approximation of the same, 47 // such that rotdamp * 2 is the total acceleration time 48 float side_slip_time_const; // time const for achieving desired velocity in the local sideways direction 49 // value should be zero for no sideslip and increase depending on desired slip 50 51 float delta_bank_const; //const that heading is multiplied by. 0 means no delta bank. 52 53 vec3d max_vel; //maximum foward velocity in x,y,z 54 vec3d afterburner_max_vel; // maximum foward velocity in x,y,z while afterburner engaged 55 vec3d booster_max_vel; 56 vec3d max_rotvel; //maximum p,b,h rotational velocity 57 float max_rear_vel; //maximum velocity in the backwards Z direction 58 59 // Acceleration rates. Only used if flag PF_ACCELERATES is set 60 // starting from rest time to reach .50 v_max 0.69 time const 61 // time to reach .75 v_max 1.39 time const 62 // 63 float forward_accel_time_const; // forward acceleration time const 64 float afterburner_forward_accel_time_const; // forward acceleration time const while afterburner engaged 65 float booster_forward_accel_time_const; 66 float forward_decel_time_const; // forward deceleration time const 67 float slide_accel_time_const; // slide acceleration time const 68 float slide_decel_time_const; // slide deceleration time const 69 float shockwave_shake_amp; // amplitude of shockwave shake at onset 70 71 // These get changed by the control code. The physics uses these 72 // as input values when doing physics. 73 vec3d prev_ramp_vel; // follows the user's desired velocity, in local coord 74 vec3d desired_vel; // in world coord, (possibly) damped by side_slip_time_const to get final vel 75 vec3d desired_rotvel; // in local coords, damped by rotdamp to get final rotvel 76 // With framerate_independent_turning, the AI are not damped, see physics_sim_rot 77 float forward_thrust; // How much the forward thruster is applied. 0-1. 78 float side_thrust; // How much the forward thruster is +x. 0-1. 79 float vert_thrust; // How much the forward thruster is +y. 0-1. 80 81 // Data that changes each frame. Physics fills these in each frame. 82 vec3d vel; // The current velocity vector of this object 83 vec3d rotvel; // The current rotational velecity (angles) 84 float speed; // Yes, this can be derived from velocity, but that's expensive! 85 float fspeed; // Speed in the forward direction. 86 float heading; 87 vec3d prev_fvec; // Used in AI for momentum. 88 matrix last_rotmat; // Used for moving two objects together and for editor. 89 90 int afterburner_decay; // timestamp used to control how long ship shakes after afterburner released 91 int shockwave_decay; // timestamp used to control how long ship affected after hit by shockwave 92 int reduced_damp_decay; // timestamp used to control how long ship ship has reduced damp physics 93 94 float glide_cap; //Backslash - for 'newtonian'-style gliding, the cap on velocity (so that something can't accelerate to ridiculous speeds... unless allowed to) 95 float cur_glide_cap; //SUSHI: Used for dynamic glide cap, so we can use the ramping function on the glide cap 96 float glide_accel_mult; //SUSHI: The acceleration multiplier for glide mode. A value < 0 means use glide ramping instead 97 98 float afterburner_max_reverse_vel; //SparK: This is the reverse afterburners top speed vector 99 float afterburner_reverse_accel; //SparK: Afterburner's acceleration on reverse mode 100 101 matrix ai_desired_orient; // Asteroth - This is only set to something other than the zero matrix if Framerate_independent_turning is enabled, and 102 // only by the AI after calls to angular_move. It is read and then zeroed out for the rest of the frame by physics_sim_rot 103 vec3d acceleration; // this is only the current trend of velocity in m/s^2, does NOT determine future velocity 104 } physics_info; 105 106 // control info override flags 107 #define CIF_DONT_BANK_WHEN_TURNING (1 << 0) // Goober5000 - changing heading does not change bank 108 #define CIF_DONT_CLAMP_MAX_VELOCITY (1 << 1) // Goober5000 - maneuvers can exceed tabled max velocity 109 #define CIF_INSTANTANEOUS_ACCELERATION (1 << 2) // Goober5000 - instantaneously jump to the goal velocity 110 #define CIF_DONT_OVERRIDE_OLD_MANEUVERS (1 << 3) // Asteroth - will attempt to maintain any old maneuvers still in progress 111 112 #define SW_ROT_FACTOR 5 // increase in rotational time constant in shockwave 113 #define SW_BLAST_DURATION 2000 // maximum duration of shockwave 114 115 // All of these are numbers from -1.0 to 1.0 indicating 116 // what percent of full velocity you want to go. 117 typedef struct control_info { 118 float pitch; // -1.0 to 1.0 119 float vertical; 120 float heading; 121 float sideways; 122 float bank; 123 float forward; 124 float forward_cruise_percent; // percentage used for forward cruising 125 // This is a special case from -100 to 100 126 127 // below is information that are used by the player controls for firing information. 128 int fire_primary_count; 129 int fire_secondary_count; 130 int fire_countermeasure_count; 131 int fire_debug_count; // should this be around an NDEBUG #if/#endif? 132 133 // afterburner control information 134 int afterburner_start; 135 int afterburner_stop; 136 137 int control_flags; // for sexp- and script-controlled maneuvers 138 139 } control_info; 140 141 extern int physics_paused; // Set means don't do physics, except for player. 142 143 // To use the "Descent-ship" physics: 144 // controls_read_all(&ci, FrameSecs ); 145 // physics_read_flying_controls( &ViewerOrient, &ViewerPhysics, FrameSecs, &ci ); 146 // physics_sim(&ViewerPos, &ViewerOrient, &ViewerPhysics, FrameSecs ); 147 extern void physics_init( physics_info * pi ); 148 extern void physics_read_flying_controls( matrix * orient, physics_info * pi, control_info * ci, float sim_time, vec3d *wash_rot=NULL); 149 extern void physics_sim(vec3d *position, matrix * orient, physics_info * pi, float sim_time ); 150 extern void physics_sim_editor(vec3d *position, matrix * orient, physics_info * pi, float sim_time); 151 152 extern void physics_sim_vel(vec3d * position, physics_info * pi, float sim_time, matrix * orient); 153 extern void physics_sim_rot(matrix * orient, physics_info * pi, float sim_time ); 154 extern bool whack_below_limit(const vec3d* impulse); 155 extern void physics_calculate_and_apply_whack(vec3d *force, vec3d *pos, physics_info *pi, matrix *orient, matrix *inv_moi); 156 extern void physics_apply_whack(float orig_impulse, physics_info* pi, vec3d *delta_rotvel, vec3d* delta_vel, matrix* orient); 157 extern void physics_apply_shock(vec3d *direction_vec, float pressure, physics_info *pi, matrix *orient, vec3d *min, vec3d *max, float radius); 158 extern void physics_collide_whack(vec3d *impulse, vec3d *delta_rotvel, physics_info *pi, matrix *orient, bool is_landing); 159 int check_rotvel_limit( physics_info *pi ); 160 extern void physics_add_point_mass_moi(matrix *moi, float mass, vec3d *pos); 161 162 163 // If physics_set_viewer is called with the viewer's physics_info, then 164 // this variable tracks the viewer's bank. This is used for g3_draw_rotated_bitmap. 165 extern float Physics_viewer_bank; 166 167 // If you would like Physics_viewer_bank to be tracked (Which is needed 168 // for rotating 3d bitmaps) call this and pass it a pointer to the 169 // viewer's physics info. 170 #define PHYSICS_VIEWER_FRONT 0 171 #define PHYSICS_VIEWER_LEFT 1 172 #define PHYSICS_VIEWER_RIGHT 2 173 #define PHYSICS_VIEWER_REAR 3 174 #define PHYSICS_VIEWER_UP 4 175 void physics_set_viewer( physics_info * p, int dir ); 176 177 //WMC - apply_physics 178 void apply_physics( float damping, float desired_vel, float initial_vel, float t, float * new_vel, float * delta_pos ); 179 180 //WMC - camera code type stuff 181 //Acceleration, constant Velocity, Deceleration (to another speed, so maybe not deceleration) 182 class avd_movement 183 { 184 private: 185 //Current 186 float Pc; //Current position 187 float Vc; //Current velocity 188 189 //Initial 190 int TSi; //Initial timestamp <-- note TIMESTAMP 191 float Pi; //Initial position 192 float Vi; //Initial velocity 193 194 //Given 195 float Pf; //Final position 196 float Tf; //Final duration 197 float Tai; //Starting acceleration duration 198 float Taf; //Ending acceleration duration 199 float Vf; //Final velocity 200 201 //Calculated 202 float Vm; //Middle velocity 203 float Ai; //Starting acceleration 204 float Af; //Ending acceleration 205 public: 206 avd_movement(); 207 void clear(); 208 209 void get(float Time, float *Position, float *Velocity); 210 void get(float *Position, float *Velocity); 211 212 void set(float position); 213 void setAVD(float final_position, float total_movement_time, float starting_accleration_time, float ending_acceleration_time, float final_velocity); 214 void setVD(float total_movement_time, float ending_acceleration_time, float final_velocity); 215 216 void update(float Time); 217 void update(); 218 }; 219 220 /* 221 #ifdef __cplusplus 222 } 223 #endif 224 */ 225 226 #endif // PHYSICS_H 227