[WIP] stripe-pattern is now ok.
This commit is contained in:
@@ -77,10 +77,10 @@ int shadow_sphere(uint8_t a_canvas_pixels, double a_wall_size, uint8_t a_wall_z)
|
|||||||
if (the_intersec.is_defined())
|
if (the_intersec.is_defined())
|
||||||
{
|
{
|
||||||
Tuple the_point = the_ray.position(the_intersec.distance_t());
|
Tuple the_point = the_ray.position(the_intersec.distance_t());
|
||||||
Tuple the_normal = the_intersec.object().normal_at(the_point);
|
Tuple the_normal = the_intersec.object()->normal_at(the_point);
|
||||||
Tuple the_eye = -the_ray.direction();
|
Tuple the_eye = -the_ray.direction();
|
||||||
Color the_color =
|
Color the_color = the_intersec.object()->material().lighting(nullptr, the_light, the_point, the_eye,
|
||||||
the_intersec.object().material().lighting(the_light, the_point, the_eye, the_normal, false);
|
the_normal, false);
|
||||||
the_canvas.write_pixel(x, y, the_color);
|
the_canvas.write_pixel(x, y, the_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ int main(void)
|
|||||||
Material &the_floor_material = the_floor->material();
|
Material &the_floor_material = the_floor->material();
|
||||||
the_floor_material.set_color(Color(1, 0.9, 0.9));
|
the_floor_material.set_color(Color(1, 0.9, 0.9));
|
||||||
the_floor_material.set_specular(0);
|
the_floor_material.set_specular(0);
|
||||||
the_floor_material.set_pattern(new StripePattern(Color(1, 1, 1), Color(0, 0, 0)));
|
the_floor_material.set_pattern(new StripePattern(Color(1, 1, 1), Color(1, 0.9, 0.9)));
|
||||||
the_world.add_object(the_floor);
|
the_world.add_object(the_floor);
|
||||||
|
|
||||||
// The large sphere in the middle is a unit sphere, translated upward slightly and colored green.
|
// The large sphere in the middle is a unit sphere, translated upward slightly and colored green.
|
||||||
@@ -62,6 +62,7 @@ int main(void)
|
|||||||
the_middle->set_transform(Matrix::translation(-0.5, 1, 0.5));
|
the_middle->set_transform(Matrix::translation(-0.5, 1, 0.5));
|
||||||
Material &the_middle_material = the_middle->material();
|
Material &the_middle_material = the_middle->material();
|
||||||
the_middle_material.set_color(Color(0.1, 1, 0.5));
|
the_middle_material.set_color(Color(0.1, 1, 0.5));
|
||||||
|
the_middle_material.set_pattern(new StripePattern(Color(1, 1, 1), Color(0.1, 1, 0.5)));
|
||||||
the_middle_material.set_diffuse(0.7);
|
the_middle_material.set_diffuse(0.7);
|
||||||
the_middle_material.set_specular(0.3);
|
the_middle_material.set_specular(0.3);
|
||||||
the_world.add_object(the_middle);
|
the_world.add_object(the_middle);
|
||||||
|
|||||||
@@ -54,9 +54,9 @@ void IntersectionData::set_distance_t(double a_value)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
const Shape &IntersectionData::object(void) const
|
Shape *IntersectionData::object(void) const
|
||||||
{
|
{
|
||||||
return *m_shape;
|
return m_shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ namespace Raytracer
|
|||||||
double distance_t(void) const;
|
double distance_t(void) const;
|
||||||
void set_distance_t(double a_value);
|
void set_distance_t(double a_value);
|
||||||
|
|
||||||
const Shape &object(void) const;
|
Shape *object(void) const;
|
||||||
void set_object(Shape *a_shape);
|
void set_object(Shape *a_shape);
|
||||||
|
|
||||||
const Tuple &point(void) const;
|
const Tuple &point(void) const;
|
||||||
|
|||||||
@@ -141,9 +141,9 @@ double Intersection::distance_t(void) const
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
const Shape &Intersection::object(void) const
|
const Shape *Intersection::object(void) const
|
||||||
{
|
{
|
||||||
return *m_shape;
|
return m_shape;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ namespace Raytracer
|
|||||||
bool operator<=(double a_distance) const;
|
bool operator<=(double a_distance) const;
|
||||||
|
|
||||||
double distance_t(void) const;
|
double distance_t(void) const;
|
||||||
const Shape &object(void) const;
|
const Shape *object(void) const;
|
||||||
bool is_nothing(void);
|
bool is_nothing(void);
|
||||||
bool is_defined(void);
|
bool is_defined(void);
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,9 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "core/common.h"
|
#include "core/common.h"
|
||||||
|
#include "shapes/shape.h"
|
||||||
|
|
||||||
|
#include "renderer/stripe-pattern.h"
|
||||||
|
|
||||||
#include "material.h"
|
#include "material.h"
|
||||||
|
|
||||||
@@ -144,8 +147,8 @@ void Material::set_pattern(StripePattern *a_pattern)
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
Color Material::lighting(const PointLight &a_light, const Tuple &a_point, const Tuple &an_eyev, const Tuple &a_normalv,
|
Color Material::lighting(Shape *an_object, const PointLight &a_light, const Tuple &a_point, const Tuple &an_eyev,
|
||||||
bool is_shadowed) const
|
const Tuple &a_normalv, bool is_shadowed) const
|
||||||
{
|
{
|
||||||
Color the_effective_color;
|
Color the_effective_color;
|
||||||
Tuple the_light_v, the_reflect_v;
|
Tuple the_light_v, the_reflect_v;
|
||||||
@@ -153,7 +156,7 @@ Color Material::lighting(const PointLight &a_light, const Tuple &a_point, const
|
|||||||
|
|
||||||
if (m_pattern != nullptr)
|
if (m_pattern != nullptr)
|
||||||
{
|
{
|
||||||
the_color = m_pattern->stripe_at(a_point);
|
the_color = m_pattern->stripe_at_object(an_object, a_point);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,13 +30,16 @@
|
|||||||
|
|
||||||
#include "core/color.h"
|
#include "core/color.h"
|
||||||
#include "core/tuple.h"
|
#include "core/tuple.h"
|
||||||
|
|
||||||
#include "lights/point-light.h"
|
#include "lights/point-light.h"
|
||||||
#include "stripe-pattern.h"
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
namespace Raytracer
|
namespace Raytracer
|
||||||
{
|
{
|
||||||
|
class Shape;
|
||||||
|
class StripePattern;
|
||||||
|
|
||||||
class Material
|
class Material
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -62,8 +65,8 @@ namespace Raytracer
|
|||||||
const StripePattern *pattern(void) const;
|
const StripePattern *pattern(void) const;
|
||||||
void set_pattern(StripePattern *a_pattern);
|
void set_pattern(StripePattern *a_pattern);
|
||||||
|
|
||||||
Color lighting(const PointLight &a_light, const Tuple &a_point, const Tuple &an_eyev, const Tuple &a_normalv,
|
Color lighting(Shape *an_object, const PointLight &a_light, const Tuple &a_point, const Tuple &an_eyev,
|
||||||
bool is_shadowed) const;
|
const Tuple &a_normalv, bool is_shadowed) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Color m_color;
|
Color m_color;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ using namespace Raytracer;
|
|||||||
|
|
||||||
StripePattern::StripePattern(const Color &a_color_a, const Color &a_color_b) : m_a(a_color_a), m_b(a_color_b)
|
StripePattern::StripePattern(const Color &a_color_a, const Color &a_color_b) : m_a(a_color_a), m_b(a_color_b)
|
||||||
{
|
{
|
||||||
|
m_transform = Matrix::identity();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
@@ -72,3 +73,20 @@ const Color &StripePattern::stripe_at(const Tuple &a_point) const
|
|||||||
|
|
||||||
return m_b;
|
return m_b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
void StripePattern::set_pattern_transform(const Matrix &a_transform_matrix)
|
||||||
|
{
|
||||||
|
m_transform = a_transform_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
const Color &StripePattern::stripe_at_object(Shape *an_object, const Tuple &a_world_point) const
|
||||||
|
{
|
||||||
|
Tuple the_objet_point = an_object->transform().inverse() * a_world_point;
|
||||||
|
Tuple the_pattern_point = m_transform.inverse() * the_objet_point;
|
||||||
|
|
||||||
|
return stripe_at(the_pattern_point);
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,8 +29,11 @@
|
|||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "core/color.h"
|
#include "core/color.h"
|
||||||
|
#include "core/matrix.h"
|
||||||
#include "core/tuple.h"
|
#include "core/tuple.h"
|
||||||
|
|
||||||
|
#include "shapes/shape.h"
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
namespace Raytracer
|
namespace Raytracer
|
||||||
@@ -47,7 +50,12 @@ namespace Raytracer
|
|||||||
|
|
||||||
const Color &stripe_at(const Tuple &a_point) const;
|
const Color &stripe_at(const Tuple &a_point) const;
|
||||||
|
|
||||||
|
void set_pattern_transform(const Matrix &a_transform_matrix);
|
||||||
|
|
||||||
|
const Color &stripe_at_object(Shape *an_object, const Tuple &a_world_point) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Matrix m_transform;
|
||||||
Color m_a;
|
Color m_a;
|
||||||
Color m_b;
|
Color m_b;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "core/matrix.h"
|
#include "core/matrix.h"
|
||||||
|
|
||||||
|
#include "shapes/shape.h"
|
||||||
#include "shapes/sphere.h"
|
#include "shapes/sphere.h"
|
||||||
|
|
||||||
#include "world.h"
|
#include "world.h"
|
||||||
@@ -158,9 +160,9 @@ Intersections World::intersect_world(const Ray &a_ray) const
|
|||||||
Color World::shade_hit(const IntersectionData &an_intersection_data) const
|
Color World::shade_hit(const IntersectionData &an_intersection_data) const
|
||||||
{
|
{
|
||||||
bool the_shadowed = is_shadowed(an_intersection_data.over_point());
|
bool the_shadowed = is_shadowed(an_intersection_data.over_point());
|
||||||
return an_intersection_data.object().material().lighting(m_light, an_intersection_data.over_point(),
|
Shape *the_object = an_intersection_data.object();
|
||||||
an_intersection_data.eyev(),
|
return the_object->material().lighting(the_object, m_light, an_intersection_data.over_point(),
|
||||||
an_intersection_data.normalv(), the_shadowed);
|
an_intersection_data.eyev(), an_intersection_data.normalv(), the_shadowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
|
|
||||||
namespace Raytracer
|
namespace Raytracer
|
||||||
{
|
{
|
||||||
|
class Shape;
|
||||||
|
|
||||||
class World
|
class World
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -80,6 +80,13 @@ bool Shape::operator==(const Shape &a_shape) const
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
bool Shape::operator==(const Shape *a_shape) const
|
||||||
|
{
|
||||||
|
return (m_transform == a_shape->m_transform) && (m_material == a_shape->m_material);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
Matrix &Shape::transform(void)
|
Matrix &Shape::transform(void)
|
||||||
{
|
{
|
||||||
return m_transform;
|
return m_transform;
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ namespace Raytracer
|
|||||||
|
|
||||||
const Shape &operator=(const Shape &a_shape);
|
const Shape &operator=(const Shape &a_shape);
|
||||||
bool operator==(const Shape &a_shape) const;
|
bool operator==(const Shape &a_shape) const;
|
||||||
|
bool operator==(const Shape *a_shape) const;
|
||||||
|
|
||||||
Matrix &transform(void);
|
Matrix &transform(void);
|
||||||
const Matrix &transform(void) const;
|
const Matrix &transform(void) const;
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ SCENARIO("An intersection encapsulates t and object", "[features/intersections.f
|
|||||||
}
|
}
|
||||||
AND_THEN("i.object = s")
|
AND_THEN("i.object = s")
|
||||||
{
|
{
|
||||||
REQUIRE(i.object() == s);
|
REQUIRE(*i.object() == s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ SCENARIO("An intersection could be affected", "[features/intersections.feature]"
|
|||||||
}
|
}
|
||||||
AND_THEN("i2.object = s")
|
AND_THEN("i2.object = s")
|
||||||
{
|
{
|
||||||
REQUIRE(i2.object() == s);
|
REQUIRE(*i2.object() == s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -403,11 +403,11 @@ SCENARIO("Intersect sets the object on the intersection", "[features/spheres.fea
|
|||||||
}
|
}
|
||||||
AND_THEN("xs[0].object = s")
|
AND_THEN("xs[0].object = s")
|
||||||
{
|
{
|
||||||
REQUIRE(xs[0].object() == s);
|
REQUIRE(*xs[0].object() == s);
|
||||||
}
|
}
|
||||||
AND_THEN("xs[1].object = s")
|
AND_THEN("xs[1].object = s")
|
||||||
{
|
{
|
||||||
REQUIRE(xs[1].object() == s);
|
REQUIRE(*xs[1].object() == s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ SCENARIO("Lighting with the eye between the light and the surface", "[features/m
|
|||||||
PointLight light = PointLight(Tuple::Point(0, 0, -10), Color(1, 1, 1));
|
PointLight light = PointLight(Tuple::Point(0, 0, -10), Color(1, 1, 1));
|
||||||
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
||||||
{
|
{
|
||||||
Color result = m.lighting(light, position, eyev, normalv, false);
|
Color result = m.lighting(nullptr, light, position, eyev, normalv, false);
|
||||||
THEN("result = color(1.9, 1.9, 1.9)")
|
THEN("result = color(1.9, 1.9, 1.9)")
|
||||||
{
|
{
|
||||||
REQUIRE(result == Color(1.9, 1.9, 1.9));
|
REQUIRE(result == Color(1.9, 1.9, 1.9));
|
||||||
@@ -360,7 +360,7 @@ SCENARIO("Lighting with eye between the light & surface, eye offset 45°", "[fea
|
|||||||
PointLight light = PointLight(Tuple::Point(0, 0, -10), Color(1, 1, 1));
|
PointLight light = PointLight(Tuple::Point(0, 0, -10), Color(1, 1, 1));
|
||||||
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
||||||
{
|
{
|
||||||
Color result = m.lighting(light, position, eyev, normalv, false);
|
Color result = m.lighting(nullptr, light, position, eyev, normalv, false);
|
||||||
THEN("result = color(1.0, 1.0, 1.0)")
|
THEN("result = color(1.0, 1.0, 1.0)")
|
||||||
{
|
{
|
||||||
REQUIRE(result == Color(1.0, 1.0, 1.0));
|
REQUIRE(result == Color(1.0, 1.0, 1.0));
|
||||||
@@ -389,7 +389,7 @@ SCENARIO("Lighting with the eye opposite surface, light offset 45°", "[features
|
|||||||
PointLight light = PointLight(Tuple::Point(0, 10, -10), Color(1, 1, 1));
|
PointLight light = PointLight(Tuple::Point(0, 10, -10), Color(1, 1, 1));
|
||||||
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
||||||
{
|
{
|
||||||
Color result = m.lighting(light, position, eyev, normalv, false);
|
Color result = m.lighting(nullptr, light, position, eyev, normalv, false);
|
||||||
THEN("result = color(0.7364, 0.7364, 0.7364)")
|
THEN("result = color(0.7364, 0.7364, 0.7364)")
|
||||||
{
|
{
|
||||||
REQUIRE(result == Color(0.7364, 0.7364, 0.7364));
|
REQUIRE(result == Color(0.7364, 0.7364, 0.7364));
|
||||||
@@ -418,7 +418,7 @@ SCENARIO("Lighting with the eye in the path of the reflection vector", "[feature
|
|||||||
PointLight light = PointLight(Tuple::Point(0, 10, -10), Color(1, 1, 1));
|
PointLight light = PointLight(Tuple::Point(0, 10, -10), Color(1, 1, 1));
|
||||||
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
||||||
{
|
{
|
||||||
Color result = m.lighting(light, position, eyev, normalv, false);
|
Color result = m.lighting(nullptr, light, position, eyev, normalv, false);
|
||||||
THEN("result = color(1.6364, 1.6364, 1.6364)")
|
THEN("result = color(1.6364, 1.6364, 1.6364)")
|
||||||
{
|
{
|
||||||
REQUIRE(result == Color(1.6364, 1.6364, 1.6364));
|
REQUIRE(result == Color(1.6364, 1.6364, 1.6364));
|
||||||
@@ -447,7 +447,7 @@ SCENARIO("Lighting with the light behind the surface", "[features/materials.feat
|
|||||||
PointLight light = PointLight(Tuple::Point(0, 0, 10), Color(1, 1, 1));
|
PointLight light = PointLight(Tuple::Point(0, 0, 10), Color(1, 1, 1));
|
||||||
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
WHEN("result <- lighting(m, light, position, eyev, normalv)")
|
||||||
{
|
{
|
||||||
Color result = m.lighting(light, position, eyev, normalv, false);
|
Color result = m.lighting(nullptr, light, position, eyev, normalv, false);
|
||||||
THEN("result = color(0.1, 0.1, 0.1)")
|
THEN("result = color(0.1, 0.1, 0.1)")
|
||||||
{
|
{
|
||||||
REQUIRE(result == Color(0.1, 0.1, 0.1));
|
REQUIRE(result == Color(0.1, 0.1, 0.1));
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ SCENARIO("Lightning with the surface in shadow", "[features/materials.feature]")
|
|||||||
bool in_shadow = true;
|
bool in_shadow = true;
|
||||||
WHEN("result <- lighting(m, light, position, eyev, normalv, in_shadow)")
|
WHEN("result <- lighting(m, light, position, eyev, normalv, in_shadow)")
|
||||||
{
|
{
|
||||||
Color result = m.lighting(light, position, eyev, normalv, in_shadow);
|
Color result = m.lighting(nullptr, light, position, eyev, normalv, in_shadow);
|
||||||
THEN("result = color(0.1, 0.1, 0.1)")
|
THEN("result = color(0.1, 0.1, 0.1)")
|
||||||
{
|
{
|
||||||
REQUIRE(result == Color(0.1, 0.1, 0.1));
|
REQUIRE(result == Color(0.1, 0.1, 0.1));
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ SCENARIO("A ray Intersecting a plane from above", "[features/planes.feature]")
|
|||||||
}
|
}
|
||||||
AND_THEN("xs[0].object = p")
|
AND_THEN("xs[0].object = p")
|
||||||
{
|
{
|
||||||
REQUIRE(xs[0].object() == p);
|
REQUIRE(*xs[0].object() == p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,12 +58,15 @@ SCENARIO("A stripe pattern is constant in y", "[features/patterns.feature]")
|
|||||||
StripePattern pattern(Color::White(), Color::Black());
|
StripePattern pattern(Color::White(), Color::Black());
|
||||||
THEN("stripe_at(pattern, point(0, 0, 0) = white")
|
THEN("stripe_at(pattern, point(0, 0, 0) = white")
|
||||||
{
|
{
|
||||||
|
REQUIRE(pattern.stripe_at(Tuple::Point(0, 0, 0)) == Color::White());
|
||||||
}
|
}
|
||||||
AND_THEN("stripe_at(pattern, point(0, 1, 0) = white")
|
AND_THEN("stripe_at(pattern, point(0, 1, 0) = white")
|
||||||
{
|
{
|
||||||
|
REQUIRE(pattern.stripe_at(Tuple::Point(0, 1, 0)) == Color::White());
|
||||||
}
|
}
|
||||||
AND_THEN("stripe_at(pattern, point(0, 2, 0) = white")
|
AND_THEN("stripe_at(pattern, point(0, 2, 0) = white")
|
||||||
{
|
{
|
||||||
|
REQUIRE(pattern.stripe_at(Tuple::Point(0, 2, 0)) == Color::White());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -128,42 +131,48 @@ SCENARIO("A stripe pattern alternates in x", "[features/patterns.feature]")
|
|||||||
|
|
||||||
SCENARIO("Lightning with a pattern applied", "[features/materials.feature]")
|
SCENARIO("Lightning with a pattern applied", "[features/materials.feature]")
|
||||||
{
|
{
|
||||||
Material m;
|
GIVEN("object <- sphere()")
|
||||||
GIVEN("m.pattern <- strip_pattern(color(1, 1, 1), color(0, 0, 0))")
|
|
||||||
{
|
{
|
||||||
m.set_pattern(new StripePattern(Color(1, 1, 1), Color(0, 0, 0)));
|
Sphere object;
|
||||||
AND_GIVEN("m.ambient <- 1")
|
Material m;
|
||||||
|
GIVEN("m.pattern <- strip_pattern(color(1, 1, 1), color(0, 0, 0))")
|
||||||
{
|
{
|
||||||
m.set_ambient(1);
|
m.set_pattern(new StripePattern(Color(1, 1, 1), Color(0, 0, 0)));
|
||||||
AND_GIVEN("m.diffuse <- 0")
|
AND_GIVEN("m.ambient <- 1")
|
||||||
{
|
{
|
||||||
m.set_diffuse(0);
|
m.set_ambient(1);
|
||||||
AND_GIVEN("m.specular <- 0")
|
AND_GIVEN("m.diffuse <- 0")
|
||||||
{
|
{
|
||||||
m.set_specular(0);
|
m.set_diffuse(0);
|
||||||
AND_GIVEN("eyev <- vector(0, 0, -1)")
|
AND_GIVEN("m.specular <- 0")
|
||||||
{
|
{
|
||||||
Tuple eyev = Tuple::Vector(0, 0, -1);
|
m.set_specular(0);
|
||||||
AND_GIVEN("normalv <- vector(0, 0, -1)")
|
AND_GIVEN("eyev <- vector(0, 0, -1)")
|
||||||
{
|
{
|
||||||
Tuple normalv = Tuple::Vector(0, 0, -1);
|
Tuple eyev = Tuple::Vector(0, 0, -1);
|
||||||
AND_GIVEN("light <- point_light(point(0, 0, -10), color(1, 1, 1))")
|
AND_GIVEN("normalv <- vector(0, 0, -1)")
|
||||||
{
|
{
|
||||||
PointLight light = PointLight(Tuple::Point(0, 0, -10), Color(1, 1, 1));
|
Tuple normalv = Tuple::Vector(0, 0, -1);
|
||||||
|
AND_GIVEN("light <- point_light(point(0, 0, -10), color(1, 1, 1))")
|
||||||
WHEN("c1 <- lighting(m, light, point(0.9, 0, 0), eyev, normalv, false)")
|
|
||||||
{
|
{
|
||||||
Color c1 = m.lighting(light, Tuple::Point(0.9, 0, 0), eyev, normalv, false);
|
PointLight light = PointLight(Tuple::Point(0, 0, -10), Color(1, 1, 1));
|
||||||
AND_WHEN("c2 <- lighting(m, light, point(1.1, 0, 0), eyev, normalv, false)")
|
|
||||||
|
WHEN("c1 <- lighting(m, light, point(0.9, 0, 0), eyev, normalv, false)")
|
||||||
{
|
{
|
||||||
Color c2 = m.lighting(light, Tuple::Point(1.1, 0, 0), eyev, normalv, false);
|
Color c1 =
|
||||||
THEN("c1 = color(1, 1, 1)")
|
m.lighting(&object, light, Tuple::Point(0.9, 0, 0), eyev, normalv, false);
|
||||||
|
AND_WHEN("c2 <- lighting(m, light, point(1.1, 0, 0), eyev, normalv, false)")
|
||||||
{
|
{
|
||||||
REQUIRE(c1 == Color(1, 1, 1));
|
Color c2 = m.lighting(&object, light, Tuple::Point(1.1, 0, 0), eyev,
|
||||||
}
|
normalv, false);
|
||||||
AND_THEN("c2 = color(0, 0, 0)")
|
THEN("c1 = color(1, 1, 1)")
|
||||||
{
|
{
|
||||||
REQUIRE(c2 == Color(0, 0, 0));
|
REQUIRE(c1 == Color(1, 1, 1));
|
||||||
|
}
|
||||||
|
AND_THEN("c2 = color(0, 0, 0)")
|
||||||
|
{
|
||||||
|
REQUIRE(c2 == Color(0, 0, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -175,3 +184,85 @@ SCENARIO("Lightning with a pattern applied", "[features/materials.feature]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SCENARIO("Stripes with an object transformation", "[features/patterns.feature]")
|
||||||
|
{
|
||||||
|
GIVEN("object <- sphere()")
|
||||||
|
{
|
||||||
|
Sphere object;
|
||||||
|
AND_GIVEN("set_transform(object, scaling(2, 2, 2))")
|
||||||
|
{
|
||||||
|
object.set_transform(Matrix::scaling(2, 2, 2));
|
||||||
|
AND_GIVEN("pattern <- stripe_pattern(white, black)")
|
||||||
|
{
|
||||||
|
StripePattern pattern(Color::White(), Color::Black());
|
||||||
|
WHEN("c <- stripe_at_object(pattern, object, point(1.5, 0, 0))")
|
||||||
|
{
|
||||||
|
Color c = pattern.stripe_at_object(&object, Tuple::Point(1.5, 0, 0));
|
||||||
|
THEN("c = white")
|
||||||
|
{
|
||||||
|
REQUIRE(c == Color::White());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SCENARIO("Stripes with an pattern transformation", "[features/patterns.feature]")
|
||||||
|
{
|
||||||
|
GIVEN("object <- sphere()")
|
||||||
|
{
|
||||||
|
Sphere object;
|
||||||
|
AND_GIVEN("pattern <- stripe_pattern(white, black)")
|
||||||
|
{
|
||||||
|
StripePattern pattern(Color::White(), Color::Black());
|
||||||
|
AND_GIVEN("set_transform(pattern, scaling(2, 2, 2))")
|
||||||
|
{
|
||||||
|
pattern.set_pattern_transform(Matrix::scaling(2, 2, 2));
|
||||||
|
WHEN("c <- stripe_at_object(pattern, object, point(1.5, 0, 0))")
|
||||||
|
{
|
||||||
|
Color c = pattern.stripe_at_object(&object, Tuple::Point(1.5, 0, 0));
|
||||||
|
THEN("c = white")
|
||||||
|
{
|
||||||
|
REQUIRE(c == Color::White());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
SCENARIO("Stripes with both an object and pattern transformation", "[features/patterns.feature]")
|
||||||
|
{
|
||||||
|
GIVEN("object <- sphere()")
|
||||||
|
{
|
||||||
|
Sphere object;
|
||||||
|
AND_GIVEN("set_transform(object, scaling(2, 2, 2))")
|
||||||
|
{
|
||||||
|
object.set_transform(Matrix::scaling(2, 2, 2));
|
||||||
|
AND_GIVEN("pattern <- stripe_pattern(white, black)")
|
||||||
|
{
|
||||||
|
StripePattern pattern(Color::White(), Color::Black());
|
||||||
|
AND_GIVEN("set_pattern_transform(pattern, translation(0.5, 0, 0)))")
|
||||||
|
{
|
||||||
|
pattern.set_pattern_transform(Matrix::translation(0.5, 0, 0));
|
||||||
|
WHEN("c <- stripe_at_object(pattern, object, point(2.5, 0, 0))")
|
||||||
|
{
|
||||||
|
Color c = pattern.stripe_at_object(&object, Tuple::Point(1.5, 0, 0));
|
||||||
|
THEN("c = white")
|
||||||
|
{
|
||||||
|
REQUIRE(c == Color::White());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user