//-------------------------------------------------------------------------
eiBool eiSphere::intersect(eiRay *ray, eiObject *po, eiFloat & oldt,
eiPrimitive* & ret_pri, eiFloat *cust_data,
HitParam *hparam)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) {
if( oldt == 0.0f || ray_box( ray->src, hparam->hitPoint )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
//compute intersecting point![](/Images/dot.gif)
![](/Images/OutliningIndicators/InBlock.gif)
eiVector oc = add( ray->src, - center );
eiFloat oc_len = dist( oc );
if( oc_len > radius || po->material->doubleSide )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
eiFloat a = dot( ray->dir, ray->dir );
eiFloat b = 2.0f * dot( oc, ray->dir);
eiFloat c = dot( oc, oc ) - RR;
eiFloat dt = b * b - 4.0f * a * c;
![](/Images/OutliningIndicators/InBlock.gif)
eiFloat t;
![](/Images/OutliningIndicators/InBlock.gif)
if(a == 0.0f || dt < 0.0f)
return false;
else if(dt == 0.0f)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
t = - b / a * 0.5f;
![](/Images/OutliningIndicators/InBlock.gif)
if(t < 0.0f)
return false;
}
else
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
a = 0.5f / a;
eiFloat t1 = (- b + sqrtf( dt )) * a;
eiFloat t2 = (- b - sqrtf( dt )) * a;
![](/Images/OutliningIndicators/InBlock.gif)
if(t1 > 0.0f && t2 < 0.0f)
t = t1;
else if(t1 < 0.0f && t2 > 0.0f)
t = t2;
else if(t1 > 0.0f && t2 > 0.0f)
t = (t1 < t2) ? t1 : t2;
else
return false;
}
![](/Images/OutliningIndicators/InBlock.gif)
eiVector tmpIntersection = add(ray->src, mulvf(ray->dir,t));
![](/Images/OutliningIndicators/InBlock.gif)
//affect shadow factor![](/Images/dot.gif)
![](/Images/OutliningIndicators/InBlock.gif)
if(ray->type == RAY_SHADOW)
hparam->shadow_factor *= 1.0f - po->material->opacity;
![](/Images/OutliningIndicators/InBlock.gif)
//find nearest hit point![](/Images/dot.gif)
![](/Images/OutliningIndicators/InBlock.gif)
if(oldt == 0.0f || t < oldt)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
hparam->hitPoint = tmpIntersection;
hparam->hitObj = po;
ret_pri = this;
oldt = t;
![](/Images/OutliningIndicators/InBlock.gif)
//fill custom data![](/Images/dot.gif)
![](/Images/OutliningIndicators/InBlock.gif)
return true;
}
}
}
![](/Images/OutliningIndicators/InBlock.gif)
return false;
}
|