From b00bb75189756c1de21aeab4bf0a8238a7c4ab4e Mon Sep 17 00:00:00 2001 From: Godzil Date: Thu, 12 Mar 2020 00:11:26 +0000 Subject: [PATCH] Huge speed up by changing how Intersect are shared. --- source/include/cone.h | 2 +- source/include/csg.h | 4 ++-- source/include/cube.h | 2 +- source/include/cylinder.h | 2 +- source/include/group.h | 6 ++++-- source/include/objfile.h | 4 ++-- source/include/plane.h | 2 +- source/include/shape.h | 8 ++++---- source/include/sphere.h | 2 +- source/include/testshape.h | 2 +- source/include/triangle.h | 2 +- source/include/world.h | 2 +- source/shapes/cone.cpp | 14 +++++--------- source/shapes/csg.cpp | 21 +++++++-------------- source/shapes/cube.cpp | 10 +++------- source/shapes/cylinder.cpp | 12 ++++-------- source/shapes/group.cpp | 26 +++++--------------------- source/shapes/objfile.cpp | 8 ++++---- source/shapes/plane.cpp | 14 ++++++-------- source/shapes/shape.cpp | 4 ++-- source/shapes/sphere.cpp | 9 +++------ source/shapes/testshape.cpp | 3 +-- source/shapes/triangle.cpp | 14 +++++--------- source/world.cpp | 10 ++++++---- tests/ch5_test.cpp | 3 ++- tests/ch6_test.cpp | 3 ++- tests/cone_test.cpp | 7 ++++--- tests/csg_test.cpp | 8 ++++---- tests/cube_test.cpp | 4 ++-- tests/cylinder_test.cpp | 8 ++++---- tests/group_test.cpp | 6 +++--- tests/intersect_test.cpp | 2 +- tests/plane_test.cpp | 8 ++++---- tests/shape_test.cpp | 4 ++-- tests/smoothtriangle_test.cpp | 6 +++--- tests/sphere_test.cpp | 14 +++++++------- tests/triangle_test.cpp | 10 +++++----- tests/world_test.cpp | 3 ++- 38 files changed, 116 insertions(+), 153 deletions(-) diff --git a/source/include/cone.h b/source/include/cone.h index 412f0f0..2aa2911 100644 --- a/source/include/cone.h +++ b/source/include/cone.h @@ -17,7 +17,7 @@ class Cone : public Shape { protected: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); diff --git a/source/include/csg.h b/source/include/csg.h index 06c1396..5ff194f 100644 --- a/source/include/csg.h +++ b/source/include/csg.h @@ -28,7 +28,7 @@ protected: BoundingBox bounds; protected: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); BoundingBox getLocalBounds(); @@ -42,7 +42,7 @@ protected: public: CSG(OperationType operation, Shape *left, Shape *right); - Intersect intersect(Ray r); + void intersect(Ray &r, Intersect &xs); bool includes(Shape *b); diff --git a/source/include/cube.h b/source/include/cube.h index e63df50..5ce3255 100644 --- a/source/include/cube.h +++ b/source/include/cube.h @@ -19,7 +19,7 @@ class Cube : public Shape { protected: void checkAxis(double axeOrigin, double axeDirection, double *axeMin, double *axeMax); - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); diff --git a/source/include/cylinder.h b/source/include/cylinder.h index 46ad2e1..a5f8b0b 100644 --- a/source/include/cylinder.h +++ b/source/include/cylinder.h @@ -18,7 +18,7 @@ class Cylinder : public Shape { protected: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); diff --git a/source/include/group.h b/source/include/group.h index a816731..fb0cda0 100644 --- a/source/include/group.h +++ b/source/include/group.h @@ -28,7 +28,7 @@ private: char name[32 + 1]; protected: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); BoundingBox bounds; @@ -43,7 +43,7 @@ public: Shape *getObject(const int p) { return this->objectList[p]; }; Shape *getUnboxable(const int p) { return this->unboxableObjectList[p]; }; - Intersect intersect(Ray r); + void intersect(Ray &r, Intersect &xs); BoundingBox getLocalBounds(); BoundingBox getBounds(); @@ -59,6 +59,8 @@ public: void lock(); + void setBounds(BoundingBox &bb) { this->bounds | bb; }; + const char *getName() { return this->name; }; void dumpMe(FILE * fp); diff --git a/source/include/objfile.h b/source/include/objfile.h index e280729..fd42e7d 100644 --- a/source/include/objfile.h +++ b/source/include/objfile.h @@ -31,7 +31,7 @@ private: uint32_t vertexNormalCount; private: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); public: @@ -59,7 +59,7 @@ public: Point vertices(uint32_t i) { return *this->vertexList[i - 1]; }; Vector verticesNormal(uint32_t i) { return *this->vertexNormalList[i - 1]; }; Group *groups(const char *groupName); - Intersect intersect(Ray r); + void intersect(Ray &r, Intersect &xs); BoundingBox getLocalBounds(); BoundingBox getBounds(); diff --git a/source/include/plane.h b/source/include/plane.h index f5f5b60..cfdfae3 100644 --- a/source/include/plane.h +++ b/source/include/plane.h @@ -14,7 +14,7 @@ class Plane : public Shape { protected: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); public: diff --git a/source/include/shape.h b/source/include/shape.h index 6c1206c..3d3e7cd 100644 --- a/source/include/shape.h +++ b/source/include/shape.h @@ -44,7 +44,7 @@ protected: bool locked; protected: - virtual Intersect localIntersect(Ray r) = 0; + virtual void localIntersect(Ray r, Intersect &xs) = 0; virtual Tuple localNormalAt(Tuple point, Intersection *hit) = 0; public: @@ -62,7 +62,7 @@ public: ShapeType getType() { return this->type; }; - virtual Intersect intersect(Ray r); + virtual void intersect(Ray &r, Intersect &xs); Tuple normalAt(Tuple point, Intersection *hit = nullptr); /* Bounding box points are always world value */ @@ -92,8 +92,8 @@ public: void setTransform(Matrix transform); void setMaterial(Material material) { this->material = material; this->materialSet = true; }; - Ray transform(Ray r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); }; - Ray invTransform(Ray r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); }; + Ray transform(Ray &r) { return Ray(this->transformMatrix * r.origin, this->transformMatrix * r.direction); }; + Ray invTransform(Ray &r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); }; bool operator==(const Shape &b) const { return this->material == b.material && this->type == b.type && diff --git a/source/include/sphere.h b/source/include/sphere.h index 999ce86..722a791 100644 --- a/source/include/sphere.h +++ b/source/include/sphere.h @@ -18,7 +18,7 @@ class Sphere : public Shape { protected: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); public: diff --git a/source/include/testshape.h b/source/include/testshape.h index 42598a9..dced723 100644 --- a/source/include/testshape.h +++ b/source/include/testshape.h @@ -16,7 +16,7 @@ class TestShape : public Shape { private: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); public: diff --git a/source/include/triangle.h b/source/include/triangle.h index ff642b9..a0d05b3 100644 --- a/source/include/triangle.h +++ b/source/include/triangle.h @@ -15,7 +15,7 @@ class Triangle : public Shape { protected: - Intersect localIntersect(Ray r); + void localIntersect(Ray r, Intersect &xs); Tuple localNormalAt(Tuple point, Intersection *hit = nullptr); public: diff --git a/source/include/world.h b/source/include/world.h index ae186bd..b5062d3 100644 --- a/source/include/world.h +++ b/source/include/world.h @@ -63,7 +63,7 @@ public: Colour reflectColour(Computation comps, uint32_t depthCount = 4); Colour refractedColour(Computation comps, uint32_t depthCount = 4); - Intersect intersect(Ray r); + void intersect(Ray &r, Intersect &xs); void finalise(WorldOptimiser &opt); diff --git a/source/shapes/cone.cpp b/source/shapes/cone.cpp index 3f755c6..0f28313 100644 --- a/source/shapes/cone.cpp +++ b/source/shapes/cone.cpp @@ -51,10 +51,8 @@ void Cone::intersectCaps(Ray r, Intersect &xs) } } -Intersect Cone::localIntersect(Ray r) +void Cone::localIntersect(Ray r, Intersect &xs) { - Intersect ret; - double A = (r.direction.x * r.direction.x) - (r.direction.y * r.direction.y) + (r.direction.z * r.direction.z); @@ -70,7 +68,7 @@ Intersect Cone::localIntersect(Ray r) if ((fabs(A) <= getEpsilon()) && (fabs(B) >= getEpsilon())) { double t = -C / (2*B); - ret.add(Intersection(t, this)); + xs.add(Intersection(t, this)); } else if (fabs(A) >= getEpsilon()) { @@ -83,20 +81,18 @@ Intersect Cone::localIntersect(Ray r) double y0 = r.origin.y + t0 * r.direction.y; if ((this->minCap < y0) && (y0 < this->maxCap)) { - ret.add(Intersection(t0, this)); + xs.add(Intersection(t0, this)); } double y1 = r.origin.y + t1 * r.direction.y; if ((this->minCap < y1) && (y1 < this->maxCap)) { - ret.add(Intersection(t1, this)); + xs.add(Intersection(t1, this)); } } } - this->intersectCaps(r, ret); - - return ret; + this->intersectCaps(r, xs); } Tuple Cone::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/csg.cpp b/source/shapes/csg.cpp index 2e5b3e8..76dc2ab 100644 --- a/source/shapes/csg.cpp +++ b/source/shapes/csg.cpp @@ -24,31 +24,24 @@ CSG::CSG(OperationType operation, Shape *left, Shape *right) : Shape(Shape::CSG) this->bounds | this->right->getBounds(); } -Intersect CSG::localIntersect(Ray r) +void CSG::localIntersect(Ray r, Intersect &xs) { - return this->intersect(r); + this->intersect(r, xs); } -Intersect CSG::intersect(Ray r) +void CSG::intersect(Ray &r, Intersect &xs) { int i; - Intersect ret = Intersect(); + Intersect tmp = Intersect(); if (this->bounds.intesectMe(r)) { - Intersect leftxs = this->left->intersect(r); - Intersect rightxs = this->right->intersect(r); + this->left->intersect(r, tmp); + this->right->intersect(r, tmp); - for (i = 0 ; i < rightxs.count() ; i++) - { - leftxs.add(rightxs[i]); - } - - this->filterIntersections(leftxs, ret); + this->filterIntersections(tmp, xs); } - - return ret; } Tuple CSG::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/cube.cpp b/source/shapes/cube.cpp index a1847e8..9926a45 100644 --- a/source/shapes/cube.cpp +++ b/source/shapes/cube.cpp @@ -36,10 +36,8 @@ void Cube::checkAxis(double axeOrigin, double axeDirection, double *axeMin, doub } } -Intersect Cube::localIntersect(Ray r) +void Cube::localIntersect(Ray r, Intersect &xs) { - Intersect ret; - double xtMin, xtMax, ytMin, ytMax, ztMin, ztMax; double tMin, tMax; @@ -52,11 +50,9 @@ Intersect Cube::localIntersect(Ray r) if (tMin <= tMax) { - ret.add(Intersection(tMin, this)); - ret.add(Intersection(tMax, this)); + xs.add(Intersection(tMin, this)); + xs.add(Intersection(tMax, this)); } - - return ret; } Tuple Cube::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/cylinder.cpp b/source/shapes/cylinder.cpp index 3676072..3e22600 100644 --- a/source/shapes/cylinder.cpp +++ b/source/shapes/cylinder.cpp @@ -51,10 +51,8 @@ void Cylinder::intersectCaps(Ray r, Intersect &xs) } } -Intersect Cylinder::localIntersect(Ray r) +void Cylinder::localIntersect(Ray r, Intersect &xs) { - Intersect ret; - double A = r.direction.x * r.direction.x + r.direction.z * r.direction.z; /* Ray is parallel to the Y axis */ @@ -74,20 +72,18 @@ Intersect Cylinder::localIntersect(Ray r) double y0 = r.origin.y + t0 * r.direction.y; if ((this->minCap < y0) && (y0 < this->maxCap)) { - ret.add(Intersection(t0, this)); + xs.add(Intersection(t0, this)); } double y1 = r.origin.y + t1 * r.direction.y; if ((this->minCap < y1) && (y1 < this->maxCap)) { - ret.add(Intersection(t1, this)); + xs.add(Intersection(t1, this)); } } } - this->intersectCaps(r, ret); - - return ret; + this->intersectCaps(r, xs); } Tuple Cylinder::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/group.cpp b/source/shapes/group.cpp index ce0e5a3..6e04477 100644 --- a/source/shapes/group.cpp +++ b/source/shapes/group.cpp @@ -36,9 +36,8 @@ Group::Group(const char *name) : Shape(Shape::GROUP) } } -Intersect Group::intersect(Ray r) +void Group::intersect(Ray &r, Intersect &xs) { - Intersect ret; int i, j; if (this->objectCount > 0) { @@ -46,14 +45,7 @@ Intersect Group::intersect(Ray r) { for (i = 0 ; i < this->objectCount ; i++) { - Intersect xs = this->objectList[i]->intersect(r); - if (xs.count() > 0) - { - for (j = 0 ; j < xs.count() ; j++) - { - ret.add(xs[j]); - } - } + this->objectList[i]->intersect(r, xs); } } } @@ -63,17 +55,9 @@ Intersect Group::intersect(Ray r) { for(i = 0; i < this->unboxableObjectCount; i++) { - Intersect xs = this->unboxableObjectList[i]->intersect(r); - if (xs.count() > 0) - { - for(j = 0; j < xs.count(); j++) - { - ret.add(xs[j]); - } - } + this->unboxableObjectList[i]->intersect(r, xs); } } - return ret; } bool Group::includes(Shape *b) @@ -104,9 +88,9 @@ bool Group::includes(Shape *b) return false; } -Intersect Group::localIntersect(Ray r) +void Group::localIntersect(Ray r, Intersect &xs) { - return Intersect(); + this->intersect(r, xs); } Tuple Group::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/objfile.cpp b/source/shapes/objfile.cpp index 39d46ce..bc8254a 100644 --- a/source/shapes/objfile.cpp +++ b/source/shapes/objfile.cpp @@ -160,9 +160,9 @@ Group *OBJFile::groups(const char *groupName) return nullptr; } -Intersect OBJFile::intersect(Ray r) +void OBJFile::intersect(Ray &r, Intersect &xs) { - return this->baseGroup->intersect(r); + this->baseGroup->intersect(r, xs); } bool OBJFile::includes(Shape *b) @@ -170,9 +170,9 @@ bool OBJFile::includes(Shape *b) return this->baseGroup->includes(b); } -Intersect OBJFile::localIntersect(Ray r) +void OBJFile::localIntersect(Ray r, Intersect &xs) { - return Intersect(); + this->intersect(r, xs); } Tuple OBJFile::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/plane.cpp b/source/shapes/plane.cpp index bf65cf2..1e8a17f 100644 --- a/source/shapes/plane.cpp +++ b/source/shapes/plane.cpp @@ -12,22 +12,20 @@ #include #include -Intersect Plane::localIntersect(Ray r) +void Plane::localIntersect(Ray r, Intersect &xs) { double t; - Intersect ret = Intersect(); if (fabs(r.direction.y) < getEpsilon()) { /* With a direction == 0, the ray can't intersect the plane */ - return ret; } + else + { + t = -r.origin.y / r.direction.y; - t = -r.origin.y / r.direction.y; - - ret.add(Intersection(t, this)); - - return ret; + xs.add(Intersection(t, this)); + } } Tuple Plane::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/shape.cpp b/source/shapes/shape.cpp index 6e39a0b..d071004 100644 --- a/source/shapes/shape.cpp +++ b/source/shapes/shape.cpp @@ -25,9 +25,9 @@ Shape::Shape(ShapeType type) this->updateTransform(); } -Intersect Shape::intersect(Ray r) +void Shape::intersect(Ray &r, Intersect &xs) { - return this->localIntersect(this->invTransform(r)); + this->localIntersect(this->invTransform(r), xs); }; Tuple Shape::normalToWorld(Tuple normalVector) diff --git a/source/shapes/sphere.cpp b/source/shapes/sphere.cpp index e141d2a..29edfbb 100644 --- a/source/shapes/sphere.cpp +++ b/source/shapes/sphere.cpp @@ -13,9 +13,8 @@ #include #include -Intersect Sphere::localIntersect(Ray r) +void Sphere::localIntersect(Ray r, Intersect &xs) { - Intersect ret; double a, b, c, discriminant; Tuple sphere_to_ray = r.origin - Point(0, 0, 0); @@ -28,11 +27,9 @@ Intersect Sphere::localIntersect(Ray r) if (discriminant >= 0) { - ret.add(Intersection((-b - sqrt(discriminant)) / (2 * a), this)); - ret.add(Intersection((-b + sqrt(discriminant)) / (2 * a), this)); + xs.add(Intersection((-b - sqrt(discriminant)) / (2 * a), this)); + xs.add(Intersection((-b + sqrt(discriminant)) / (2 * a), this)); } - - return ret; } Tuple Sphere::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/testshape.cpp b/source/shapes/testshape.cpp index 23210d2..43e4d05 100644 --- a/source/shapes/testshape.cpp +++ b/source/shapes/testshape.cpp @@ -13,10 +13,9 @@ TestShape::TestShape() : localRay(Point(0, 0, 0), Vector(0, 0, 0)) { } -Intersect TestShape::localIntersect(Ray r) +void TestShape::localIntersect(Ray r, Intersect &xs) { this->localRay = r; - return Intersect(); } Tuple TestShape::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/shapes/triangle.cpp b/source/shapes/triangle.cpp index 8b3195e..1302e14 100644 --- a/source/shapes/triangle.cpp +++ b/source/shapes/triangle.cpp @@ -21,15 +21,13 @@ Triangle::Triangle(Point p1, Point p2, Point p3) : Shape(Shape::TRIANGLE), p1(p1 this->normal = e2.cross(e1).normalise(); } -Intersect Triangle::localIntersect(Ray r) +void Triangle::localIntersect(Ray r, Intersect &xs) { - Intersect ret; - Tuple dirCrossE2 = r.direction.cross(this->e2); double determinant = this->e1.dot(dirCrossE2); if (fabs(determinant) < getEpsilon()) { - return ret; + return; } double f = 1.0 / determinant; @@ -40,18 +38,16 @@ Intersect Triangle::localIntersect(Ray r) if ((u < 0) || (u > 1)) { - return ret; + return; } if ((v < 0) || ((u + v) > 1)) { - return ret; + return; } double t = f * this->e2.dot(originCrossE1); - ret.add(Intersection(t, this, u, v)); - - return ret; + xs.add(Intersection(t, this, u, v)); } Tuple Triangle::localNormalAt(Tuple point, Intersection *hit) diff --git a/source/world.cpp b/source/world.cpp index e6dbd88..7c805a0 100644 --- a/source/world.cpp +++ b/source/world.cpp @@ -75,9 +75,9 @@ bool World::objectIsIn(Shape &s) return this->worldGroup.includes(&s); } -Intersect World::intersect(Ray r) +void World::intersect(Ray &r, Intersect &xs) { - return this->worldGroup.intersect(r); + this->worldGroup.intersect(r, xs); } Tuple World::shadeHit(Computation comps, uint32_t depthCount) @@ -108,7 +108,8 @@ Tuple World::shadeHit(Computation comps, uint32_t depthCount) Tuple World::colourAt(Ray r, uint32_t depthCount) { - Intersect allHits = this->intersect(r); + Intersect allHits; + this->intersect(r, allHits); Intersection hit = allHits.hit(); stats.setMaxDepth(depthCount); @@ -131,7 +132,8 @@ bool World::isShadowed(Tuple point, Tuple lightPosition) Ray r = Ray(point, direction); stats.addLightRay(); - Intersect xs = this->intersect(r); + Intersect xs; + this->intersect(r, xs); int i; for(i = 0; i < xs.count(); i++) diff --git a/tests/ch5_test.cpp b/tests/ch5_test.cpp index 2b7e0bc..babe818 100644 --- a/tests/ch5_test.cpp +++ b/tests/ch5_test.cpp @@ -32,7 +32,8 @@ int main() double worldX = -(wallSize / 2) + pixelSize * x; Point position = Point(worldX, worldY, wallDistance); Ray r = Ray(cameraOrigin, (position - cameraOrigin).normalise()); - Intersect xs = s.intersect(r); + Intersect xs; + s.intersect(r, xs); if (!xs.hit().nothing()) { diff --git a/tests/ch6_test.cpp b/tests/ch6_test.cpp index 6a822a2..87e4eb1 100644 --- a/tests/ch6_test.cpp +++ b/tests/ch6_test.cpp @@ -36,7 +36,8 @@ int main() double worldX = -(wallSize / 2) + pixelSize * x; Point position = Point(worldX, worldY, wallDistance); Ray r = Ray(cameraOrigin, (position - cameraOrigin).normalise()); - Intersect xs = s.intersect(r); + Intersect xs; + s.intersect(r, xs); Intersection hit = xs.hit(); diff --git a/tests/cone_test.cpp b/tests/cone_test.cpp index 0a74989..b2418db 100644 --- a/tests/cone_test.cpp +++ b/tests/cone_test.cpp @@ -46,7 +46,7 @@ TEST(ConeTest, Intersecting_a_cone_with_a_ray) Tuple direction = Directions[i].normalise(); Ray r = Ray(Origins[i], direction); - Intersect xs = cone.intersect(r); + Intersect xs; cone.intersect(r, xs); /* Temporary lower the precision */ set_equal_precision(0.00001); @@ -64,7 +64,7 @@ TEST(ConeTest, Intersecting_a_cone_with_a_ray_parall_to_one_of_its_halves) Cone cone = Cone(); Tuple direction = Vector(0, 1, 1).normalise(); Ray r = Ray(Point(0, 0, -1), direction); - Intersect xs = cone.intersect(r); + Intersect xs; cone.intersect(r, xs); ASSERT_EQ(xs.count(), 1); /* Temporary lower the precision */ @@ -102,7 +102,8 @@ TEST(ConeTest, Intersecting_a_cone_end_cap) Tuple direction = Directions[i].normalise(); Ray r = Ray(Origins[i], direction); - Intersect xs = cone.intersect(r); + Intersect xs; + cone.intersect(r, xs); ASSERT_EQ(xs.count(), Counts[i]); } diff --git a/tests/csg_test.cpp b/tests/csg_test.cpp index 308430a..e3a867a 100644 --- a/tests/csg_test.cpp +++ b/tests/csg_test.cpp @@ -18,8 +18,8 @@ class CSGTest : public CSG { public: - Intersect doLocalIntersect(Ray r) { - return this->localIntersect(r); + void doLocalIntersect(Ray r, Intersect &xs) { + return this->localIntersect(r, xs); }; Tuple doLocalNormalAt(Tuple point, Intersection *hit = nullptr) { return this->localNormalAt(point, hit); @@ -202,7 +202,7 @@ TEST(CSGTest, A_ray_misses_a_csg_object) CSGTest c = CSGTest(CSG::UNION, &s1, &s2); Ray r = Ray(Point(0, 2, -5), Vector(0, 0, 1)); - Intersect xs = c.doLocalIntersect(r); + Intersect xs; c.doLocalIntersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -217,7 +217,7 @@ TEST(CSGTest, A_ray_hits_a_csg_object) CSGTest c = CSGTest(CSG::UNION, &s1, &s2); Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1)); - Intersect xs = c.doLocalIntersect(r); + Intersect xs; c.doLocalIntersect(r, xs); ASSERT_EQ(xs.count(), 2); ASSERT_TRUE(double_equal(xs[0].t, 4)); diff --git a/tests/cube_test.cpp b/tests/cube_test.cpp index 4a74803..141c8d0 100644 --- a/tests/cube_test.cpp +++ b/tests/cube_test.cpp @@ -43,7 +43,7 @@ TEST(CubeTest, A_ray_intersects_a_cube) for(i = 0; i < 7; i++) { Ray r = Ray(Origins[i], Directions[i]); - Intersect xs = c.intersect(r); + Intersect xs; c.intersect(r, xs); ASSERT_EQ(xs.count(), 2); EXPECT_EQ(xs[0].t, t1[i]); @@ -77,7 +77,7 @@ TEST(CubeTest, A_ray_miss_a_cube) for(i = 0; i < 6; i++) { Ray r = Ray(Origins[i], Directions[i]); - Intersect xs = c.intersect(r); + Intersect xs; c.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } diff --git a/tests/cylinder_test.cpp b/tests/cylinder_test.cpp index 81d85e7..fdbc87e 100644 --- a/tests/cylinder_test.cpp +++ b/tests/cylinder_test.cpp @@ -34,7 +34,7 @@ TEST(CylinderTest, A_ray_miss_a_cylinder) Tuple direction = Directions[i].normalise(); Ray r = Ray(Origins[i], direction); - Intersect xs = cyl.intersect(r); + Intersect xs; cyl.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -65,7 +65,7 @@ TEST(CylinderTest, A_ray_hit_a_cylinder) Tuple direction = Directions[i].normalise(); Ray r = Ray(Origins[i], direction); - Intersect xs = cyl.intersect(r); + Intersect xs; cyl.intersect(r, xs); /* Temporary lower the precision */ set_equal_precision(0.00001); @@ -142,7 +142,7 @@ TEST(CylinderTest, Intersecting_a_constrained_cylinder) Tuple direction = Directions[i].normalise(); Ray r = Ray(Origins[i], direction); - Intersect xs = cyl.intersect(r); + Intersect xs; cyl.intersect(r, xs); ASSERT_EQ(xs.count(), Counts[i]); } @@ -184,7 +184,7 @@ TEST(CylinderTest, Intersecting_the_caps_of_a_close_cylinder) Tuple direction = Directions[i].normalise(); Ray r = Ray(Origins[i], direction); - Intersect xs = cyl.intersect(r); + Intersect xs; cyl.intersect(r, xs); ASSERT_EQ(xs.count(), Counts[i]); } } diff --git a/tests/group_test.cpp b/tests/group_test.cpp index 9642939..38fa26d 100644 --- a/tests/group_test.cpp +++ b/tests/group_test.cpp @@ -39,7 +39,7 @@ TEST(GroupTest, Intersecting_a_ray_with_an_empty_group) { Group g = Group(); Ray r = Ray(Point(0, 0, 0), Vector(0, 0, 1)); - Intersect xs = g.intersect(r); + Intersect xs; g.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -58,7 +58,7 @@ TEST(GroupTest, Intersecting_a_ray_with_an_nonempty_group) g.addObject(&s3); Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1)); - Intersect xs = g.intersect(r); + Intersect xs; g.intersect(r, xs); ASSERT_EQ(xs.count(), 4); EXPECT_EQ(xs[0].object, &s2); EXPECT_EQ(xs[1].object, &s2); @@ -77,7 +77,7 @@ TEST(GroupTest, Intersecting_a_transformed_group) g.addObject(&s); Ray r = Ray(Point(10, 0, -50), Vector(0, 0, 1)); - Intersect xs = g.intersect(r); + Intersect xs; g.intersect(r, xs); ASSERT_EQ(xs.count(), 2); } diff --git a/tests/intersect_test.cpp b/tests/intersect_test.cpp index 989bb4e..c3a27a5 100644 --- a/tests/intersect_test.cpp +++ b/tests/intersect_test.cpp @@ -57,7 +57,7 @@ TEST(IntersectTest, Intersect_sets_the_object_on_the_intersection) { Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1)); Sphere s = Sphere(); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(xs.count(), 2); ASSERT_EQ(xs[0].object, (Shape *)&s); diff --git a/tests/plane_test.cpp b/tests/plane_test.cpp index 8d943d8..4de950e 100644 --- a/tests/plane_test.cpp +++ b/tests/plane_test.cpp @@ -31,7 +31,7 @@ TEST(PlaneTest, Intersect_with_a_ray_parallel_to_the_plane) Plane p = Plane(); Ray r = Ray(Point(0, 10, 0), Vector(0, 0, 1)); - Intersect xs = p.intersect(r); + Intersect xs; p.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -41,7 +41,7 @@ TEST(PlaneTest, Intersect_with_a_coplanar_ray) Plane p = Plane(); Ray r = Ray(Point(0, 0, 0), Vector(0, 0, 1)); - Intersect xs = p.intersect(r); + Intersect xs; p.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -51,7 +51,7 @@ TEST(PlaneTest, A_ray_intersecting_a_plane_from_above) Plane p = Plane(); Ray r = Ray(Point(0, 1, 0), Vector(0, -1, 0)); - Intersect xs = p.intersect(r); + Intersect xs; p.intersect(r, xs); ASSERT_EQ(xs.count(), 1); ASSERT_EQ(xs[0].t, 1); @@ -63,7 +63,7 @@ TEST(PlaneTest, A_ray_intersecting_a_plane_from_below) Plane p = Plane(); Ray r = Ray(Point(0, -1, 0), Vector(0, 1, 0)); - Intersect xs = p.intersect(r); + Intersect xs; p.intersect(r, xs); ASSERT_EQ(xs.count(), 1); ASSERT_EQ(xs[0].t, 1); diff --git a/tests/shape_test.cpp b/tests/shape_test.cpp index 1f53bc1..c9399c7 100644 --- a/tests/shape_test.cpp +++ b/tests/shape_test.cpp @@ -53,7 +53,7 @@ TEST(ShapeTest, Intersecting_a_scaled_shape_with_a_ray) TestShape s = TestShape(); s.setTransform(scaling(2, 2, 2)); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(s.localRay.origin, Point(0, 0, -2.5)); ASSERT_EQ(s.localRay.direction, Vector(0, 0, 0.5)); @@ -65,7 +65,7 @@ TEST(ShapeTest, Intersecting_a_translated_shape_with_a_ray) TestShape s = TestShape(); s.setTransform(translation(5, 0, 0)); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(s.localRay.origin, Point(-5, 0, -5)); ASSERT_EQ(s.localRay.direction, Vector(0, 0, 1)); diff --git a/tests/smoothtriangle_test.cpp b/tests/smoothtriangle_test.cpp index f81ab15..bc814fa 100644 --- a/tests/smoothtriangle_test.cpp +++ b/tests/smoothtriangle_test.cpp @@ -14,9 +14,9 @@ class SmoothTriTest : public SmoothTriangle { public: SmoothTriTest(Point p1, Point p2, Point p3, Vector n1, Vector n2, Vector n3) : SmoothTriangle(p1, p2, p3, n1, n2, n3) {}; - Intersect doLocalIntersect(Ray ray) + void doLocalIntersect(Ray ray, Intersect &xs) { - return this->localIntersect(ray); + this->localIntersect(ray, xs); }; Tuple doLocalNormalAt(Tuple point, Intersection *hit) @@ -48,7 +48,7 @@ TEST(SmoothTriangleTest, An_intersection_with_a_smooth_triangle_stores_u_v) { Ray r = Ray(Point(-0.2, 0.3, -2), Vector(0, 0, 1)); - Intersect xs = tri.doLocalIntersect(r); + Intersect xs; tri.doLocalIntersect(r, xs); ASSERT_TRUE(double_equal(xs[0].u, 0.45)); ASSERT_TRUE(double_equal(xs[0].v, 0.25)); diff --git a/tests/sphere_test.cpp b/tests/sphere_test.cpp index a5ee786..6ec4861 100644 --- a/tests/sphere_test.cpp +++ b/tests/sphere_test.cpp @@ -17,7 +17,7 @@ TEST(SphereTest, A_ray_intersect_a_sphere_at_two_points) { Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1)); Sphere s = Sphere(); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(xs.count(), 2); ASSERT_EQ(xs[0].t, 4.0); @@ -28,7 +28,7 @@ TEST(SphereTest, A_ray_intersect_a_sphere_at_a_tangent) { Ray r = Ray(Point(0, 1, -5), Vector(0, 0, 1)); Sphere s = Sphere(); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(xs.count(), 2); ASSERT_EQ(xs[0].t, 5.0); @@ -39,7 +39,7 @@ TEST(SphereTest, A_ray_miss_a_sphere) { Ray r = Ray(Point(0, 2, -5), Vector(0, 0, 1)); Sphere s = Sphere(); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -48,7 +48,7 @@ TEST(SphereTest, A_ray_originate_inside_a_sphere) { Ray r = Ray(Point(0, 0, 0), Vector(0, 0, 1)); Sphere s = Sphere(); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(xs.count(), 2); ASSERT_EQ(xs[0].t, -1.0); @@ -59,7 +59,7 @@ TEST(SphereTest, A_sphere_is_behind_a_ray) { Ray r = Ray(Point(0, 0, 5), Vector(0, 0, 1)); Sphere s = Sphere(); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(xs.count(), 2); ASSERT_EQ(xs[0].t, -6.0); @@ -89,7 +89,7 @@ TEST(SphereTest, Intersecting_a_scaled_sphere_with_a_ray) s.setTransform(scaling(2, 2, 2)); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(xs.count(), 2); ASSERT_EQ(xs[0].t, 3.0); @@ -103,7 +103,7 @@ TEST(SphereTest, Intersecting_a_translated_sphere_with_a_ray) s.setTransform(translation(5, 0, 0)); - Intersect xs = s.intersect(r); + Intersect xs; s.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } diff --git a/tests/triangle_test.cpp b/tests/triangle_test.cpp index e54f427..8368199 100644 --- a/tests/triangle_test.cpp +++ b/tests/triangle_test.cpp @@ -44,7 +44,7 @@ TEST(TriangleTest, Intersecting_a_ray_parallel_to_the_triangle) Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0)); Ray r = Ray(Point(0, -1, -2), Vector(0, 1, 0)); - Intersect xs = t.intersect(r); + Intersect xs; t.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -54,7 +54,7 @@ TEST(TriangleTest, A_ray_miss_the_p1_p3_edge) Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0)); Ray r = Ray(Point(1, 1, -2), Vector(0, 0, 1)); - Intersect xs = t.intersect(r); + Intersect xs; t.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -64,7 +64,7 @@ TEST(TriangleTest, A_ray_miss_the_p1_p2_edge) Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0)); Ray r = Ray(Point(-1, 1, -2), Vector(0, 0, 1)); - Intersect xs = t.intersect(r); + Intersect xs; t.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -74,7 +74,7 @@ TEST(TriangleTest, A_ray_miss_the_p2_p3_edge) Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0)); Ray r = Ray(Point(0, -1, -2), Vector(0, 0, 1)); - Intersect xs = t.intersect(r); + Intersect xs; t.intersect(r, xs); ASSERT_EQ(xs.count(), 0); } @@ -84,7 +84,7 @@ TEST(TriangleTest, A_ray_strikes_a_triangle) Triangle t = Triangle(Point(0, 1, 0), Point(-1, 0, 0), Point(1, 0, 0)); Ray r = Ray(Point(0, .5, -2), Vector(0, 0, 1)); - Intersect xs = t.intersect(r); + Intersect xs; t.intersect(r, xs); ASSERT_EQ(xs.count(), 1); EXPECT_EQ(xs[0].t, 2); diff --git a/tests/world_test.cpp b/tests/world_test.cpp index 07ce64d..340df9d 100644 --- a/tests/world_test.cpp +++ b/tests/world_test.cpp @@ -54,7 +54,8 @@ TEST(WorldTest, Intersect_a_world_with_a_ray) World w = DefaultWorld(); Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1)); - Intersect xs = w.intersect(r); + Intersect xs; + w.intersect(r, xs); ASSERT_EQ(xs.count(), 4); ASSERT_EQ(xs[0].t, 4);