cloudy-raytracer/primitive/infiniteplane.cpp

60 lines
2 KiB
C++
Raw Normal View History

2022-10-28 09:31:13 +02:00
#include "primitive/infiniteplane.h"
#include <cmath>
// Constructor /////////////////////////////////////////////////////////////////
InfinitePlane::InfinitePlane(std::shared_ptr<Shader> const &shader) : Primitive(shader), normal(0, 1, 0) {}
InfinitePlane::InfinitePlane(Vector3d const &origin, Vector3d const &normal, std::shared_ptr<Shader> const &shader)
: Primitive(shader), origin(origin), normal(normal) {}
// Primitive functions /////////////////////////////////////////////////////////
bool InfinitePlane::intersect(Ray &ray) const {
2022-11-11 14:27:43 +01:00
float const cosine = dotProduct(ray.direction, this->normal);
2022-10-28 09:31:13 +02:00
// 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.
2022-11-11 14:27:43 +01:00
if (cosine > 0)
return false;
2022-10-28 09:31:13 +02:00
2022-11-11 14:27:43 +01:00
// Determine the distance at which the ray intersects the plane
float const t = dotProduct(this->origin - ray.origin, this->normal) / cosine;
2022-10-28 09:31:13 +02:00
// Test whether this is the foremost primitive in front of the camera
2022-11-11 14:27:43 +01:00
if (t < EPSILON || ray.length < t)
return false;
2022-10-28 09:31:13 +02:00
2022-11-11 14:27:43 +01:00
// Set the normal
2022-11-17 20:34:37 +01:00
if (std::acos(dotProduct(ray.direction, this->normal)) > 0) {
2022-11-17 19:22:30 +01:00
ray.normal = normalized(this->normal);
2022-11-17 14:40:47 +01:00
} else {
2022-11-17 19:22:30 +01:00
ray.normal = normalized((-1.0f * this->normal));
2022-11-17 14:40:47 +01:00
}
2022-10-28 09:31:13 +02:00
// Set the new length and the current primitive
2022-11-11 14:27:43 +01:00
ray.length = t;
ray.primitive = this;
2022-10-28 09:31:13 +02:00
2022-11-11 14:27:43 +01:00
// True, because the primitive was hit
return true;
2022-10-28 09:31:13 +02:00
}
// 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::maximumBounds(int dimension) const {
if (this->normal[dimension] == 1.0f) // plane is orthogonal to the axis
return this->origin[dimension] + EPSILON;
else
return +INFINITY;
}