//
-------------------------------------------------------------------------
eiBool eiSphere::intersect(eiRay
*
ray, eiObject
*
po, eiFloat
&
oldt,
eiPrimitive
* &
ret_pri, eiFloat
*
cust_data,
HitParam
*
hparam)
![ExpandedBlockStart.gif](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
if( oldt == 0.0f || ray_box( ray->src, hparam->hitPoint )
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
//compute intersecting point![dot.gif](/Images/dot.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
eiVector oc = add( ray->src, - center );
eiFloat oc_len = dist( oc );
if( oc_len > radius || po->material->doubleSide )
![ExpandedSubBlockStart.gif](/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;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
eiFloat t;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
if(a == 0.0f || dt < 0.0f)
return false;
else if(dt == 0.0f)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
t = - b / a * 0.5f;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
if(t < 0.0f)
return false;
}
else
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
a = 0.5f / a;
eiFloat t1 = (- b + sqrtf( dt )) * a;
eiFloat t2 = (- b - sqrtf( dt )) * a;
![InBlock.gif](/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;
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
eiVector tmpIntersection = add(ray->src, mulvf(ray->dir,t));
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
//affect shadow factor![dot.gif](/Images/dot.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
if(ray->type == RAY_SHADOW)
hparam->shadow_factor *= 1.0f - po->material->opacity;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
//find nearest hit point![dot.gif](/Images/dot.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
if(oldt == 0.0f || t < oldt)
![ExpandedSubBlockStart.gif](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
hparam->hitPoint = tmpIntersection;
hparam->hitObj = po;
ret_pri = this;
oldt = t;
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
//fill custom data![dot.gif](/Images/dot.gif)
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
return true;
}
}
}
![InBlock.gif](/Images/OutliningIndicators/InBlock.gif)
return false;
}
转载于:https://www.cnblogs.com/len3d/archive/2005/07/28/202305.html