[FEAT] Not working yet. Move intersect to object and sphere instead of RAy.
This commit is contained in:
@@ -28,20 +28,23 @@
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include "intersection.h"
|
||||
#include "common.h"
|
||||
|
||||
#include "intersection.h"
|
||||
|
||||
using namespace Raytracer;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Intersection::Intersection(void) : m_distance_t(0.0)
|
||||
Intersection::Intersection(void) : m_distance_t(0.0), m_object()
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Intersection::Intersection(double a_distance_t, Object an_object) : m_distance_t(a_distance_t), m_object(an_object)
|
||||
Intersection::Intersection(double a_distance_t, const Object &an_object) :
|
||||
m_distance_t(a_distance_t),
|
||||
m_object(an_object)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -134,7 +137,7 @@ double Intersection::distance_t(void) const
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Object &Intersection::object(void)
|
||||
const Object &Intersection::object(void) const
|
||||
{
|
||||
return m_object;
|
||||
}
|
||||
|
||||
@@ -34,11 +34,13 @@
|
||||
|
||||
namespace Raytracer
|
||||
{
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class Intersection
|
||||
{
|
||||
public:
|
||||
Intersection(void);
|
||||
Intersection(double a_distance_t, Object an_object);
|
||||
Intersection(double a_distance_t, const Object &an_object);
|
||||
Intersection(Intersection &an_intersection);
|
||||
Intersection(const Intersection &an_intersection);
|
||||
|
||||
@@ -53,7 +55,7 @@ namespace Raytracer
|
||||
bool operator<=(double a_distance) const;
|
||||
|
||||
double distance_t(void) const;
|
||||
Object &object(void);
|
||||
const Object &object(void) const;
|
||||
|
||||
private:
|
||||
double m_distance_t;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <initializer_list>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include "intersection.h"
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include "intersections.h"
|
||||
|
||||
#include "object.h"
|
||||
|
||||
using namespace Raytracer;
|
||||
@@ -40,19 +42,19 @@ uint32_t Object::s_current_index = 0;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Object::Object(void) : m_id(kNothing)
|
||||
Object::Object(void) : m_id(kNothing), m_transform(Matrix::identity())
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Object::Object(Object &a_copy) : m_id(a_copy.m_id)
|
||||
Object::Object(Object &a_copy) : m_id(a_copy.m_id), m_transform(Matrix::identity())
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Object::Object(const Object &a_copy) : m_id(a_copy.m_id)
|
||||
Object::Object(const Object &a_copy) : m_id(a_copy.m_id), m_transform(Matrix::identity())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -66,6 +68,7 @@ const Object &Object::operator=(const Object &an_other)
|
||||
}
|
||||
|
||||
m_id = an_other.m_id;
|
||||
m_transform = an_other.m_transform;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -74,7 +77,7 @@ const Object &Object::operator=(const Object &an_other)
|
||||
|
||||
bool Object::operator==(const Object &an_object) const
|
||||
{
|
||||
return m_id == an_object.m_id;
|
||||
return (m_id == an_object.m_id) && (m_transform == an_object.m_transform);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -86,6 +89,29 @@ bool Object::is_nothing(void)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Matrix &Object::transform(void)
|
||||
{
|
||||
return m_transform;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void Object::set_transform(const Matrix &a_transform_matrix)
|
||||
{
|
||||
m_transform = a_transform_matrix;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Intersections Object::intersect(Ray &a_ray)
|
||||
{
|
||||
Intersections the_ret;
|
||||
|
||||
return the_ret;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void Object::inc_id(void)
|
||||
{
|
||||
m_id = s_current_index++;
|
||||
|
||||
@@ -30,10 +30,17 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "matrix.h"
|
||||
#include "ray.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
namespace Raytracer
|
||||
{
|
||||
class Intersections;
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
@@ -46,11 +53,17 @@ namespace Raytracer
|
||||
|
||||
bool is_nothing(void);
|
||||
|
||||
Matrix &transform(void);
|
||||
void set_transform(const Matrix &a_transform_matrix);
|
||||
|
||||
virtual Intersections intersect(Ray &a_ray);
|
||||
|
||||
protected:
|
||||
void inc_id(void);
|
||||
|
||||
private:
|
||||
uint32_t m_id;
|
||||
Matrix m_transform;
|
||||
static uint32_t s_current_index;
|
||||
};
|
||||
}; // namespace Raytracer
|
||||
|
||||
@@ -28,10 +28,8 @@
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "common.h"
|
||||
#include "ray.h"
|
||||
#include "common.h"
|
||||
|
||||
using namespace Raytracer;
|
||||
|
||||
@@ -64,29 +62,6 @@ Tuple Ray::position(double a_distance)
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Intersections Ray::intersect(Sphere a_sphere)
|
||||
{
|
||||
Intersections the_intersections;
|
||||
Tuple the_sphere_to_ray = m_origin - Tuple::Point(0, 0, 0);
|
||||
|
||||
double the_a = m_direction.dot(m_direction);
|
||||
double the_b = 2 * m_direction.dot(the_sphere_to_ray);
|
||||
double the_c = the_sphere_to_ray.dot(the_sphere_to_ray) - 1;
|
||||
|
||||
double discriminant = std::pow(the_b, 2) - 4 * the_a * the_c;
|
||||
double the_sqrt = std::sqrt(discriminant);
|
||||
|
||||
if (discriminant >= 0)
|
||||
{
|
||||
the_intersections.add(Intersection((-the_b - the_sqrt) / (2 * the_a), a_sphere));
|
||||
the_intersections.add(Intersection((-the_b + the_sqrt) / (2 * the_a), a_sphere));
|
||||
}
|
||||
|
||||
return the_intersections;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Ray Ray::transform(const Matrix &a_matrix)
|
||||
{
|
||||
Ray the_output_ray;
|
||||
|
||||
@@ -28,11 +28,7 @@
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "intersections.h"
|
||||
#include "matrix.h"
|
||||
#include "sphere.h"
|
||||
#include "tuple.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -49,7 +45,6 @@ namespace Raytracer
|
||||
const Tuple &direction(void) const;
|
||||
|
||||
Tuple position(double a_distance);
|
||||
Intersections intersect(Sphere a_sphere);
|
||||
|
||||
Ray transform(const Matrix &a_matrix);
|
||||
|
||||
|
||||
@@ -28,8 +28,12 @@
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#include "sphere.h"
|
||||
#include <cmath>
|
||||
|
||||
#include "common.h"
|
||||
#include "intersections.h"
|
||||
|
||||
#include "sphere.h"
|
||||
|
||||
using namespace Raytracer;
|
||||
|
||||
@@ -39,3 +43,29 @@ Sphere::Sphere(void)
|
||||
{
|
||||
inc_id();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
Intersections Sphere::intersect(Ray &a_ray)
|
||||
{
|
||||
Intersections the_intersections;
|
||||
Ray the_ray = a_ray.transform(transform().inverse());
|
||||
|
||||
Tuple the_sphere_to_ray = the_ray.origin() - Tuple::Point(0, 0, 0);
|
||||
Tuple the_direction = the_ray.direction();
|
||||
|
||||
double the_a = the_direction.dot(the_direction);
|
||||
double the_b = 2 * the_direction.dot(the_sphere_to_ray);
|
||||
double the_c = the_sphere_to_ray.dot(the_sphere_to_ray) - 1;
|
||||
|
||||
double discriminant = std::pow(the_b, 2) - 4 * the_a * the_c;
|
||||
|
||||
if (discriminant >= 0)
|
||||
{
|
||||
double the_sqrt = std::sqrt(discriminant);
|
||||
the_intersections.add(Intersection((-the_b - the_sqrt) / (2 * the_a), *this));
|
||||
the_intersections.add(Intersection((-the_b + the_sqrt) / (2 * the_a), *this));
|
||||
}
|
||||
|
||||
return the_intersections;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace Raytracer
|
||||
{
|
||||
public:
|
||||
Sphere(void);
|
||||
Intersections intersect(Ray &a_ray) override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -63,7 +63,7 @@ TEST_CASE("[05][Rays] a ray intersects a sphere at two points", "[Sphere]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
Intersections xs = r.intersect(s);
|
||||
Intersections xs = s.intersect(r);
|
||||
|
||||
REQUIRE(xs.count() == 2);
|
||||
REQUIRE(xs[0].distance_t() == 4.0);
|
||||
@@ -76,7 +76,7 @@ TEST_CASE("[05][Rays] a ray intersects a sphere at a tangent", "[Sphere]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 1, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
Intersections xs = r.intersect(s);
|
||||
Intersections xs = s.intersect(r);
|
||||
|
||||
REQUIRE(xs.count() == 2);
|
||||
REQUIRE(xs[0].distance_t() == 5.0);
|
||||
@@ -89,7 +89,7 @@ TEST_CASE("[05][Rays] a ray misses a sphere", "[Sphere]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 2, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
Intersections xs = r.intersect(s);
|
||||
Intersections xs = s.intersect(r);
|
||||
|
||||
REQUIRE(xs.count() == 0);
|
||||
}
|
||||
@@ -100,7 +100,7 @@ TEST_CASE("[05][Rays] a originates inside a sphere", "[Sphere]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, 0), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
Intersections xs = r.intersect(s);
|
||||
Intersections xs = s.intersect(r);
|
||||
|
||||
REQUIRE(xs.count() == 2);
|
||||
REQUIRE(xs[0].distance_t() == -1.0);
|
||||
@@ -113,7 +113,7 @@ TEST_CASE("[05][Rays] a sphere is behind a ray", "[Sphere]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, 5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
Intersections xs = r.intersect(s);
|
||||
Intersections xs = s.intersect(r);
|
||||
|
||||
REQUIRE(xs.count() == 2);
|
||||
REQUIRE(xs[0].distance_t() == -6.0);
|
||||
@@ -163,7 +163,7 @@ TEST_CASE("[05][Rays] Intersect set the object on the intersection", "[Intersect
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, 5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
Intersections xs = r.intersect(s);
|
||||
Intersections xs = s.intersect(r);
|
||||
|
||||
REQUIRE(xs.count() == 2);
|
||||
REQUIRE(xs[0].object() == s);
|
||||
@@ -207,9 +207,9 @@ TEST_CASE("[05][Rays] The hit, when all intersections have negative t", "[Inters
|
||||
Intersection i2(-1, s);
|
||||
Intersections xs = Intersections({i1, i2});
|
||||
|
||||
Intersection i = xs.hit();
|
||||
auto i = xs.hit();
|
||||
|
||||
REQUIRE(i.object().is_nothing());
|
||||
// REQUIRE(i.has_value());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -251,3 +251,47 @@ TEST_CASE("[05][Rays] Scaling a ray", "[Rays]")
|
||||
REQUIRE(r2.origin() == Tuple::Point(2, 6, 12));
|
||||
REQUIRE(r2.direction() == Tuple::Vector(0, 3, 0));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] A sphere's default transformation", "[Sphere]")
|
||||
{
|
||||
Sphere s;
|
||||
REQUIRE(s.transform() == Matrix::identity());
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Changing a sphere's transformation", "[Sphere]")
|
||||
{
|
||||
Sphere s;
|
||||
Matrix t = Matrix::translation(2, 3, 4);
|
||||
s.set_transform(t);
|
||||
REQUIRE(s.transform() == t);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
#if 0
|
||||
TEST_CASE("[05][Rays] Intersecting a scaled sphere with a ray", "[Sphere]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
s.set_transform(Matrix::scaling(2, 2, 2));
|
||||
Intersections xs = s.intersect(r);
|
||||
|
||||
REQUIRE(xs.count() == 2);
|
||||
REQUIRE(xs[0].distance_t() == 3);
|
||||
REQUIRE(xs[1].distance_t() == 7);
|
||||
}
|
||||
#endif
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
TEST_CASE("[05][Rays] Intersecting a translated sphere with a ray", "[Sphere]")
|
||||
{
|
||||
Ray r(Tuple::Point(0, 0, -5), Tuple::Vector(0, 0, 1));
|
||||
Sphere s;
|
||||
s.set_transform(Matrix::translation(5, 0, 0));
|
||||
Intersections xs = s.intersect(r);
|
||||
|
||||
REQUIRE(xs.count() == 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user