Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:48:54

0001 #pragma once
0002 
0003 /**
0004 intersect_leaf_newcone
0005 ------------------------
0006 
0007 Old cone incorrectly assumed that rays would always intersect the infinite cone.
0008 
0009 
0010 **fminf(float4) picking t_cand implications**
0011 
0012 1. cannot allow t_min disqualified t into roots
0013 
0014    * BUT that check can be combined with z-range or r-range qualifications
0015 
0016 2. must use RT_DEFAULT_MAX to represent disqualified, not t_min as is often used
0017 
0018 
0019 **normal**
0020 
0021 x^2 + y^2  - (z - z0)^2 tanth^2 = 0 
0022 x^2 + y^2  - (z^2 -2z0 z - z0^2) tanth^2 = 0 
0023 
0024 Gradient:    [2x, 2y, (-2z + 2z0) tanth^2 ] 
0025 Gradient:    2*[x, y, (z0-z) tanth^2 ] 
0026 
0027 huh : is there a simpler way to get normal ? just from cone param ?
0028 
0029 
0030 **References**
0031 
0032 * https://www.geometrictools.com/Documentation/IntersectionLineCone.pdf
0033 
0034 **/
0035 
0036 
0037 LEAF_FUNC
0038 float z_apex_cone( const quad& q0 )
0039 {
0040     float r1 = q0.f.x ; 
0041     float z1 = q0.f.y ; 
0042     float r2 = q0.f.z ; 
0043     float z2 = q0.f.w ;   // z2 > z1
0044     float z0 = (z2*r1-z1*r2)/(r1-r2) ;  // apex
0045     return z0 ; 
0046 }
0047 
0048 
0049 LEAF_FUNC
0050 void intersect_leaf_newcone( bool& valid_isect, float4& isect, const quad& q0, const float t_min , const float3& ray_origin, const float3& ray_direction )
0051 {
0052     const float& r1 = q0.f.x ; 
0053     const float& z1 = q0.f.y ; 
0054     const float& r2 = q0.f.z ; 
0055     const float& z2 = q0.f.w ;   // z2 > z1
0056 
0057     const float r1r1 = r1*r1 ; 
0058     const float r2r2 = r2*r2 ; 
0059     const float tth = (r2-r1)/(z2-z1) ;
0060     const float tth2 = tth*tth ; 
0061     const float z0 = (z2*r1-z1*r2)/(r1-r2) ;  // apex
0062 
0063     const float3& o = ray_origin ;
0064     const float3& d = ray_direction ;
0065     const float idz = 1.f/d.z ;  
0066 
0067 #ifdef DEBUG_CONE
0068     printf("//intersect_leaf_newcone r1 %10.4f z1 %10.4f r2 %10.4f z2 %10.4f : z0 %10.4f \n", r1, z1, r2, z2, z0 );  
0069 #endif
0070  
0071     // intersects with cap planes
0072     float t_cap1 = d.z == 0.f ? RT_DEFAULT_MAX : (z1 - o.z)*idz ;   // d.z zero means no z-plane intersects
0073     float t_cap2 = d.z == 0.f ? RT_DEFAULT_MAX : (z2 - o.z)*idz ;  // HMM: could just let the infinities arise ?
0074     // radii squared at cap intersects  
0075     const float rr_cap1 = (o.x + t_cap1*d.x)*(o.x + t_cap1*d.x) + (o.y + t_cap1*d.y)*(o.y + t_cap1*d.y) ;  
0076     const float rr_cap2 = (o.x + t_cap2*d.x)*(o.x + t_cap2*d.x) + (o.y + t_cap2*d.y)*(o.y + t_cap2*d.y) ;  
0077 
0078     t_cap1 = rr_cap1 < r1r1 && t_cap1 > t_min ? t_cap1 : RT_DEFAULT_MAX ;  // disqualify out-of-radius
0079     t_cap2 = rr_cap2 < r2r2 && t_cap2 > t_min ? t_cap2 : RT_DEFAULT_MAX ; 
0080  
0081     // collecting terms to form coefficients of the quadratic : c2 t^2 + 2 c1 t + c0 = 0 
0082     const float c2 = d.x*d.x + d.y*d.y - d.z*d.z*tth2 ;
0083     const float c1 = o.x*d.x + o.y*d.y - (o.z-z0)*d.z*tth2 ; 
0084     const float c0 = o.x*o.x + o.y*o.y - (o.z-z0)*(o.z-z0)*tth2 ;
0085 
0086     float t_near, t_far, disc, sdisc ;   
0087     robust_quadratic_roots_disqualifying(RT_DEFAULT_MAX, t_near, t_far, disc, sdisc, c2, c1, c0 ) ;
0088 
0089 
0090 #ifdef DEBUG_CONE
0091     printf("//intersect_leaf_newcone c2 %10.4f c1 %10.4f c0 %10.4f disc %10.4f disc > 0.f %d : tth %10.4f \n", c2, c1, c0, disc, disc>0.f, tth  );  
0092 #endif
0093 
0094     const float z_near = o.z+t_near*d.z ; 
0095     const float z_far  = o.z+t_far*d.z ; 
0096 
0097     t_near = z_near > z1 && z_near < z2  && t_near > t_min ? t_near : RT_DEFAULT_MAX ; // disqualify out-of-z
0098     t_far  = z_far  > z1 && z_far  < z2  && t_far  > t_min ? t_far  : RT_DEFAULT_MAX ; 
0099 
0100     const float4 roots = make_float4( t_near, t_far, t_cap1, t_cap2 );
0101     const float t_cand = fminf(roots) ; 
0102     
0103     valid_isect = t_cand > t_min && t_cand < RT_DEFAULT_MAX ;
0104     if(valid_isect)
0105     {
0106         if( t_cand == t_cap1 || t_cand == t_cap2 )
0107         {
0108             isect.x = 0.f ; 
0109             isect.y = 0.f ;
0110             isect.z = t_cand == t_cap2 ? 1.f : -1.f  ;   
0111         }
0112         else
0113         { 
0114             float3 n = normalize(make_float3( o.x+t_cand*d.x, o.y+t_cand*d.y, (z0-(o.z+t_cand*d.z))*tth2  ))  ; 
0115             isect.x = n.x ; 
0116             isect.y = n.y ;
0117             isect.z = n.z ; 
0118         }
0119         isect.w = t_cand ; 
0120     }
0121 }
0122 
0123