Boundingboxes should be ready.
Next step (later) would be to properly use them other than group to lower the number of intersection calculation per ray.
This commit is contained in:
@@ -5,7 +5,8 @@ find_package(Threads REQUIRED)
|
||||
|
||||
set(TESTS_SRC math_test.cpp tuple_test.cpp colour_test.cpp canvas_test.cpp matrix_test.cpp transformation_test.cpp
|
||||
ray_test.cpp intersect_test.cpp sphere_test.cpp light_test.cpp material_test.cpp world_test.cpp camera_test.cpp
|
||||
shape_test.cpp plane_test.cpp pattern_test.cpp cube_test.cpp cylinder_test.cpp cone_test.cpp group_test.cpp)
|
||||
shape_test.cpp plane_test.cpp pattern_test.cpp cube_test.cpp cylinder_test.cpp cone_test.cpp group_test.cpp
|
||||
boundingbox_test.cpp)
|
||||
|
||||
add_executable(testMyRays)
|
||||
target_include_directories(testMyRays PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
|
||||
|
||||
81
tests/boundingbox_test.cpp
Normal file
81
tests/boundingbox_test.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* DoRayMe - a quick and dirty Raytracer
|
||||
* Boundingbox unit tests
|
||||
*
|
||||
* Created by Manoël Trapier
|
||||
* Copyright (c) 2020 986-Studio.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* DoRayMe - a quick and dirty Raytracer
|
||||
* Camera unit tests
|
||||
*
|
||||
* Created by Manoël Trapier
|
||||
* Copyright (c) 2020 986-Studio.
|
||||
*
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <math_helper.h>
|
||||
#include <ray.h>
|
||||
#include <transformation.h>
|
||||
#include <stdint.h>
|
||||
#include <boundingbox.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(BoundingBox, Default_boundingbox_is_not_set)
|
||||
{
|
||||
BoundingBox bb;
|
||||
|
||||
ASSERT_TRUE(bb.isEmpty());
|
||||
ASSERT_EQ(bb.min, Point(INFINITY, INFINITY, INFINITY));
|
||||
ASSERT_EQ(bb.max, Point(-INFINITY, -INFINITY, -INFINITY));
|
||||
}
|
||||
|
||||
TEST(BoundingBox, Bounding_box_can_be_created_with_values)
|
||||
{
|
||||
BoundingBox bb = BoundingBox(Point(-1, -1, -1), Point(1, 1, 1));
|
||||
|
||||
ASSERT_FALSE(bb.isEmpty());
|
||||
ASSERT_EQ(bb.min, Point(-1, -1, -1));
|
||||
ASSERT_EQ(bb.max, Point(1, 1, 1));
|
||||
}
|
||||
|
||||
TEST(BoundingBox, Cating_a_bb_to_an_empty_bb_reset_the_original_one)
|
||||
{
|
||||
BoundingBox bb;
|
||||
|
||||
bb | BoundingBox(Point(-1, -1, -1), Point(1, 1, 1));
|
||||
|
||||
ASSERT_FALSE(bb.isEmpty());
|
||||
ASSERT_EQ(bb.min, Point(-1, -1, -1));
|
||||
ASSERT_EQ(bb.max, Point(1, 1, 1));
|
||||
}
|
||||
|
||||
TEST(BoundingBox, Cating_a_bb_to_another_bb_expand_the_original_one_if_needed)
|
||||
{
|
||||
BoundingBox bb(Point(-1, -1, -1), Point(1, 1, 1));
|
||||
|
||||
bb | BoundingBox(Point(-2, 0, -5), Point(4, 5, 0.5));
|
||||
|
||||
ASSERT_FALSE(bb.isEmpty());
|
||||
ASSERT_EQ(bb.min, Point(-2, -1, -5));
|
||||
ASSERT_EQ(bb.max, Point(4, 5, 1));
|
||||
}
|
||||
|
||||
TEST(BoundingBox, A_smaller_bb_should_fit_in_a_bigger)
|
||||
{
|
||||
BoundingBox bigBb = BoundingBox(Point(-10, -10, -10), Point(10, 10, 10));
|
||||
|
||||
BoundingBox smallBb = BoundingBox(Point(-2, -2, -2), Point(2, 2, 2));
|
||||
|
||||
ASSERT_TRUE(bigBb.fitsIn(smallBb));
|
||||
}
|
||||
|
||||
TEST(BoundingBox, A_big_bb_should_not_fit_in_a_smaller)
|
||||
{
|
||||
BoundingBox bigBb = BoundingBox(Point(-10, -10, -10), Point(10, 10, 10));
|
||||
|
||||
BoundingBox smallBb = BoundingBox(Point(-2, -2, -2), Point(2, 2, 2));
|
||||
|
||||
ASSERT_FALSE(smallBb.fitsIn(bigBb));
|
||||
}
|
||||
@@ -130,3 +130,41 @@ TEST(ConeTest, Computing_the_normal_vector_on_a_cone)
|
||||
ASSERT_EQ(cone.doLocalNormalAt(HitPointss[i]), Normals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(ConeTest, The_bounding_box_of_a_cut_cone)
|
||||
{
|
||||
Cone t = Cone();
|
||||
BoundingBox b = BoundingBox(Point(-8, -5, -8), Point(8, 8, 8));
|
||||
t.minCap = -5;
|
||||
t.maxCap = 8;
|
||||
BoundingBox res = t.getBounds();
|
||||
|
||||
ASSERT_EQ(res.min, b.min);
|
||||
ASSERT_EQ(res.max, b.max);
|
||||
}
|
||||
|
||||
TEST(ConeTest, The_bounding_box_of_a_uncut_cone)
|
||||
{
|
||||
/* This one is tricky. Infinite size don't cope well with transformations */
|
||||
Cone t = Cone();
|
||||
BoundingBox res = t.getBounds();
|
||||
|
||||
ASSERT_FALSE(res.min.isRepresentable());
|
||||
ASSERT_FALSE(res.max.isRepresentable());
|
||||
}
|
||||
|
||||
TEST(ConeTest, An_uncut_cone_have_infinite_bounds)
|
||||
{
|
||||
Cone t = Cone();
|
||||
|
||||
ASSERT_FALSE(t.haveFiniteBounds());
|
||||
}
|
||||
|
||||
TEST(ConeTest, A_cut_cone_have_finite_bounds)
|
||||
{
|
||||
Cone t = Cone();
|
||||
t.minCap = -1;
|
||||
t.maxCap = 1;
|
||||
|
||||
ASSERT_TRUE(t.haveFiniteBounds());
|
||||
}
|
||||
@@ -116,7 +116,7 @@ TEST(CubeTest, The_normal_on_the_surface_of_a_cube)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Cube, The_bounding_box_of_a_cube)
|
||||
TEST(CubeTest, The_bounding_box_of_a_cube)
|
||||
{
|
||||
Cube t = Cube();
|
||||
BoundingBox b = BoundingBox(Point(-1, -1, -1), Point(1, 1, 1));
|
||||
@@ -125,4 +125,11 @@ TEST(Cube, The_bounding_box_of_a_cube)
|
||||
|
||||
ASSERT_EQ(res.min, b.min);
|
||||
ASSERT_EQ(res.max, b.max);
|
||||
}
|
||||
|
||||
TEST(CubeTest, A_cube_have_finite_bounds)
|
||||
{
|
||||
Cube t = Cube();
|
||||
|
||||
ASSERT_TRUE(t.haveFiniteBounds());
|
||||
}
|
||||
@@ -222,7 +222,7 @@ TEST(CylinderTest, The_normal_on_a_cylinder_end_cap)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CylinderTest, The_bounding_box_of_an_uncut_cylinder)
|
||||
TEST(CylinderTest, The_bounding_box_of_a_cut_cylinder)
|
||||
{
|
||||
Cylinder t = Cylinder();
|
||||
BoundingBox b = BoundingBox(Point(-1, -10000, -1), Point(1, 10000, 1));
|
||||
@@ -232,4 +232,30 @@ TEST(CylinderTest, The_bounding_box_of_an_uncut_cylinder)
|
||||
|
||||
ASSERT_EQ(res.min, b.min);
|
||||
ASSERT_EQ(res.max, b.max);
|
||||
}
|
||||
|
||||
TEST(CylinderTest, The_bounding_box_of_a_uncut_cylinder)
|
||||
{
|
||||
/* This one is tricky. Infinite size don't cope well with transformations */
|
||||
Cylinder t = Cylinder();
|
||||
BoundingBox res = t.getBounds();
|
||||
|
||||
ASSERT_FALSE(res.min.isRepresentable());
|
||||
ASSERT_FALSE(res.max.isRepresentable());
|
||||
}
|
||||
|
||||
TEST(CylinderTest, An_uncut_cylinder_have_infinite_bounds)
|
||||
{
|
||||
Cylinder t = Cylinder();
|
||||
|
||||
ASSERT_FALSE(t.haveFiniteBounds());
|
||||
}
|
||||
|
||||
TEST(CylinderTest, A_cut_cylinder_have_finite_bounds)
|
||||
{
|
||||
Cylinder t = Cylinder();
|
||||
t.minCap = -1;
|
||||
t.maxCap = 1;
|
||||
|
||||
ASSERT_TRUE(t.haveFiniteBounds());
|
||||
}
|
||||
@@ -66,7 +66,7 @@ TEST(GroupTest, Intersecting_a_ray_with_an_nonempty_group)
|
||||
EXPECT_EQ(xs[3].object, &s1);
|
||||
}
|
||||
|
||||
TEST(GroupTest, Intersecting_a_transformer_group)
|
||||
TEST(GroupTest, Intersecting_a_transformed_group)
|
||||
{
|
||||
Group g = Group();
|
||||
Sphere s = Sphere();
|
||||
@@ -79,4 +79,22 @@ TEST(GroupTest, Intersecting_a_transformer_group)
|
||||
Ray r = Ray(Point(10, 0, -50), Vector(0, 0, 1));
|
||||
Intersect xs = g.intersect(r);
|
||||
ASSERT_EQ(xs.count(), 2);
|
||||
}
|
||||
|
||||
TEST(GroupTest, Group_bounding_box)
|
||||
{
|
||||
Group g = Group();
|
||||
Sphere s = Sphere();
|
||||
|
||||
g.setTransform(scaling(2, 2, 2));
|
||||
s.setTransform(translation(5, 0, 0));
|
||||
|
||||
g.addObject(&s);
|
||||
|
||||
BoundingBox b = BoundingBox(Point(8, -2, -2), Point(12, 2, 2));
|
||||
|
||||
BoundingBox res = g.getBounds();
|
||||
|
||||
ASSERT_EQ(res.min, b.min);
|
||||
ASSERT_EQ(res.max, b.max);
|
||||
}
|
||||
@@ -68,4 +68,21 @@ TEST(PlaneTest, A_ray_intersecting_a_plane_from_below)
|
||||
ASSERT_EQ(xs.count(), 1);
|
||||
ASSERT_EQ(xs[0].t, 1);
|
||||
ASSERT_EQ(xs[0].object, &p);
|
||||
}
|
||||
|
||||
TEST(PlaneTest, The_bounding_box_of_a_plane)
|
||||
{
|
||||
Plane t = Plane();
|
||||
BoundingBox b = BoundingBox(Point(-8, -5, -8), Point(8, 8, 8));
|
||||
BoundingBox res = t.getBounds();
|
||||
|
||||
ASSERT_FALSE(res.min.isRepresentable());
|
||||
ASSERT_FALSE(res.max.isRepresentable());
|
||||
}
|
||||
|
||||
TEST(PlaneTest, A_plane_have_infinite__bounds)
|
||||
{
|
||||
Plane t = Plane();
|
||||
|
||||
ASSERT_FALSE(t.haveFiniteBounds());
|
||||
}
|
||||
@@ -218,4 +218,11 @@ TEST(SphereTest, The_bounding_box_of_a_sphere)
|
||||
|
||||
ASSERT_EQ(res.min, b.min);
|
||||
ASSERT_EQ(res.max, b.max);
|
||||
}
|
||||
|
||||
TEST(SphereTest, A_sphere_have_finite_bounds)
|
||||
{
|
||||
Sphere t = Sphere();
|
||||
|
||||
ASSERT_TRUE(t.haveFiniteBounds());
|
||||
}
|
||||
Reference in New Issue
Block a user