コード例 #1
0
void NodeIntersector<real>::TransformIntersectionToGlobalCoordinates( const CoreLib::Node<real>* node, Intersection<real>& ioIntersection )
{
	// newPosition = M * position
	// newNormal = M^{-T} * normal
	const Matrix4<real>& localToGlobal = node->GetLocalToGlobal();
	Matrix4<real> localToGlobalForNormals = node->GetGlobalToLocal();
	localToGlobalForNormals.Transpose();

	ioIntersection.SetPosition( localToGlobal * ioIntersection.GetPosition() );
	ioIntersection.SetNormal( localToGlobalForNormals ^ ioIntersection.GetNormal() );
}
コード例 #2
0
bool SphereIntersector<real>::Intersect( const Sphere<real>* sphere, const Ray<real>& ray, Intersection<real>& oIntersection )
{
	// Compute the equation corresponding to x²+y²+z²=0 with p+t*d to obtain a quadratic equation
	real a = ray.GetDirection().SquaredLength();
	real b = 2.0 * ray.GetDirection() * ray.GetOrigin();
	real c = ray.GetOrigin().SquaredLength() - sphere->GetRadius() * sphere->GetRadius();

	real discriminant = b*b - 4*a*c;

	// Discriminant >= 0 => the must be at least one intersection
	if ( discriminant >= 0 )
	{
		// Compute the two potential intersections and only keep the nearest
		real sqrtDisc = sqrt( discriminant );
		real t = 0;
		real t1 = ( -b - sqrtDisc ) / ( 2.0 * a );
		real t2 = ( -b + sqrtDisc ) / ( 2.0 * a );

		if ( t1 >= 0 )
		{
			t = t1;
			oIntersection.IsInside( false );
		}
		else if ( t2 >= 0 )
		{
			t = t2;
			oIntersection.IsInside( true );
		}
		else
			return false;

		oIntersection.SetPosition( ray.GetOrigin() + t * ray.GetDirection() );
		oIntersection.SetNormal( oIntersection.GetPosition().Normalized() );
		oIntersection.SetTextureCoordinates( oIntersection.GetPosition().Normalized() );

		// The normal must be flipped to coincide with the hit direction
		if ( oIntersection.IsInside() )
			oIntersection.SetNormal( -oIntersection.GetNormal() );

		return true;
	}

	return false;
}