File indexing completed on 2026-04-09 07:48:54
0001 #pragma once
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 LEAF_FUNC
0025 void intersect_leaf_hyperboloid(bool& valid_isect, float4& isect, const quad& q0, const float t_min, const float3& ray_origin, const float3& ray_direction )
0026 {
0027 const float zero(0.f);
0028 const float one(1.f);
0029
0030 const float r0 = q0.f.x ;
0031 const float zf = q0.f.y ;
0032 const float z1 = q0.f.z ;
0033 const float z2 = q0.f.w ;
0034
0035 const float rr0 = r0*r0 ;
0036 const float z1s = z1/zf ;
0037 const float z2s = z2/zf ;
0038 const float rr1 = rr0 * ( z1s*z1s + one ) ;
0039 const float rr2 = rr0 * ( z2s*z2s + one ) ;
0040
0041 const float A = -rr0/(zf*zf) ;
0042 const float B = -rr0 ;
0043
0044 const float& sx = ray_direction.x ;
0045 const float& sy = ray_direction.y ;
0046 const float& sz = ray_direction.z ;
0047
0048 const float& ox = ray_origin.x ;
0049 const float& oy = ray_origin.y ;
0050 const float& oz = ray_origin.z ;
0051
0052 const float d = sx*sx + sy*sy + A*sz*sz ;
0053 const float b = ox*sx + oy*sy + A*oz*sz ;
0054 const float c = ox*ox + oy*oy + A*oz*oz + B ;
0055
0056 float t1hyp, t2hyp, disc, sdisc ;
0057 robust_quadratic_roots(t1hyp, t2hyp, disc, sdisc, d, b, c);
0058
0059 const float h1z = oz + t1hyp*sz ;
0060 const float h2z = oz + t2hyp*sz ;
0061
0062
0063 float osz = one/sz ;
0064 float t2cap = (z2 - oz)*osz ;
0065 float t1cap = (z1 - oz)*osz ;
0066
0067 const float3 c1 = ray_origin + t1cap*ray_direction ;
0068 const float3 c2 = ray_origin + t2cap*ray_direction ;
0069
0070 float crr1 = c1.x*c1.x + c1.y*c1.y ;
0071 float crr2 = c2.x*c2.x + c2.y*c2.y ;
0072
0073
0074
0075
0076 const float4 t_cand_ = make_float4(
0077 t1hyp > t_min && disc > zero && h1z > z1 && h1z < z2 ? t1hyp : RT_DEFAULT_MAX ,
0078 t2hyp > t_min && disc > zero && h2z > z1 && h2z < z2 ? t2hyp : RT_DEFAULT_MAX ,
0079 t2cap > t_min && crr2 < rr2 ? t2cap : RT_DEFAULT_MAX ,
0080 t1cap > t_min && crr1 < rr1 ? t1cap : RT_DEFAULT_MAX
0081 ) ;
0082
0083 float t_cand = fminf( t_cand_ );
0084
0085 valid_isect = t_cand > t_min && t_cand < RT_DEFAULT_MAX ;
0086 if(valid_isect)
0087 {
0088 isect.w = t_cand ;
0089 if( t_cand == t1hyp || t_cand == t2hyp )
0090 {
0091 const float3 p = ray_origin + t_cand*ray_direction ;
0092 float3 n = normalize(make_float3( p.x, p.y, A*p.z )) ;
0093 isect.x = n.x ;
0094 isect.y = n.y ;
0095 isect.z = n.z ;
0096 }
0097 else
0098 {
0099 isect.x = zero ;
0100 isect.y = zero ;
0101 isect.z = t_cand == t1cap ? -one : one ;
0102 }
0103 }
0104 }
0105
0106