//-------------------------------------------------------------------------
eiBool eiSphere::intersect(eiRay *ray, eiObject *po, eiFloat & oldt,
eiPrimitive* & ret_pri, eiFloat *cust_data,
HitParam *hparam)
{
if( oldt == 0.0f || ray_box( ray->src, hparam->hitPoint )
{
//compute intersecting point
eiVector oc = add( ray->src, - center );
eiFloat oc_len = dist( oc );
if( oc_len > radius || po->material->doubleSide )
{
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;
eiFloat t;
if(a == 0.0f || dt < 0.0f)
return false;
else if(dt == 0.0f)
{
t = - b / a * 0.5f;
if(t < 0.0f)
return false;
}
else
{
a = 0.5f / a;
eiFloat t1 = (- b + sqrtf( dt )) * a;
eiFloat t2 = (- b - sqrtf( dt )) * a;
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;
}
eiVector tmpIntersection = add(ray->src, mulvf(ray->dir,t));
//affect shadow factor
if(ray->type == RAY_SHADOW)
hparam->shadow_factor *= 1.0f - po->material->opacity;
//find nearest hit point
if(oldt == 0.0f || t < oldt)
{
hparam->hitPoint = tmpIntersection;
hparam->hitObj = po;
ret_pri = this;
oldt = t;
//fill custom data
return true;
}
}
}
return false;
}
eiBool eiSphere::intersect(eiRay *ray, eiObject *po, eiFloat & oldt,
eiPrimitive* & ret_pri, eiFloat *cust_data,
HitParam *hparam)
{
if( oldt == 0.0f || ray_box( ray->src, hparam->hitPoint )
{
//compute intersecting point
eiVector oc = add( ray->src, - center );
eiFloat oc_len = dist( oc );
if( oc_len > radius || po->material->doubleSide )
{
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;
eiFloat t;
if(a == 0.0f || dt < 0.0f)
return false;
else if(dt == 0.0f)
{
t = - b / a * 0.5f;
if(t < 0.0f)
return false;
}
else
{
a = 0.5f / a;
eiFloat t1 = (- b + sqrtf( dt )) * a;
eiFloat t2 = (- b - sqrtf( dt )) * a;
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;
}
eiVector tmpIntersection = add(ray->src, mulvf(ray->dir,t));
//affect shadow factor
if(ray->type == RAY_SHADOW)
hparam->shadow_factor *= 1.0f - po->material->opacity;
//find nearest hit point
if(oldt == 0.0f || t < oldt)
{
hparam->hitPoint = tmpIntersection;
hparam->hitObj = po;
ret_pri = this;
oldt = t;
//fill custom data
return true;
}
}
}
return false;
}