コード例 #1
0
bool PlaneIntersector<real>::Intersect( const Plane<real>* plane, const Ray<real>& ray, Intersection<real>& oIntersection )
{
    const Vector3<real>& origin = ray.GetOrigin();
    const Vector3<real>& direction = ray.GetDirection();

    // Do not perform intersection if the direction of the ray is degenerated relative to the plane
    if ( fabs( direction.Y() ) > EPS )
    {
        // Compute the intersection point and see if it's inside the plane bounds
        real t = -origin.Y() / direction.Y();
        Vector3<real> intersectionPoint = origin + t * direction;
        bool isInsideXBounds = ( fabs( intersectionPoint.X() ) < plane->GetSizeX() * 0.5 ) ? true : false;
        bool isInsideZBounds = ( fabs( intersectionPoint.Z() ) < plane->GetSizeZ() * 0.5 ) ? true : false;

        // If the ray intersect and the intersection is in front
        if ( ( t > 0 ) && isInsideXBounds && isInsideZBounds )
        {
            oIntersection.SetPosition( intersectionPoint );
            oIntersection.SetNormal( Vector3<real>( 0, -sign<real>( direction.Y() ), 0 ) );
            oIntersection.IsInside( false );

            // Compute texture coodinates as (z=-0.5 => u=0 and x=-0.5 => v=0)
            real u = ( intersectionPoint.Z() + plane->GetSizeZ() * 0.5 ) / plane->GetSizeZ();
            real v = ( intersectionPoint.X() + plane->GetSizeX() * 0.5 ) / plane->GetSizeX();
            oIntersection.SetTextureCoordinates( Vector3<real>( u, v, 0 ) );

            return true;
        }
    }

    return false;
}
コード例 #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;
}
コード例 #3
0
bool CylinderIntersector<real>::Intersect( const Cylinder<real>* cylinder, const Ray<real>& ray, Intersection<real>& oIntersection )
{
	real nearestDistance = std::numeric_limits<real>::max();
	real distance = 0;
	bool hasIntersection = false;

	////////////////////////////////////////////
	//////////////////IFT 3355//////////////////
	////////////////////////////////////////////
	//Ici, vous calculerez l'intersection entre
	//le rayon "ray" et le cylindre "cylinder"
	//Pensez à initialiser les quatre attributs
	//de oIntersection (retourné par référence)
	//correctement si une intersection est trouvée.
	////////////////////////////////////////////
	//////////////////IFT 3355//////////////////
	////////////////////////////////////////////

    real halfHeight = cylinder->GetHeight() / 2;
    real radius = cylinder->GetRadius();

    // Intersection with extremeties.
    Vector3<real> extremeties[2] = {
        Vector3<real>(0, halfHeight, 0),
        Vector3<real>(0, -halfHeight, 0),
    };

    for (int k = 0; k < 2; ++k) {
        Vector3<real> plane = extremeties[k];
        real denom = ray.GetDirection() * plane;
	    bool intersectsPlane = fabs(denom) > EPS;

	    // Ray intersects with the extremety.
	    if (intersectsPlane) {
            // Intersection position on the infinite plane.
	        real t = ((plane - ray.GetOrigin()) * plane) / denom;
	        Vector3<real> intersectionPos = ray.GetOrigin() + t * ray.GetDirection();
	        // Ray intersects in the window.
            if ((plane - intersectionPos).Length() <= radius &&
                ray.GetDirection() * plane < 0 &&
                t > EPS && t <= nearestDistance) {
                oIntersection.SetNormal(plane);
                oIntersection.SetPosition(intersectionPos);
                oIntersection.SetTextureCoordinates(intersectionPos);
                oIntersection.IsInside(false);
                nearestDistance = t;
                hasIntersection = true;
            }
        }
    }




    // Intersection with main body
    Vector3<real> o = Vector3<real>(ray.GetOrigin().X(), 0, ray.GetOrigin().Z());
    Vector3<real> d = Vector3<real>(ray.GetDirection().X(), 0, ray.GetDirection().Z());
    real a = d*d;
    real b = 2 * d * o;
    real c = o * o - (radius*radius);

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

    if (discr < -EPS) {
        return hasIntersection;           // No intersection.
    }
    else {
        real t1 = (-b - sqrt(discr)) / (2*a);
        real t2 = (-b + sqrt(discr)) / (2*a);
        real t = std::min<real>(t1, t2);
        Vector3<real> intersectionPos = ray.GetOrigin() + t * ray.GetDirection();
        if (t >= EPS && t < nearestDistance && fabs(intersectionPos.Y()) < halfHeight+EPS) {
            oIntersection.SetNormal(intersectionPos - Vector3<real>(0, intersectionPos.Y(), 0));
            oIntersection.SetPosition(intersectionPos);
            oIntersection.SetTextureCoordinates(intersectionPos);
            oIntersection.IsInside(false);
            nearestDistance = t;
            hasIntersection = true;
        }
    }

	return hasIntersection;
}