2018-12-10 22:24 EST


View Issue Details Jump to Notes ] Related Changesets ]
IDProjectCategoryView StatusLast Update
0002673FSSCPmath-relatedpublic2012-07-01 21:45
ReporterAndrewofDoom 
Assigned ToValathil 
PrioritynormalSeveritymajorReproducibilityalways
StatusresolvedResolutionfixed 
Product Version 
Target Version3.6.14Fixed in Version 
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
Attached Files
  • patch file icon objcollide.cpp.patch (1,313 bytes) 2012-06-28 23:47 -
    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 );
    
    patch file icon objcollide.cpp.patch (1,313 bytes) 2012-06-28 23:47 +
  • patch file icon objcollide.cpp.goober.patch (1,996 bytes) 2012-06-29 01:54 -
    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;
    +				}
    +			}
     
     
     
    
    patch file icon objcollide.cpp.goober.patch (1,996 bytes) 2012-06-29 01:54 +

-Relationships
+Relationships

-Notes

~0013728

Goober5000 (administrator)

This should go in 3.6.14 once reviewed and confirmed.

~0013730

Valathil (developer)

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!

~0013735

Valathil (developer)

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.

~0013736

Goober5000 (administrator)

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

~0013738

Goober5000 (administrator)

Fix committed to trunk@8917.

~0013775

Zacam (administrator)

Fix committed to fs2_open_3_6_14@8966.
+Notes

+Related Changesets

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