View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002673 | FSSCP | math-related | public | 2012-06-27 05:03 | 2012-07-02 01:45 |
Reporter | AndrewofDoom | Assigned To | Valathil | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Target Version | 3.6.14 | ||||
Summary | 0002673: Weapon Velocity < Target Object Max Speed Collsion Culling | ||||
Description | When 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 Reproduce | 1. 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. | ||||
Tags | physics | ||||
|
This should go in 3.6.14 once reviewed and confirmed. |
|
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! |
|
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 ); |
|
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. |
|
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; + } + } |
|
I've uploaded a new patch that uses Volition's existing formula and just handles the opposite cases. |
|
Fix committed to trunk@8917. |
|
Fix committed to fs2_open_3_6_14@8966. |
fs2open: trunk r8917 2012-06-30 19:31 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 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 |
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 |