diff --git a/primitive/infiniteplane.cpp b/primitive/infiniteplane.cpp index 34e4190..d48bc75 100644 --- a/primitive/infiniteplane.cpp +++ b/primitive/infiniteplane.cpp @@ -3,43 +3,72 @@ // Constructor ///////////////////////////////////////////////////////////////// -InfinitePlane::InfinitePlane(std::shared_ptr const &shader) : Primitive(shader), normal(0, 1, 0) {} +InfinitePlane::InfinitePlane(std::shared_ptr const &shader) : Primitive(shader), normal(0, 1, 0) +{} InfinitePlane::InfinitePlane(Vector3d const &origin, Vector3d const &normal, std::shared_ptr const &shader) - : Primitive(shader), origin(origin), normal(normal) {} + : Primitive(shader), origin(origin), normal(normal) +{} // Primitive functions ///////////////////////////////////////////////////////// -bool InfinitePlane::intersect(Ray &ray) const { - // IMPLEMENT ME! +bool InfinitePlane::intersect(Ray &ray) const +{ + float directionDotNormal = dotProduct(ray.direction, this->normal); - // Make sure the ray is not coming from the other side (backface culling). - // Note: We only use backface culling for InfinitePlanes, because we have - // some special features planned that rely on backfaces for other primitives. + // Make sure the ray is not coming from the other side (backface culling). + // Note: We only use backface culling for InfinitePlanes, because we have + // some special features planned that rely on backfaces for other primitives. - // Determine whether the ray intersects the plane + /** + * If the dot product is 0, the ray is orthogonal to the normal => parallel to the plane => no intersection. + * If the dot product is negative, the ray is coming from the wrong side. + */ + if (directionDotNormal <= 0) + { + return false; + } - // Test whether this is the foremost primitive in front of the camera + // Basic formular to calculate intersection between ray and plane + float t = (length(this->origin) - dotProduct(ray.origin,this->normal)) / directionDotNormal; - // (Optional for now) Set the normal + // If t negative, collision happens behind the camera + if (t < 0) + { + return false; + } - // Set the new length and the current primitive + // Test whether this is the foremost primitive in front of the camera + if (t >= ray.length) + { + // Is bigger, so further away + return false; + } - return false; + // (Optional for now) Set the normal + ray.normal = this->normal; + + // Set the new length and the current primitive + ray.primitive = this; + ray.length = t; + + return true; } // Bounding box //////////////////////////////////////////////////////////////// -float InfinitePlane::minimumBounds(int dimension) const { - if (this->normal[dimension] == 1.0f) // plane is orthogonal to the axis - return this->origin[dimension] - EPSILON; - else - return -INFINITY; +float InfinitePlane::minimumBounds(int dimension) const +{ + if (this->normal[dimension] == 1.0f) // plane is orthogonal to the axis + return this->origin[dimension] - EPSILON; + else + return -INFINITY; } -float InfinitePlane::maximumBounds(int dimension) const { - if (this->normal[dimension] == 1.0f) // plane is orthogonal to the axis - return this->origin[dimension] + EPSILON; - else - return +INFINITY; +float InfinitePlane::maximumBounds(int dimension) const +{ + if (this->normal[dimension] == 1.0f) // plane is orthogonal to the axis + return this->origin[dimension] + EPSILON; + else + return +INFINITY; }