File indexing completed on 2026-04-09 07:48:55
0001 #pragma once
0002
0003 LEAF_FUNC
0004 float distance_leaf_zsphere(const float3& pos, const quad& q0, const quad& q1 )
0005 {
0006 float3 center = make_float3(q0.f);
0007 float radius = q0.f.w;
0008 const float2 zdelta = make_float2(q1.f);
0009 const float z2 = center.z + zdelta.y ;
0010 const float z1 = center.z + zdelta.x ;
0011
0012 float3 p = pos - center;
0013 float sd_sphere = length(p) - radius ;
0014 float sd_capslab = fmaxf( pos.z - z2 , z1 - pos.z );
0015
0016 float sd = fmaxf( sd_capslab, sd_sphere );
0017 return sd ;
0018 }
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 LEAF_FUNC
0045 void intersect_leaf_zsphere(bool& valid_isect, float4& isect, const quad& q0, const quad& q1, const float& t_min, const float3& ray_origin, const float3& ray_direction )
0046 {
0047 const float3 center = make_float3(q0.f);
0048 float3 O = ray_origin - center;
0049 float3 D = ray_direction;
0050 const float radius = q0.f.w;
0051
0052 float b = dot(O, D);
0053 float c = dot(O, O)-radius*radius;
0054
0055 #ifdef DEBUG_RECORD
0056 printf("//[intersect_leaf_zsphere radius %10.4f b %10.4f c %10.4f \n", radius, b, c);
0057 #endif
0058
0059 if( c > 0.f && b > 0.f )
0060 {
0061 valid_isect = false ;
0062 return ;
0063 }
0064
0065
0066
0067 const float2 zdelta = make_float2(q1.f);
0068 const float zmax = center.z + zdelta.y ;
0069 const float zmin = center.z + zdelta.x ;
0070
0071 #ifdef DEBUG_RECORD
0072 bool with_upper_cut = zmax < radius ;
0073 bool with_lower_cut = zmin > -radius ;
0074 printf("// intersect_leaf_zsphere radius %10.4f zmax %10.4f zmin %10.4f with_upper_cut %d with_lower_cut %d \n", radius, zmax, zmin, with_upper_cut, with_lower_cut );
0075 #endif
0076
0077
0078 float d = dot(D, D);
0079
0080 float t1sph, t2sph, disc, sdisc ;
0081 robust_quadratic_roots(t1sph, t2sph, disc, sdisc, d, b, c);
0082
0083 float z1sph = ray_origin.z + t1sph*ray_direction.z ;
0084 float z2sph = ray_origin.z + t2sph*ray_direction.z ;
0085
0086 #ifdef DEBUG_RECORD
0087 printf("// intersect_leaf_zsphere t1sph %10.4f t2sph %10.4f sdisc %10.4f \n", t1sph, t2sph, sdisc );
0088 printf("// intersect_leaf_zsphere z1sph %10.4f z2sph %10.4f zmax %10.4f zmin %10.4f sdisc %10.4f \n", z1sph, z2sph, zmax, zmin, sdisc );
0089 #endif
0090
0091 float idz = 1.f/ray_direction.z ;
0092 float t_QCAP = (zmax - ray_origin.z)*idz ;
0093 float t_PCAP = (zmin - ray_origin.z)*idz ;
0094
0095
0096 float t1cap = fminf( t_QCAP, t_PCAP ) ;
0097 float t2cap = fmaxf( t_QCAP, t_PCAP ) ;
0098
0099 #ifdef DEBUG_RECORD
0100 bool t1cap_disqualify = t1cap < t1sph || t1cap > t2sph ;
0101 bool t2cap_disqualify = t2cap < t1sph || t2cap > t2sph ;
0102 printf("//intersect_leaf_zsphere t1sph %7.3f t2sph %7.3f t_QCAP %7.3f t_PCAP %7.3f t1cap %7.3f t2cap %7.3f \n", t1sph, t2sph, t_QCAP, t_PCAP, t1cap, t2cap );
0103 printf("//intersect_leaf_zsphere t1cap_disqualify %d t2cap_disqualify %d \n", t1cap_disqualify, t2cap_disqualify );
0104 #endif
0105
0106
0107 if(t1cap < t1sph || t1cap > t2sph) t1cap = t_min ;
0108 if(t2cap < t1sph || t2cap > t2sph) t2cap = t_min ;
0109
0110
0111
0112 float t_cand = t_min ;
0113 if(sdisc > 0.f)
0114 {
0115
0116 #ifdef DEBUG_RECORD
0117
0118 #endif
0119
0120 if( t1sph > t_min && z1sph > zmin && z1sph <= zmax ) t_cand = t1sph ;
0121 else if( t1cap > t_min ) t_cand = t1cap ;
0122 else if( t2cap > t_min ) t_cand = t2cap ;
0123 else if( t2sph > t_min && z2sph > zmin && z2sph <= zmax) t_cand = t2sph ;
0124 }
0125
0126 valid_isect = t_cand > t_min ;
0127 #ifdef DEBUG_RECORD
0128 printf("//intersect_leaf_zsphere valid_isect %d t_min %7.3f t1sph %7.3f t1cap %7.3f t2cap %7.3f t2sph %7.3f t_cand %7.3f \n", valid_isect, t_min, t1sph, t1cap, t2cap, t2sph, t_cand );
0129 #endif
0130
0131 if(valid_isect)
0132 {
0133 isect.w = t_cand ;
0134 if( t_cand == t1sph || t_cand == t2sph)
0135 {
0136 isect.x = (O.x + t_cand*D.x)/radius ;
0137 isect.y = (O.y + t_cand*D.y)/radius ;
0138 isect.z = (O.z + t_cand*D.z)/radius ;
0139 }
0140 else
0141 {
0142 isect.x = 0.f ;
0143 isect.y = 0.f ;
0144 isect.z = t_cand == t_PCAP ? -1.f : 1.f ;
0145 }
0146 }
0147
0148 #ifdef DEBUG_RECORD
0149 printf("//]intersect_leaf_zsphere valid_isect %d \n", valid_isect );
0150 #endif
0151 }
0152
0153