26 #define MIN_PAIRS 2500 // start out with this many pairs
27 #define PAIRS_BUMP 1000 // increase by this many avialable pairs when more are needed
59 : a(NULL), b(NULL), signature_a(-1), signature_b(-1), next_check_time(-1), initialized(
false)
72 if (Obj_pairs != NULL) {
104 pair_used_list.
a = pair_used_list.
b = NULL;
105 pair_used_list.
next = NULL;
106 pair_free_list.
a = pair_free_list.
b = NULL;
110 if (Obj_pairs != NULL) {
117 if ( Obj_pairs == NULL ) {
118 mprintf((
"Unable to create space for collision pairs!!\n"));
127 Obj_pairs[
i].
next = &Obj_pairs[i+1];
130 Obj_pairs[MIN_PAIRS-1].
next = NULL;
132 pair_free_list.
next = &Obj_pairs[0];
180 check_collision = NULL;
365 vec3d velocity_rel_weapon;
371 if ( vdot <= 0.0
f ) {
377 if ( pdot <= -A->radius ) {
411 if ( !check_collision )
return;
418 if ( pair_free_list.
next == NULL ) {
419 nprintf((
"collision",
"Out of object pairs!! Not all collisions will work!\n" ));
433 Assert( Obj_pairs != NULL );
439 int prev_free_mark = (pair_free_list.
next - old_pairs_ptr);
440 int prev_used_mark = (pair_used_list.
next - old_pairs_ptr);
446 if (Obj_pairs == NULL) {
448 Obj_pairs = old_pairs_ptr;
452 Assert( Obj_pairs != NULL );
456 if (i >= old_pair_count) {
457 memset( &Obj_pairs[i], 0,
sizeof(
obj_pair) );
458 Obj_pairs[
i].
next = &Obj_pairs[i+1];
460 if (Obj_pairs[i].next != NULL) {
463 int next_mark = (Obj_pairs[
i].
next - old_pairs_ptr);
464 Obj_pairs[
i].
next = &Obj_pairs[next_mark];
468 if ( i == (old_pair_count-1) ) {
469 Obj_pairs[
i].
next = &Obj_pairs[i+1];
474 Obj_pairs[Num_pairs_allocated-1].
next = NULL;
477 pair_free_list.
next = &Obj_pairs[prev_free_mark];
478 pair_used_list.
next = &Obj_pairs[prev_used_mark];
484 pair_free_list.
next = new_pair->
next;
489 last = tmp = pair_used_list.
next;
490 while( tmp != NULL ) {
491 if ( tmp->
next == NULL )
500 last->
next = new_pair;
502 new_pair->
next = NULL;
505 new_pair->
next = pair_used_list.
next;
506 pair_used_list.
next = new_pair;
516 if ( check_time == -1 ){
536 float avg_time_to_next_check = 0.0f;
539 if (Cmdline_dis_collisions)
551 while (tmp != NULL) {
557 if ( (tmp->
a) && (tmp->
b) ) {
562 #if 0 //def DONT_REMOVE_PAIRS
576 tmp->
a = tmp->
b = NULL;
578 pair_free_list.
next = tmp;
594 avg_time_to_next_check += (
float) add_time;
604 avg_time_to_next_check = avg_time_to_next_check /
Num_pairs;
630 float a_dist, b_dist, ab_dist;
638 if (ab_dist < a_dist + b_dist + prad + qrad) {
639 if (ab_dist < prad + qrad)
643 else if (
MAX(a_dist, b_dist) < prad + qrad + 1.0
f)
682 if (radius_scale == 0.0
f) {
685 float size_A, size_B, dist,
r;
688 size_A = A->
radius * radius_scale;
689 size_B = B->
radius * radius_scale;
695 nearest_point = prev_pos;
697 nearest_point = A->
pos;
700 ret = (dist < size_A + size_B);
719 if ((r >= 0.0
f) && (r <= 1.0
f)) {
722 return (dist < objp->radius * radius_scale);
749 vec3d velocity_rel_weapon;
755 if ( vdot <= 0.0
f ) {
761 if ( pdot <= -other->radius ) {
783 if ( current_pair ) {
788 float max_vel_weapon, max_vel_other;
800 if (max_vel_other < 10.0
f) {
805 max_vel_other = 10.0f;
814 vec3d delta_x, laser_vel;
815 float a,
b,
c, delta_x_dot_vl, delta_t;
816 float root1, root2, root, earliest_time;
818 if (max_vel_weapon == max_vel_other) {
827 delta_t = (other->
radius + 10.0f) / max_vel_other;
828 delta_x_dot_vl =
vm_vec_dot( &delta_x, &laser_vel );
830 a = max_vel_weapon*max_vel_weapon - max_vel_other*max_vel_other;
831 b = 2.0f * (delta_x_dot_vl - max_vel_other*max_vel_other*delta_t);
834 float discriminant = b*b - 4.0f*a*
c;
835 if ( discriminant < 0) {
839 root =
fl_sqrt( discriminant );
840 root1 = (-b + root) / (2.0
f * a) * 1000.0f;
841 root2 = (-b - root) / (2.0
f * a) * 1000.0f;
845 if (max_vel_weapon > max_vel_other) {
847 if ( root1 > root2 ) {
854 earliest_time = root1;
855 }
else if (root2 > 0) {
867 earliest_time = root2;
877 if ( earliest_time > 1000*wp->
lifeleft )
881 earliest_time -= 200.0f;
883 if (earliest_time > 100) {
893 float dist, max_vel, time;
895 max_vel = max_vel_weapon + max_vel_other;
900 time = (dist*1000.0f) / max_vel;
909 if ( time_ms > 100 ) {
954 if (1.5
f * radius < 70.0
f)
970 vec3d cur_pos, goal_pos;
985 if (
cpls_aux(&goal_pos, objp2, objp))
994 d1 = 2.5f * distance + objp2->
radius;
1000 for (; count>0; count--) {
1016 #define CRW_NO_OBJECT -1
1017 #define CRW_NO_PAIR 0
1018 #define CRW_IN_PAIR 1
1019 #define CRW_CAN_DELETE 2
1021 #define CRW_MAX_TO_DELETE 4
1027 float next_check_time;
1035 if ( wp->
lifeleft < next_check_time )
1042 int i, num_deleted, oldest_index, j, loop_count;
1047 if (
Weapons[i].objnum == -1 )
1058 while( opp != NULL ) {
1073 for ( it = Collision_cached_pairs.begin(); it != Collision_cached_pairs.end(); ++it ) {
1074 pair_obj = &it->second;
1117 oldest_time = 1000.0f;
1120 if (
Weapons[i].objnum == -1 )
1127 if ( oldest_index != -1 ) {
1138 }
while ( loop_count < 2);
1168 CheckObjects[obj_index].
type = objp->
type;
1179 Collision_sort_list.push_back(obj_index);
1192 for ( i = 0; i < Collision_sort_list.size(); ++
i ) {
1193 if ( Collision_sort_list[i] == obj_index ) {
1194 Collision_sort_list[
i] = Collision_sort_list.back();
1195 Collision_sort_list.pop_back();
1205 Collision_sort_list.clear();
1206 Collision_cached_pairs.clear();
1213 for ( it = Collision_cached_pairs.begin(); it != Collision_cached_pairs.end(); ++it ) {
1214 it->second.next_check_time =
timestamp(checkdly);
1229 sort_list_y.clear();
1233 sort_list_z.clear();
1237 sort_list_y.clear();
1246 bool first_not_added =
true;
1252 overlappers.clear();
1254 for ( i = 0; i < (*list).size(); ++
i ) {
1259 for ( j = 0; j < overlappers.size(); ) {
1261 if ( min <= overlap_max ) {
1264 if ( overlappers.size() == 1 && first_not_added ) {
1265 first_not_added =
false;
1266 overlap_list_out->push_back(overlappers[j]);
1273 overlappers[j] = overlappers.back();
1274 overlappers.pop_back();
1281 if ( overlappers.size() == 0 ) {
1282 first_not_added =
true;
1286 overlap_list_out->push_back((*list)[i]);
1289 overlappers.push_back((*list)[i]);
1301 float min_end, max_end;
1316 float min_end, max_end;
1347 if ( right > left ) {
1348 int pivot_index = left + (right -
left) / 2;
1353 int temp = (*list)[pivot_index];
1354 (*list)[pivot_index] = (*list)[
right];
1357 int store_index =
left;
1360 for ( i = left; i <
right; ++
i ) {
1363 (*list)[
i] = (*list)[store_index];
1364 (*list)[store_index] =
temp;
1369 temp = (*list)[
right];
1370 (*list)[
right] = (*list)[store_index];
1371 (*list)[store_index] =
temp;
1384 check_collision = NULL;
1534 if ( !check_collision )
return;
1547 collision_info = &Collision_cached_pairs[
key];
1555 collision_info->
a =
A;
1556 collision_info->
b =
B;
1562 collision_info->
a =
A;
1563 collision_info->
b =
B;
1595 vec3d velocity_rel_weapon;
1601 if ( vdot <= 0.0
f ) {
1607 if ( pdot <= -A->radius ) {
1653 if ( check_collision(&new_pair) ) {
void mc_info_init(mc_info *mc)
int beam_collide_asteroid(obj_pair *pair)
int model_collide(mc_info *mc_info_obj)
#define vm_malloc_q(size)
int timestamp(int delta_ms)
void obj_quicksort_colliders(SCP_vector< int > *list, int left, int right, int axis)
int collide_ship_ship(obj_pair *pair)
weapon Weapons[MAX_WEAPONS]
int vector_object_collision(vec3d *start_pos, vec3d *end_pos, object *objp, float radius_scale)
int cpls_aux(vec3d *goal_pos, object *objp2, object *objp)
int collide_weapon_weapon(obj_pair *pair)
void vm_vec_scale_add(vec3d *dest, const vec3d *src1, const vec3d *src2, float k)
weapon_info Weapon_info[MAX_WEAPON_TYPES]
int collide_asteroid_ship(obj_pair *pair)
float obj_get_collider_endpoint(int obj_num, int axis, bool min)
float vm_vec_mag(const vec3d *v)
int(* check_collision)(obj_pair *pair)
void obj_all_collisions_retime(int checkdly)
int collide_predict_large_ship(object *objp, float distance)
bool dock_check_find_docked_object(object *objp, object *other_objp)
int beam_collide_missile(obj_pair *pair)
void obj_reset_colliders()
struct vec3d::@225::@227 xyz
int beam_collide_debris(obj_pair *pair)
char crw_status[MAX_WEAPONS]
#define END_OF_LIST(head)
void obj_find_overlap_colliders(SCP_vector< int > *overlap_list_out, SCP_vector< int > *list, int axis, bool collide)
void vm_vec_scale_add2(vec3d *dest, const vec3d *src, float k)
int collide_debris_ship(obj_pair *pair)
int collide_remove_weapons()
int reject_due_collision_groups(object *A, object *B)
int objects_will_collide(object *A, object *B, float duration, float radius_scale)
int beam_collide_early_out(object *a, object *b)
void obj_remove_collider(int obj_index)
float vm_vec_mag_squared(const vec3d *v)
void obj_sort_and_collide()
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
void vm_vec_add2(vec3d *dest, const vec3d *src)
SCP_unordered_map< uint, collider_pair > Collision_cached_pairs
void obj_add_collider(int obj_index)
GLdouble GLdouble GLdouble r
struct matrix::@228::@230 vec
#define DETAIL_FLAG_COLLISION
void obj_collide_pair(object *A, object *B)
void vm_vec_scale(vec3d *dest, float s)
int timestamp_until(int stamp)
#define COLLISION_OF(a, b)
GLboolean GLboolean GLboolean GLboolean a
void crw_check_weapon(int weapon_num, int collide_next_check)
int weapon_will_never_hit(object *obj_weapon, object *other, obj_pair *current_pair)
int collide_debris_weapon(obj_pair *pair)
float vm_vec_normalized_dir(vec3d *dest, const vec3d *end, const vec3d *start)
float vm_vec_dist(const vec3d *v0, const vec3d *v1)
#define MONITOR(function_name)
int pp_collide(vec3d *curpos, vec3d *goalpos, object *goalobjp, float radius)
int collide_ship_weapon(obj_pair *pair)
#define MC_CHECK_SPHERELINE
float vm_vec_dist_squared(const vec3d *v0, const vec3d *v1)
object Objects[MAX_OBJECTS]
#define MONITOR_INC(function_name, inc)
SCP_vector< int > Collision_sort_list
void set_hit_struct_info(collision_info_struct *hit, mc_info *mc, int submodel_rot_hit)
int ship_check_collision_fast(object *obj, object *other_obj, vec3d *hitpos)
int beam_collide_ship(obj_pair *pair)
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
int collide_asteroid_weapon(obj_pair *pair)
GLboolean GLboolean GLboolean b
#define vm_realloc_q(ptr, size)
int Cmdline_dis_collisions
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
checkobject CheckObjects[MAX_OBJECTS]
int Cmdline_old_collision_sys
void obj_delete(int objnum)
void obj_add_pair(object *A, object *B, int check_time, int add_to_end)
int collide_subdivide(vec3d *p0, vec3d *p1, float prad, vec3d *q0, vec3d *q1, float qrad)
float vm_vec_dist_quick(const vec3d *v0, const vec3d *v1)
int reject_obj_pair_on_parent(object *A, object *B)
SCP_vector< ship_info > Ship_info
vec3d * vm_vec_avg(vec3d *dest, const vec3d *src0, const vec3d *src1)
#define timestamp_elapsed(stamp)
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
void init_collision_info_struct(collision_info_struct *cis)
void obj_check_all_collisions()
float find_nearest_point_on_line(vec3d *nearest_point, const vec3d *p0, const vec3d *p1, const vec3d *int_pnt)
void obj_collide_retime_cached_pairs(int checkdly)
#define CRW_MAX_TO_DELETE