Original commit: Maximilian Giller: Implements Box, but might not work

This commit is contained in:
Tobias 2022-11-15 13:49:33 +01:00
parent 48f338dd7c
commit 29f4d0fe3c

View file

@ -10,22 +10,84 @@ Box::Box(std::shared_ptr<Shader> const &shader) : Primitive(shader), size(Vector
Box::Box(Vector3d const &center, Vector3d const &size, std::shared_ptr<Shader> const &shader) Box::Box(Vector3d const &center, Vector3d const &size, std::shared_ptr<Shader> const &shader)
: Primitive(shader), center(center), size(size) {} : Primitive(shader), center(center), size(size) {}
// Helper functions /////////////////////////////////////////////////////////
float intersectionParameterDimension(Vector3d bounds, Ray &ray, int dimension)
{
return (bounds[dimension] - ray.origin[dimension]) / ray.direction[dimension];
}
Vector3d intersectionParameter(Vector3d bounds, Ray &ray)
{
return Vector3d(intersectionParameterDimension(bounds, ray, 0),
intersectionParameterDimension(bounds, ray, 1),
intersectionParameterDimension(bounds, ray, 2));
}
// Primitive functions ///////////////////////////////////////////////////////// // Primitive functions /////////////////////////////////////////////////////////
bool Box::intersect(Ray &ray) const { bool Box::intersect(Ray &ray) const
// IMPLEMENT ME! {
// IMPLEMENT ME!
// Determine whether the ray intersects the box // Determine whether the ray intersects the box
// Test whether this is the foremost primitive in front of the camera Vector3d minBounds(this->minimumBounds(0), this->minimumBounds(1), this->minimumBounds(2));
Vector3d maxBounds(this->maximumBounds(0), this->maximumBounds(1), this->maximumBounds(2));
// (Optional for now) Calculate the normal Vector3d tMin = intersectionParameter(minBounds, ray);
Vector3d tMax = intersectionParameter(maxBounds, ray);
// (Optional for now) Calculate the surface position Vector3d tInAll = Vector3d(std::min(tMin[0], tMax[0]), std::min(tMin[1], tMax[1]), std::min(tMin[2], tMax[2]));
Vector3d tOutAll = Vector3d(std::max(tMin[0], tMax[0]), std::max(tMin[1], tMax[1]), std::max(tMin[2], tMax[2]));
// Set the new length and the current primitive float tIn = std::max(std::max(tInAll[0], tInAll[1]), tInAll[2]);
float tOut = std::min(std::min(tOutAll[0], tOutAll[1]), tOutAll[2]);
return false; if (tIn > tOut || tOut < 0)
{
return false;
}
float t = tIn;
// Test whether this is the foremost primitive in front of the camera
if (t >= ray.length)
{
return false;
}
// (Optional for now) Calculate the normal
// On what side of the box did the ray hit?
Vector3d normal;
if (tInAll[0] == tIn)
{
normal = Vector3d(1, 0, 0);
}
else if (tInAll[1] == tIn)
{
normal = Vector3d(0, 1, 0);
}
else // tInAll[2] == tIn
{
normal = Vector3d(0, 0, 1);
}
// Make sure sign is correct
if (dotProduct(ray.direction, normal) > 0)
{
normal = -normal;
}
ray.normal = normalized(normal);
// (Optional for now) Calculate the surface position
// Set the new length and the current primitive
ray.length = t;
ray.primitive = this;
return false;
} }
// Bounding box //////////////////////////////////////////////////////////////// // Bounding box ////////////////////////////////////////////////////////////////