2018-12-10 22:24 EST
 All Projects | FSSCP: wxFRED

View Issue Details
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
• 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);
+					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) 2012-06-28 23:47
• 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;
+				}
+			}

```
objcollide.cpp.goober.patch (1,996 bytes) 2012-06-29 01:54

 Relationships
 Relationships

 Notes ~0013728 Goober5000 (administrator) 2012-06-27 01:30 This should go in 3.6.14 once reviewed and confirmed. ~0013730 Valathil (developer) 2012-06-27 01:37 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) 2012-06-28 23:48 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) 2012-06-29 01:54 I've uploaded a new patch that uses Volition's existing formula and just handles the opposite cases. ~0013738 Goober5000 (administrator) 2012-06-30 19:31 Fix committed to trunk@8917. ~0013775 Zacam (administrator) 2012-07-01 21:45 Fix committed to fs2_open_3_6_14@8966.
 Notes

 Related Changesets