Esempio n. 1
0
bool Torus::shadowHit(const Ray& ray, float& tmin) const
{
	if(!castsShadows)
		return false;

	if(!bbox.hit(ray))
		return false;

	glm::vec3 origin = ray.getOrigin();
	glm::vec3 dir = ray.getDirection();

	float coefs[5];
	float roots[4];

	//define coefficients
	float sumDSquared = glm::dot(dir,dir);
	float e = glm::dot(origin,origin) - sweptRadiusSQ - tubeRadiusSQ;
	float f = glm::dot(origin,dir);
	float fourASquared = 4.0f * sweptRadiusSQ;

	coefs[0] = e * e - fourASquared * (tubeRadiusSQ - origin.y * origin.y);
	coefs[1] = 4.0f * f * e + 2.0f * fourASquared * origin.y * dir.y;
	coefs[2] = 2.0f * sumDSquared * e + 4.0f * f * f + fourASquared * dir.y * dir.y;
	coefs[3] = 4.0f * sumDSquared * f;
	coefs[4] = sumDSquared * sumDSquared;

	int numRealRoots = solveQuartic(coefs,roots);

	bool intersected = false;
	float t = kHugeValue;

	if(numRealRoots == 0)
		return false;

	for(int i=0;i<numRealRoots;i++)
		if(roots[i] > KEpsilon)
		{
			intersected = true;
			if(roots[i] < t)
				t = roots[i];
		}

	if(!intersected)
		return false;

	tmin = t;

	return true;
}
Esempio n. 2
0
float TorusObject::hit_test(const Ray &ray, Vector &normal, const Point *max_pos, bool *inside)
{
	Ray inv_ray;
	inv_ray.origin = mul_point(inv_trans, ray.origin);
	inv_ray.direction = mul_vec(inv_trans, ray.direction);
	inv_ray.direction.normalize();

	double x1 = inv_ray.origin.x; double y1 = inv_ray.origin.y; double z1 = inv_ray.origin.z;
	double d1 = inv_ray.direction.x; double d2 = inv_ray.direction.y; double d3 = inv_ray.direction.z;

	double coeffs[5];	// coefficient array
	double roots[4];	// solution array

	//define the coefficients
	double sum_d_sqrd = d1*d1 + d2*d2 + d3*d3;
	double e = x1*x1 + y1*y1 + z1*z1 - radius*radius - thickness*thickness;
	double f = x1*d1 + y1*d2 + z1*d3;
	double four_a_sqrd = 4.0 * radius*radius;

	coeffs[0] = e*e - four_a_sqrd * (thickness*thickness-y1*y1);	// constante term
	coeffs[1] = 4.0 * f * e + 2.0 * four_a_sqrd * y1 *d2;
	coeffs[2] = 2.0 * sum_d_sqrd * e + 4.0 * f * f + four_a_sqrd * d2 * d2;
	coeffs[3] = 4.0 * sum_d_sqrd * f;
	coeffs[4] = sum_d_sqrd * sum_d_sqrd;	// coefficient of t^4

	//fin the roots
	int num_real_roots = solveQuartic(coeffs, roots);

	bool intersected = false;
	double t = FLT_MAX;

	if ( num_real_roots == 0)	// ray misses the torus
		return -1.0;

	//find the smallest root greater than FLT_EPSILON, if any
	for( int j = 0; j < num_real_roots; j++)
	{
		if(roots[j] > FLT_EPSILON)
		{
			intersected = true;
			if(roots[j] < t)
				t = roots[j];
		}
	}

	double max_t;
    if(max_pos)
        max_t = (max_pos->x - ray.origin.x) / ray.direction.x;
    else
        max_t = FLT_MAX;

	if( t > max_t || !intersected)
		return -1.0;


	Point hit = inv_ray.origin + t*inv_ray.direction;
	normal = compute_normal(hit);
	normal = mul_vec(inv_trans, normal);
	normal.normalize();
	return t;
}