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