poosh

Headshot Detection Function

Mar 1st, 2021 (edited)
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class ScrnZedFunc extends Object
  2. abstract;
  3.  
  4.  
  5. /**
  6.  * Tests if the tracing Ray that hit the target at HitLoc hits also the given target's sphere-shaped hitbox.
  7.  * @param HitLoc location where the tracing ray hit the target's collision cylinder
  8.  * @param Ray normalized direction of the trace line
  9.  * @param SphereLoc the center of the sphere (e.g., Head bone's location for headshot detection)
  10.  * @param SphereRadius the radius of the sphere
  11.  * @pre The function assumes that the sphere is inside the target's collision cylinder
  12.  * @return true if the ray hits the sphere
  13.  */
  14. static function bool TestHitboxSphere(vector HitLoc, vector Ray, vector SphereLoc, float SphereRadius)
  15. {
  16.     local vector HitToSphere;  // vector from HitLoc to SphereLoc
  17.     local vector P;
  18.  
  19.     SphereRadius *= SphereRadius; // square it to avoid doing sqrt()
  20.  
  21.     HitToSphere = SphereLoc - HitLoc;
  22.     if ( VSizeSquared(HitToSphere) < SphereRadius ) {
  23.         // HitLoc is already inside the sphere - no projection needed
  24.         return true;
  25.     }
  26.  
  27.     // Let's project SphereLoc to Ray to get the projection point P.
  28.     //               SphereLoc
  29.     //              /|
  30.     //            /  |
  31.     //          /    |
  32.     // HitLoc /_ _ _ |  _ _ _ _ _ _ > Ray
  33.     //              P^
  34.     //
  35.     // If VSize(P - SphereLoc) < SphereRadius, the Ray hits the sphere.
  36.     // VSize(P - SphereLoc) = sin(A) * vsize(SpereLoc - HitLoc)
  37.     // A = acos(normal(SphereLoc - HitLoc) dot Ray)
  38.     // The above solution is simle to understand. However, it is CPU-heavy since it uses 2 trigonometric function calls.
  39.     // The below algorithm does the same but avoids trigonometry
  40.  
  41.     // HitToSphere dot Ray = cos(A) * VSize(HitToSphere) = VSize(P - HitLoc)
  42.     P = HitLoc + Ray * (HitToSphere dot Ray);
  43.  
  44.     return VSizeSquared(P - SphereLoc) < SphereRadius;
  45. }
  46.  
Add Comment
Please, Sign In to add comment