Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions src/src/objects/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,21 +54,24 @@ bool Mesh::hit(const Ray& ray, double t_min, double t_max, HitRecord& rec) const
Point3 world_p;
double world_t = INFINITY;

if (rec.t < t_max) {
if (rec.t < t_max) { // If a hit was found, transform the hit point back to world space
world_p = transform * transformed_ray.at(rec.t);
world_t = (world_p - ray.origin()).dot(ray.direction().normalize());
}

if (world_t < t_max) {
rec.p = world_p;
rec.t = world_t;
Vector3 world_normal = (inverseTransposeTransform * rec.normal).normalize();
rec.set_face_normal(ray, world_normal);
rec.material = material;
return true;
if (world_t < t_min || world_t > t_max) {
return false;
}

return false;
rec.t = world_t;
rec.p = world_p;

Vector3 world_normal = (inverseTransposeTransform * rec.normal).normalize();
rec.set_face_normal(ray, world_normal);

rec.material = material;

return true;
};

void Mesh::setMaterial(std::shared_ptr<Material> new_material) {
Expand Down
9 changes: 5 additions & 4 deletions src/src/objects/plane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ bool Plane::hit(const Ray& ray, double t_min, double t_max, HitRecord& rec) cons
return false;
}

double t = (point_on_plane - transformed_ray.origin()).dot(normal) / denominator;
Vector3 world_normal = (this->inverseTransposeTransform * this->normal).normalize();
Vector3 world_point_on_plane = transform * point_on_plane;
double t = (world_point_on_plane - ray.origin()).dot(world_normal) / denominator;

if (t < t_min || t > t_max) {
return false;
}

rec.t = t;
rec.p = transform * transformed_ray.at(t); // Ponto de volta para o espaço global
Vector3 outward_normal_world = (inverseTransposeTransform * this->normal).normalize();
rec.set_face_normal(ray, outward_normal_world); // Usa o raio original
rec.p = ray.at(t); // Ponto de volta para o espaço global
rec.set_face_normal(ray, world_normal); // Usa o raio original
rec.material = material;

return true;
Expand Down
25 changes: 17 additions & 8 deletions src/src/objects/sphere.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,30 @@ bool Sphere::hit(const Ray& ray, double t_min, double t_max, HitRecord& rec) con
}
auto sqrtd = sqrt(discriminant);


auto root = (-halfb - sqrtd) / a;
if (root < t_min || t_max < root) {

Point3 local_hit_point = transformed_ray.at(root);
Point3 world_hit_point = transform * local_hit_point;
double t = (world_hit_point - ray.origin()).dot(ray.direction());

if (t < t_min || t > t_max) {
root = (-halfb + sqrtd) / a;
if (root < t_min || t_max < root) {
local_hit_point = transformed_ray.at(root);
world_hit_point = transform * local_hit_point;
t = (world_hit_point - ray.origin()).dot(ray.direction());
if (t < t_min || t > t_max) {
return false;
}
}

rec.t = root;
Point3 local_hit_point = transformed_ray.at(rec.t);
Vector3 outward_normal_local = (local_hit_point - center) / radius;
rec.t = t;
rec.p = world_hit_point;

Vector3 normal_local = (local_hit_point - center) / radius;
Vector3 normal_world = (inverseTransposeTransform * normal_local).normalize();
rec.set_face_normal(ray, normal_world);

rec.p = transform * local_hit_point;
Vector3 outward_normal_world = (inverseTransposeTransform * outward_normal_local).normalize();
rec.set_face_normal(ray, outward_normal_world);
rec.material = material;

return true;
Expand Down
34 changes: 18 additions & 16 deletions src/src/objects/triangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,43 +27,46 @@ bool Triangle::hit(const Ray& ray, double t_min, double t_max, HitRecord& rec) c
const Vector3 edge1 = this->getPoint2() - this->getPoint1();
const Vector3 edge2 = this->getPoint3() - this->getPoint1();

const Vector3 h = transformed_ray.direction() ^ edge2;
const double a = edge1 * h;
const Vector3 h = transformed_ray.direction().cross(edge2);
const double a = edge1.dot(h);

if (a > -epsilon && a < epsilon) {
return false;
}

const double f = 1.0 / a;
const Vector3 s = transformed_ray.origin() - this->getPoint1();
const double u = f * (s * h);
const double u = f * s.dot(h);

if (u < 0.0 || u > 1.0) {
return false;
}

const Vector3 q = s ^ edge1;
const Vector3 q = s.cross(edge1);
const double v = f * (transformed_ray.direction() * q);

if (v < 0.0 || u + v > 1.0) {
return false;
}

const double t = f * (edge2 * q);
const double t_local = f * edge2.dot(q);
Point3 world_hit_point = transform * transformed_ray.at(t_local);
const double t_global = (world_hit_point - ray.origin()).dot(ray.direction());

if (t > t_min && t < t_max) {
rec.t = t;
rec.p = transform * transformed_ray.at(t);
if (t_global < t_min || t_global > t_max) {
return false;
}

Vector3 local_normal = edge1 ^ edge2;
Vector3 world_normal = (inverseTransposeTransform * local_normal).normalize();
rec.set_face_normal(ray, world_normal);
rec.t = t_global;
rec.p = world_hit_point;

rec.material = material;
return true;
}
Vector3 local_normal = edge1.cross(edge2);
Vector3 world_normal = (inverseTransposeTransform * local_normal).normalize();
rec.set_face_normal(ray, world_normal);

return false;
rec.material = material;

return true;
}

MeshTriangle::MeshTriangle(std::shared_ptr<Point3> p1, std::shared_ptr<Point3> p2,
Expand Down Expand Up @@ -128,7 +131,6 @@ bool MeshTriangle::hit(const Ray& ray, double t_min, double t_max, HitRecord& re
if (t > t_min && t < t_max) {

const double w = 1.0 - u - v;
;
rec.t = t;
rec.normal = ((*normal1 * w) + (*normal2 * u) + (*normal3 * v)).normalize();
return true;
Expand Down
2 changes: 1 addition & 1 deletion tests/src/TransformationsTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ TEST(TransformationsTest, SphereHitWithNonUniformScale) {

// Act & Assert
EXPECT_TRUE(s->hit(ray_that_hits, 0, 100, rec));
EXPECT_NEAR(rec.t, 1.5, 1e-6);
EXPECT_NEAR(rec.t, 3, 1e-6);

// As asserções mais importantes (ponto e normal em espaço global) continuam as mesmas.
AssertPointAlmostEqual(rec.p, Point3(0, 2, 0));
Expand Down