47 static int Collide_friendly = 1;
48 DCF_BOOL( collide_friendly, Collide_friendly )
51 static int Player_collide_sound, AI_collide_sound;
52 static int Player_collide_shield_sound, AI_collide_shield_sound;
60 ship *shipp1, *shipp2;
113 object *heavy_obj = ship_ship_hit_info->
heavy;
114 object *light_obj = ship_ship_hit_info->
light;
160 if ( !Collide_friendly ) {
161 if ( (!player_involved) && (heavy_shipp->
team == light_shipp->
team) ) {
169 if (heavy_shipp->
team == light_shipp->
team) {
190 vec3d p0_temp, p0_rotated;
206 static bool Warned_about_fast_rotational_collisions =
false;
207 if (!Warned_about_fast_rotational_collisions) {
208 Warning(
LOCATION,
"Ship '%s' rotates too quickly! Rotational collision detection has been skipped.", heavy_sip->
name);
209 Warned_about_fast_rotational_collisions =
true;
231 int copy_flags = mc.
flags;
232 vec3d copy_p0, copy_p1;
240 int valid_hit_occured = 0;
253 ship_ship_hit_info->
hit_time = FLT_MAX;
264 for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
276 for (smv = submodel_vector.begin(); smv != submodel_vector.end(); ++smv) {
304 valid_hit_occured = 1;
311 if (ship_ship_hit_info->
edge_hit == 0) {
316 vec3d int_light_pos, diff;
327 mc.
flags = copy_flags;
336 valid_hit_occured = 1;
341 if (ship_ship_hit_info->
edge_hit == 0) {
353 if (valid_hit_occured) {
357 object *collide_obj = NULL;
359 collide_obj = light_obj;
361 collide_obj = heavy_obj;
364 char *submode_string =
"";
373 nprintf((
"AI",
"Player collided with ship %s, AI mode = %s, submode = %s\n", Ships[collide_obj->
instance].ship_name, Mode_text[aip->
mode], submode_string));
395 if ( ship_ship_hit_info->
edge_hit ) {
407 if (heavy_shipp->
team == light_shipp->
team) {
452 return valid_hit_occured;
469 if (asteroid_type == 0) {
471 }
else if (asteroid_type == 1) {
487 if (asteroid_type == 0) {
489 }
else if (asteroid_type == 1) {
541 object *heavy = ship_ship_hit_info->
heavy;
542 object *lighter = ship_ship_hit_info->
light;
552 int special_cruiser_asteroid_collision;
553 int cruiser_light = 0;
554 float cruiser_mass = 0.0f, copy_mass = 0.0f;
557 if (special_cruiser_asteroid_collision) {
569 float coeff_restitution;
570 float v_rel_normal_m;
571 vec3d v_rel_parallel_m;
572 vec3d world_rotvel_heavy_m, world_rotvel_light_m, vel_from_rotvel_heavy_m, vel_from_rotvel_light_m, v_rel_m, vel_heavy_m, vel_light_m;
574 coeff_restitution = 0.1f;
585 vm_vec_cross(&vel_from_rotvel_heavy_m, &world_rotvel_heavy_m, &ship_ship_hit_info->
r_heavy);
586 vel_heavy_m = vel_from_rotvel_heavy_m;
590 vec3d local_vel_from_submodel;
619 vec3d omega, axis, r_rot;
651 vm_vec_cross(&vel_from_rotvel_light_m, &world_rotvel_light_m, &ship_ship_hit_info->
r_light);
653 vm_vec_sub(&v_rel_m, &vel_light_m, &vel_heavy_m);
661 if (v_rel_normal_m > 0) {
670 nprintf((
"Physics",
"Frame %i reset v_rel_normal_m %f Edge %i\n",
Framecount, v_rel_normal_m, ship_ship_hit_info->
edge_hit));
671 v_rel_normal_m = -v_rel_normal_m;
677 float light_uvec_dot_norm = 0.0f;
678 float light_fvec_dot_norm = 0.0f;
679 float light_rvec_dot_norm = 0.0f;
681 if (subsys_landing_allowed) {
687 if (subsys_landing_allowed &&
692 light_uvec_dot_norm > 0 &&
693 light_fvec_dot_norm < light_sip->collision_physics.landing_max_angle &&
700 vec3d rotational_impulse_heavy, rotational_impulse_light, delta_rotvel_heavy, delta_rotvel_light;
701 vec3d delta_vel_from_delta_rotvel_heavy, delta_vel_from_delta_rotvel_light, impulse;
702 float impulse_mag, heavy_denom, light_denom;
703 matrix heavy_I_inv, light_I_inv;
708 float collision_speed_parallel;
714 parallel_mag =
float(-friction) * collision_speed_parallel /
vm_vec_mag(&v_rel_m);
726 vm_vec_rotate(&delta_rotvel_heavy, &rotational_impulse_heavy, &heavy_I_inv);
729 vm_vec_cross(&delta_vel_from_delta_rotvel_heavy, &delta_rotvel_heavy , &ship_ship_hit_info->
r_heavy);
731 if (heavy_denom < 0) {
744 if (lighter ==
Player_obj || subsys_landing_allowed) {
750 vm_vec_rotate(&delta_rotvel_light, &rotational_impulse_light, &light_I_inv);
753 vm_vec_cross(&delta_vel_from_delta_rotvel_light, &delta_rotvel_light, &ship_ship_hit_info->
r_light);
755 if (light_denom < 0) {
764 impulse_mag = -(1.0f + coeff_restitution)*v_rel_normal_m / (heavy_denom + light_denom);
765 ship_ship_hit_info->
impulse = impulse_mag;
766 if (impulse_mag < 0) {
767 nprintf((
"Physics",
"negative impulse mag -- Get Dave A if not Descent Physics\n"));
768 impulse_mag = -impulse_mag;
784 if (subsys_landing_allowed &&
789 light_uvec_dot_norm > 0 &&
790 light_fvec_dot_norm < light_sip->collision_physics.reorient_max_angle &&
794 vec3d landing_delta_rotvel;
800 float xzVelMag = sqrt(light_local_vel.
xyz.x * light_local_vel.
xyz.x + light_local_vel.
xyz.z * light_local_vel.
xyz.z);
801 float xzVelDotOrient =
MIN(
MAX((xzVelMag > 0 ? (light_local_vel.
xyz.x / xzVelMag) : 0), -0.5f), 0.5f);
815 vec3d direction_light;
832 if (special_cruiser_asteroid_collision) {
865 #define PLANET_DAMAGE_SCALE 4.0f
866 #define PLANET_DAMAGE_RANGE 3 // If within this factor of radius, apply damage.
875 void mcp_1(
object *player_objp,
object *planet_objp)
880 planet_radius = planet_objp->
radius;
945 #define MIN_REL_SPEED_FOR_LOUD_COLLISION 50 // relative speed of two colliding objects at which we play the "loud" collide sound
949 Player_collide_sound = -1;
950 AI_collide_sound = -1;
951 Player_collide_shield_sound = -1;
952 AI_collide_shield_sound = -1;
969 if ( player_involved ) {
982 if ( player_involved ) {
1001 ship *ship1, *ship2;
1049 float added_perp_vel_mag = impulse / small_obj->
phys_info.
mass;
1066 int player_involved;
1068 object *
A = pair->
a;
1069 object *
B = pair->
b;
1083 player_involved = 1;
1085 player_involved = 0;
1099 if ( dist < A->radius + B->
radius ) {
1102 object *HeavyOne, *LightOne;
1127 ship_ship_hit_info.
heavy = HeavyOne;
1128 ship_ship_hit_info.
light = LightOne;
1130 vec3d world_hit_pos;
1144 if(!a_override && !b_override)
1153 damage = 0.005f * ship_ship_hit_info.
impulse;
1156 damage = 5.0f + (damage - 5.0f)/2.0
f;
1161 if (ship_ship_hit_info.
impulse > 0) {
1163 if ( player_involved && !ship_ship_hit_info.
is_landing) {
1171 if ( player_involved ) {
1187 if (player_involved && (ship_ship_hit_info.
impulse > 0)) {
1197 if ( !Collide_friendly ) {
1199 vec3d collision_vec, right_angle_vec;
1220 }
else if (Ships[LightOne->
instance].team == Ships[HeavyOne->
instance].team) {
1223 if ((LightOne->
radius < 50.0f) && (HeavyOne->
radius <50.0f)) {
1246 if(!(b_override && !a_override))
1251 if((b_override && !a_override) || (!b_override && !a_override))
1266 int sif_a_flags, sif_b_flags;
1278 float shipA_max_speed, shipB_max_speed, time;
1289 shipA_max_speed =
MAX(shipA_max_speed, 10.0
f);
1300 shipB_max_speed =
MAX(shipB_max_speed, 10.0
f);
1302 time = 1000.0f * (dist - A->
radius - B->
radius) / (shipA_max_speed + shipB_max_speed);
1340 *light_collide_cm_pos = *mc_info_obj->
p0;
1349 nprintf((
"Physics",
"Framecount: %i |r_light - core_rad| > 0.1)\n",
Framecount));
1352 if (ship_ship_hit_info->
edge_hit) {
1367 float q =
vm_vec_dist(heavy_collide_cm_pos, light_collide_cm_pos) / (heavier_obj->
radius + core_rad);
1369 nprintf((
"Physics",
"Warning: q = %f. Supposed to be <= 1.0.\n", q));
1372 *r_heavy = ship_ship_hit_info->
hit_pos;
1376 #ifdef COLLIDE_DEBUG
1377 nprintf((
"Physics",
"Frame: %i %s info: last_pos: [%4.1f, %4.1f, %4.1f], collide_pos: [%4.1f, %4.1f %4.1f] vel: [%4.1f, %4.1f %4.1f]\n",
1379 heavy_collide_cm_pos.
x, heavy_collide_cm_pos.
y, heavy_collide_cm_pos.
z,
1382 nprintf((
"Physics",
"Frame: %i %s info: last_pos: [%4.1f, %4.1f, %4.1f], collide_pos: [%4.1f, %4.1f, %4.1f] vel: [%4.1f, %4.1f, %4.1f]\n",
1384 light_collide_cm_pos.
x, light_collide_cm_pos.
y, light_collide_cm_pos.
z,
void mc_info_init(mc_info *mc)
int model_collide(mc_info *mc_info_obj)
int timestamp(int delta_ms)
void vm_vec_projection_onto_plane(vec3d *projection, const vec3d *src, const vec3d *unit_normal)
int collide_ship_ship(obj_pair *pair)
light ship-ship collide sound
void mcp_1(object *player_objp, object *planet_objp)
#define STI_SHIP_WARP_PUSHES
int maybe_collide_planet(object *obj1, object *obj2)
#define MSS_FLAG_ALLOW_LANDING
float vm_vec_mag_quick(const vec3d *v)
matrix * vm_matrix_x_matrix(matrix *dest, const matrix *src0, const matrix *src1)
#define PCM_WARPOUT_STAGE1
float ship_get_max_speed(ship *shipp)
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
polymodel * model_get(int model_num)
submodel_instance_info * sii
float shield_get_strength(object *objp)
SCP_vector< game_snd > Snds
float vm_vec_mag(const vec3d *v)
asteroid Asteroids[MAX_ASTEROIDS]
float ship_get_warpout_speed(object *objp)
int get_quadrant(vec3d *hit_pnt, object *shipobjp)
void model_get_rotating_submodel_list(SCP_vector< int > *submodel_vector, object *objp)
void calculate_ship_ship_collision_physics(collision_info_struct *ship_ship_hit_info)
int ship_is_beginning_warpout_speedup(object *objp)
float vm_vec_normalize_quick(vec3d *src)
void _cdecl void void _cdecl void _cdecl Warning(char *filename, int line, SCP_FORMAT_STRING const char *format,...) SCP_FORMAT_STRING_ARGS(3
int detail[MAX_MODEL_DETAIL_LEVELS]
#define SUBMODEL_NO_ROT_HIT
struct vec3d::@225::@227 xyz
#define SF2_DONT_COLLIDE_INVIS
heavy ship-ship collide sound
int snd_is_playing(int sig)
float model_get_core_radius(int modelnum)
matrix * vm_copy_transpose(matrix *dest, const matrix *src)
bool dock_check_find_direct_docked_object(object *objp, object *other_objp)
ai_info Ai_info[MAX_AI_INFO]
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
model_subsystem * subsystems
#define KAMIKAZE_HULL_ON_DEATH
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
void HUD_sourced_printf(int source, const char *format,...)
int reject_due_collision_groups(object *A, object *B)
float vm_vec_mag_squared(const vec3d *v)
script_state Script_system("FS2_Open Scripting")
fix Last_planet_damage_time
#define COLLISION_ROTATION_FACTOR
#define LANDING_POS_OFFSET
#define COLLISION_FRICTION_FACTOR
void physics_collide_whack(vec3d *impulse, vec3d *world_delta_rotvel, physics_info *pi, matrix *orient, bool is_landing)
int ship_ship_check_collision(collision_info_struct *ship_ship_hit_info, vec3d *hitpos)
vec3d heavy_collision_cm_pos
void model_instance_find_world_point(vec3d *outpnt, vec3d *mpnt, int model_instance_num, int submodel_num, const matrix *objorient, const vec3d *objpos)
void vm_vec_add2(vec3d *dest, const vec3d *src)
#define SIF2_ALLOW_LANDINGS
void collide_ship_ship_do_sound(vec3d *world_hit_pos, object *A, object *B, int player_involved)
int check_special_cruiser_asteroid_collision(object *heavy, object *lighter, float *cruiser_mass, int *cruiser_light)
void get_I_inv(matrix *I_inv, matrix *I_inv_body, matrix *orient)
struct matrix::@228::@230 vec
void vm_vec_scale(vec3d *dest, float s)
#define strnicmp(s1, s2, n)
int ship_get_sound(object *objp, GameSoundsIndex id)
Returns a ship-specific sound index.
int snd_play_3d(game_snd *gs, vec3d *source_pos, vec3d *listen_pos, float radius, vec3d *source_vel, int looping, float vol_scale, int priority, vec3d *sound_fvec, float range_factor, int force, bool is_ambient)
void vm_vec_sub2(vec3d *dest, const vec3d *src)
void world_find_model_instance_point(vec3d *out, vec3d *world_pt, const polymodel_instance *pmi, int submodel_num, const matrix *orient, const vec3d *pos)
submodel_instance * submodel
void hud_shield_quadrant_hit(object *objp, int quadrant)
bool check_subsystem_landing_allowed(ship_info *heavy_sip, collision_info_struct *ship_ship_hit_info)
char * Mode_text[MAX_AI_BEHAVIORS]
#define HUD_SOURCE_HIDDEN
float reorient_max_rot_angle
float vm_vec_normalized_dir(vec3d *dest, const vec3d *end, const vec3d *start)
float vm_vec_dist(const vec3d *v0, const vec3d *v1)
void hud_start_text_flash(char *txt, int t, int interval)
void model_init_submodel_axis_pt(submodel_instance_info *sii, int model_num, int submodel_num)
float vm_vec_normalize_safe(vec3d *v)
debris Debris[MAX_DEBRIS_PIECES]
#define MC_CHECK_SPHERELINE
void model_instance_find_obj_dir(vec3d *w_vec, vec3d *m_vec, int model_instance_num, int submodel_num, matrix *objorient)
vec3d * vm_vec_unrotate(vec3d *dest, const vec3d *src, const matrix *m)
shield ship-ship collide overlay sound
void ship_apply_global_damage(object *ship_objp, object *other_obj, vec3d *force_center, float damage)
#define MC_SUBMODEL_INSTANCE
object Objects[MAX_OBJECTS]
#define SF_ARRIVING_STAGE_1
const char * XSTR(const char *str, int index)
#define PLANET_DAMAGE_RANGE
void set_hit_struct_info(collision_info_struct *hit, mc_info *mc, int submodel_rot_hit)
int RunCondition(int condition, char format='\0', void *data=NULL, class object *objp=NULL, int more_data=0)
void SetHookObjects(int num,...)
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
void collide_ship_ship_sounds_init()
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
GLdouble GLdouble GLdouble GLdouble q
#define DCF_BOOL(function_name, bool_variable)
polymodel_instance * model_get_instance(int model_instance_num)
float vm_vec_dist_quick(const vec3d *v0, const vec3d *v1)
void collect_ship_ship_physics_info(object *heavier_obj, object *lighter_obj, mc_info *mc_info_obj, collision_info_struct *ship_ship_hit_info)
float vm_vec_copy_normalize(vec3d *dest, const vec3d *src)
void RemHookVars(unsigned int num,...)
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
SCP_vector< ship_info > Ship_info
void ship_apply_local_damage(object *ship_objp, object *other_obj, vec3d *hitpos, float damage, int quadrant, bool create_spark, int submodel_num, vec3d *hit_normal)
#define OF_SHOULD_BE_DEAD
#define STI_SHIP_WARP_PUSHABLE
GLsizei GLsizei GLuint * obj
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
void shield_set_strength(object *objp, float strength)
void init_collision_info_struct(collision_info_struct *cis)
ship_collision_physics collision_physics
#define MIN_LANDING_SOUND_VEL
int ship_hit_shield(object *obj, mc_info *mc, collision_info_struct *sshs)
void HUD_printf(const char *format,...)
int bay_emerge_or_depart(object *heavy_objp, object *light_objp)
vec3d * vm_vec_cross(vec3d *dest, const vec3d *src0, const vec3d *src1)
#define MC_CHECK_INVISIBLE_FACES
int is_planet(object *objp)
float landing_max_rot_angle
bool IsConditionOverride(int action, object *objp=NULL)
SCP_vector< asteroid_info > Asteroid_info
void gameseq_post_event(int event)
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
int ships_are_docking(object *objp1, object *objp2)
matrix vmd_identity_matrix
void joy_ff_play_vector_effect(vec3d *v, float scaler)
#define AIF_TARGET_COLLISION
char ship_name[NAME_LENGTH]
int ship_is_shield_up(object *obj, int quadrant)
void maybe_push_little_ship_from_fast_big_ship(object *big_obj, object *small_obj, float impulse, vec3d *normal)
int get_ship_quadrant_from_global(vec3d *global_pos, object *objp)
SCP_vector< ship_type_info > Ship_types
vec3d light_collision_cm_pos
#define PLANET_DAMAGE_SCALE
float vm_vec_normalize(vec3d *v)
#define MIN_REL_SPEED_FOR_LOUD_COLLISION
void do_kamikaze_crash(object *obj1, object *obj2)