View Issue Details

IDProjectCategoryView StatusLast Update
0002673FSSCPmath-relatedpublic2012-07-02 01:45
ReporterAndrewofDoom Assigned ToValathil  
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Target Version3.6.14 
Summary0002673: Weapon Velocity < Target Object Max Speed Collsion Culling
DescriptionWhen the weapon being fired is slower than the ship's max velocity that the collision pair is being tested on, the collision pair is culled.
Steps To Reproduce1. Make or modify a weapon with a very slow velocity (ie something < 60 m/s)
2. Have a ship with a fairly fast speed (ie GTF Perseus or GTF Pegasus)
3. Have something fire this new weapon.
4. Sit still and watch as it passes right through the fighter. Move around a bit, even right into it and it'll just go right through.
Tagsphysics

Activities

Goober5000

2012-06-27 05:30

administrator   ~0013728

This should go in 3.6.14 once reviewed and confirmed.

Valathil

2012-06-27 05:37

developer   ~0013730

I've posted a patch that should fix the issue. Explanation: The algorithm for pruning breaks down if the weapon is slower than the ship its targeting. I've added a check for that and generate a new timestamp assuming the ship and the weapon are flying head on at max speed at each other. If the projectile is inside the radius of the target check every frame. I can't prune out the pair cause even though the weapon might have missed, the ship could still catch up with it later cause it's faster!

Valathil

2012-06-29 03:47

developer  

objcollide.cpp.patch (1,313 bytes)   
Index: code/object/objcollide.cpp
===================================================================
--- code/object/objcollide.cpp	(revision 8916)
+++ code/object/objcollide.cpp	(working copy)
@@ -779,9 +779,24 @@
 			vec3d delta_x, laser_vel;
 			float a,b,c, delta_x_dot_vl, delta_t;
 			float root1, root2, root, earliest_time;
-
+			float laser_vel_mag;
 			vm_vec_sub( &delta_x, &obj_weapon->pos, &other->pos );
 			laser_vel = obj_weapon->phys_info.vel;
+
+			laser_vel_mag = vm_vec_mag(&laser_vel);
+			if( laser_vel_mag < max_vel_other ) { //Valathil - Algorithm is ill suited for projectiles with a slower speed than the targeted ship
+				float delta_x_mag = vm_vec_mag(&delta_x);
+				if( delta_x_mag < other->radius)
+					current_pair->next_check_time = timestamp(0);
+				else {
+					float earliest_time = (delta_x_mag - other->radius)/(laser_vel_mag + max_vel_other);
+					if( earliest_time > wp->lifeleft )
+						return 1;
+					current_pair->next_check_time = timestamp( fl2i( earliest_time*1000.0f ) );
+				}
+				return 0;
+			}
+			
 			// vm_vec_copy_scale( &laser_vel, &weapon->orient.vec.fvec, max_vel_weapon );
 			delta_t = (other->radius + 10.0f) / max_vel_other;		// time to get from center to radius of other obj
 			delta_x_dot_vl = vm_vec_dotprod( &delta_x, &laser_vel );
objcollide.cpp.patch (1,313 bytes)   

Valathil

2012-06-29 03:48

developer   ~0013735

Ok new version of the patch. I've added a case where if the ship and the weapon can never interact because of the limited weapon lifetime the pair gets culled.

Goober5000

2012-06-29 05:54

administrator  

objcollide.cpp.goober.patch (1,996 bytes)   
Index: objcollide.cpp
===================================================================
--- objcollide.cpp	(revision 8915)
+++ objcollide.cpp	(working copy)
@@ -780,6 +780,12 @@
 			float a,b,c, delta_x_dot_vl, delta_t;
 			float root1, root2, root, earliest_time;
 
+			if (max_vel_weapon == max_vel_other) {
+				// this will give us NAN using the below formula, so check every frame
+				current_pair->next_check_time = timestamp(0);
+				return 0;
+			}
+
 			vm_vec_sub( &delta_x, &obj_weapon->pos, &other->pos );
 			laser_vel = obj_weapon->phys_info.vel;
 			// vm_vec_copy_scale( &laser_vel, &weapon->orient.vec.fvec, max_vel_weapon );
@@ -800,23 +806,35 @@
 				root2 = (-b - root) / (2.0f * a) * 1000.0f;	// get time in ms
 			}
 
-			// find earliest positive time
-			if ( root1 > root2 ) {
-				float temp = root1;
-				root1 = root2;
-				root2 = temp;
-			}
+			// standard algorithm
+			if (max_vel_weapon > max_vel_other) {
+				// find earliest positive time
+				if ( root1 > root2 ) {
+					float temp = root1;
+					root1 = root2;
+					root2 = temp;
+				}
 
-			if (root1 > 0) {
-				earliest_time = root1;
-			} else if (root2 > 0) {
-				// root1 < 0 and root2 > 0, so we're inside sphere and next check should be next frame
-				current_pair->next_check_time = timestamp(0);	// check next time
-				return 0;
-			} else {
-				// both times negative, so never collides
-				return 1;
+				if (root1 > 0) {
+					earliest_time = root1;
+				} else if (root2 > 0) {
+					// root1 < 0 and root2 > 0, so we're inside sphere and next check should be next frame
+					current_pair->next_check_time = timestamp(0);	// check next time
+					return 0;
+				} else {
+					// both times negative, so never collides
+					return 1;
+				}
 			}
+			// need to modify it for weapons that are slower than ships
+			else {
+				if (root2 > 0) {
+					earliest_time = root2;
+				} else {
+					current_pair->next_check_time = timestamp(0);
+					return 0;
+				}
+			}
 
 
 
objcollide.cpp.goober.patch (1,996 bytes)   

Goober5000

2012-06-29 05:54

administrator   ~0013736

I've uploaded a new patch that uses Volition's existing formula and just handles the opposite cases.

Goober5000

2012-06-30 23:31

administrator   ~0013738

Fix committed to trunk@8917.

Zacam

2012-07-02 01:45

administrator   ~0013775

Fix committed to fs2_open_3_6_14@8966.

Related Changesets

fs2open: trunk r8917

2012-06-30 19:31

Goober5000


Ported: N/A

Details Diff
fix for Mantis 0002673, following Valathil's detective work Affected Issues
0002673
mod - /trunk/fs2_open/code/object/objcollide.cpp Diff File

fs2open: fs2_open_3_6_14 r8966

2012-07-01 21:46

Zacam


Ported: N/A

Details Diff
Backport: Trunk r8917; fix for Mantis 0002673, following Valathil's detective work Affected Issues
0002673
mod - /branches/fs2_open_3_6_14/code/object/objcollide.cpp Diff File

Issue History

Date Modified Username Field Change
2012-06-27 05:03 AndrewofDoom New Issue
2012-06-27 05:05 AndrewofDoom Tag Attached: physics
2012-06-27 05:30 Goober5000 Note Added: 0013728
2012-06-27 05:30 Goober5000 Assigned To => Valathil
2012-06-27 05:30 Goober5000 Status new => code review
2012-06-27 05:30 Goober5000 Target Version => 3.6.14
2012-06-27 05:32 Valathil Status code review => assigned
2012-06-27 05:33 Valathil File Added: objcollide.cpp.patch
2012-06-27 05:37 Valathil Note Added: 0013730
2012-06-27 05:38 Valathil Status assigned => code review
2012-06-27 08:03 Valathil File Deleted: objcollide.cpp.patch
2012-06-27 08:03 Valathil File Added: objcollide.cpp.patch
2012-06-29 03:40 Valathil File Deleted: objcollide.cpp.patch
2012-06-29 03:47 Valathil File Added: objcollide.cpp.patch
2012-06-29 03:48 Valathil Note Added: 0013735
2012-06-29 05:54 Goober5000 File Added: objcollide.cpp.goober.patch
2012-06-29 05:54 Goober5000 Note Added: 0013736
2012-06-30 23:31 Goober5000 Changeset attached => fs2open trunk r8917
2012-06-30 23:31 Goober5000 Note Added: 0013738
2012-06-30 23:31 Goober5000 Status code review => resolved
2012-06-30 23:31 Goober5000 Resolution open => fixed
2012-07-02 01:45 Zacam Changeset attached => fs2open fs2_open_3_6_14 r8966
2012-07-02 01:45 Zacam Note Added: 0013775