diff --git a/includes/RT/objects/Portal.hpp b/includes/RT/objects/Portal.hpp index 2e88118..324d5c0 100644 --- a/includes/RT/objects/Portal.hpp +++ b/includes/RT/objects/Portal.hpp @@ -24,7 +24,9 @@ class Portal : public Object float x, y, z; float x1, y1, z1; float x2, y2, z2; - int linked_portal; + + bool invert_normal; + int mat_index; if (!(line >> x >> y >> z)) @@ -36,8 +38,8 @@ class Portal : public Object if (!(line >> x2 >> y2 >> z2)) throw std::runtime_error("Missing Portal's second edge"); - if (!(line >> linked_portal)) - throw std::runtime_error("Missing Portal's linked index"); + if (!(line >> invert_normal)) + throw std::runtime_error("Missing invert_normal"); if (!(line >> mat_index)) throw std::runtime_error("Missing material properties"); @@ -53,12 +55,9 @@ class Portal : public Object up = normalize(glm::cross(forward, right)); _transform = glm::mat3(right, up, forward); - _normal = forward; + _normal = forward * (invert_normal ? -1.0f : 1.0f); - std::cout << "Portal Transform Matrix:" << std::endl; - std::cout << glm::to_string(_transform) << std::endl; - - _linked_portal = linked_portal; + _linked_portal = -1; _mat_index = mat_index; } @@ -67,6 +66,25 @@ class Portal : public Object Portal(const glm::vec3 &position, const glm::vec3 &edge1, const glm::vec3 &edge2, const int linked_portal, const int mat_index) : Object(position, mat_index), _edge1(edge1), _edge2(edge2), _linked_portal(linked_portal) {} + Quad *createSupportQuad() const + { + float extension = 0.2f; + + glm::vec3 right_dir = glm::normalize(_edge1); + glm::vec3 up_dir = glm::normalize(_edge2); + + float right_length = glm::length(_edge1) + extension; + float up_length = glm::length(_edge2) + extension; + + glm::vec3 center_offset = -(right_dir * (extension / 2.0f) + up_dir * (extension / 2.0f)); + glm::vec3 position = _position + _normal * -0.001f + center_offset; + + glm::vec3 right = right_dir * right_length; + glm::vec3 up = up_dir * up_length; + + return (new Quad(position, right, up, _mat_index)); + } + glm::vec3 getEdge1() const { return (_edge1); } glm::vec3 getEdge2() const { return (_edge2); } glm::vec3 getNormal() const { return (_normal); } @@ -74,6 +92,7 @@ class Portal : public Object glm::mat3 getTransform() const { return (_transform); } int getLinkedPortalIndex() const { return (_linked_portal); } + void setLinkedPortalIndex(int index) { _linked_portal = index; } Type getType() const override { return Type::PORTAL; } diff --git a/scenes/test.rt b/scenes/test.rt index 8b2d6f4..8594eaa 100644 --- a/scenes/test.rt +++ b/scenes/test.rt @@ -13,10 +13,7 @@ cu 1 0.5 3 1 1 1 3 cu 1 0.5 -3 1 1 1 4 -qu 2.9 0.9 -0.001 0 2.2 0 2.2 0 0 3 -po 3 1 0 0 2 0 2 0 0 6 0 +po 3 1 0 0 2 0 2 0 0 0 3 +po -3 1 0 0 2 0 2 0 2 1 4 -qu -3.1 0.9 -0.001 0 2.2 0 2.2 0 0 4 -po -3 1 0 0 2 0 2 0 0 4 0 - -sp 0 30 0 30 2 \ No newline at end of file +sp 0 30 0 30 2 diff --git a/shaders/compute.glsl b/shaders/compute.glsl index 91c6b4a..dc889e3 100644 --- a/shaders/compute.glsl +++ b/shaders/compute.glsl @@ -74,17 +74,14 @@ Ray portalRay(Ray ray, hitInfo hit) portal_1 = objects[hit.obj_index]; portal_2 = objects[int(portal_1.radius)]; // saving memory radius = portal_index - vec3 portal_2_normal = portal_2.normal * sign(dot(ray.direction, portal_2.normal)); - relative = hit.position - portal_1.position; - ray.origin = portal_2.position + mat3(portal_2.transform) * relative; - ray.origin += portal_2_normal * 0.01; + mat3 rotation = mat3(portal_2.transform) * transpose(mat3(portal_1.transform)); - if (dot(ray.direction, portal_2_normal) < 0.0) - ray.direction = reflect(ray.direction, portal_2_normal); + ray.origin = portal_2.position + rotation * relative; + ray.direction = normalize(rotation * ray.direction); - ray.direction = normalize(mat3(portal_2.transform) * ray.direction); + ray.origin += ray.direction * 0.01f; return (ray); } diff --git a/srcs/class/Scene.cpp b/srcs/class/Scene.cpp index b472231..e7ff9ef 100644 --- a/srcs/class/Scene.cpp +++ b/srcs/class/Scene.cpp @@ -70,50 +70,58 @@ void Scene::updateGPUData() _gpu_objects.clear(); _gpu_materials.clear(); - for (const auto& obj : _objects) + for (int i = 0; i < _objects.size(); i++) { + Object *obj = _objects[i]; + gpu_obj.mat_index = obj->getMaterialIndex(); gpu_obj.position = obj->getPosition(); gpu_obj.type = static_cast(obj->getType()); if (obj->getType() == Object::Type::SPHERE) { - auto sphere = static_cast(obj); + auto sphere = static_cast(obj); gpu_obj.radius = sphere->getRadius(); } else if (obj->getType() == Object::Type::PLANE) { - auto plane = static_cast(obj); + auto plane = static_cast(obj); gpu_obj.normal = plane->getNormal(); } else if (obj->getType() == Object::Type::QUAD) { - auto quad = static_cast(obj); + auto quad = static_cast(obj); gpu_obj.vertex1 = quad->getEdge1(); gpu_obj.vertex2 = quad->getEdge2(); } else if (obj->getType() == Object::Type::TRIANGLE) { - auto triangle = static_cast(obj); + auto triangle = static_cast(obj); gpu_obj.vertex1 = triangle->getVertex2(); gpu_obj.vertex2 = triangle->getVertex3(); gpu_obj.normal = triangle->getNormal(); } else if (obj->getType() == Object::Type::CUBE) { - auto cube = static_cast(obj); + auto cube = static_cast(obj); gpu_obj.position = cube->getPosition(); gpu_obj.vertex1 = cube->getSize(); gpu_obj.type = static_cast(cube->getType()); } else if (obj->getType() == Object::Type::PORTAL) { - auto portal = static_cast(obj); + auto portal = static_cast(obj); gpu_obj.vertex1 = portal->getEdge1(); gpu_obj.vertex2 = portal->getEdge2(); gpu_obj.normal = portal->getNormal(); gpu_obj.transform = glm::mat4(portal->getTransform()); - gpu_obj.radius = portal->getLinkedPortalIndex(); + + gpu_obj.radius = i + 2; + if (_objects[i - 2]->getType() == Object::Type::PORTAL) + gpu_obj.radius = i - 2; + + Quad *quad = portal->createSupportQuad(); + _objects.push_back(quad); } _gpu_objects.push_back(gpu_obj);