Huge speed up by changing how Intersect are shared.
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
class Cone : public Shape {
|
class Cone : public Shape {
|
||||||
protected:
|
protected:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ protected:
|
|||||||
BoundingBox bounds;
|
BoundingBox bounds;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
BoundingBox getLocalBounds();
|
BoundingBox getLocalBounds();
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
CSG(OperationType operation, Shape *left, Shape *right);
|
CSG(OperationType operation, Shape *left, Shape *right);
|
||||||
|
|
||||||
Intersect intersect(Ray r);
|
void intersect(Ray &r, Intersect &xs);
|
||||||
|
|
||||||
bool includes(Shape *b);
|
bool includes(Shape *b);
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Cube : public Shape {
|
|||||||
protected:
|
protected:
|
||||||
void checkAxis(double axeOrigin, double axeDirection, double *axeMin, double *axeMax);
|
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);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
class Cylinder : public Shape {
|
class Cylinder : public Shape {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
|
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ private:
|
|||||||
char name[32 + 1];
|
char name[32 + 1];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
BoundingBox bounds;
|
BoundingBox bounds;
|
||||||
@@ -43,7 +43,7 @@ public:
|
|||||||
Shape *getObject(const int p) { return this->objectList[p]; };
|
Shape *getObject(const int p) { return this->objectList[p]; };
|
||||||
Shape *getUnboxable(const int p) { return this->unboxableObjectList[p]; };
|
Shape *getUnboxable(const int p) { return this->unboxableObjectList[p]; };
|
||||||
|
|
||||||
Intersect intersect(Ray r);
|
void intersect(Ray &r, Intersect &xs);
|
||||||
BoundingBox getLocalBounds();
|
BoundingBox getLocalBounds();
|
||||||
BoundingBox getBounds();
|
BoundingBox getBounds();
|
||||||
|
|
||||||
@@ -59,6 +59,8 @@ public:
|
|||||||
|
|
||||||
void lock();
|
void lock();
|
||||||
|
|
||||||
|
void setBounds(BoundingBox &bb) { this->bounds | bb; };
|
||||||
|
|
||||||
const char *getName() { return this->name; };
|
const char *getName() { return this->name; };
|
||||||
|
|
||||||
void dumpMe(FILE * fp);
|
void dumpMe(FILE * fp);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ private:
|
|||||||
uint32_t vertexNormalCount;
|
uint32_t vertexNormalCount;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -59,7 +59,7 @@ public:
|
|||||||
Point vertices(uint32_t i) { return *this->vertexList[i - 1]; };
|
Point vertices(uint32_t i) { return *this->vertexList[i - 1]; };
|
||||||
Vector verticesNormal(uint32_t i) { return *this->vertexNormalList[i - 1]; };
|
Vector verticesNormal(uint32_t i) { return *this->vertexNormalList[i - 1]; };
|
||||||
Group *groups(const char *groupName);
|
Group *groups(const char *groupName);
|
||||||
Intersect intersect(Ray r);
|
void intersect(Ray &r, Intersect &xs);
|
||||||
BoundingBox getLocalBounds();
|
BoundingBox getLocalBounds();
|
||||||
BoundingBox getBounds();
|
BoundingBox getBounds();
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
class Plane : public Shape
|
class Plane : public Shape
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ protected:
|
|||||||
bool locked;
|
bool locked;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Intersect localIntersect(Ray r) = 0;
|
virtual void localIntersect(Ray r, Intersect &xs) = 0;
|
||||||
virtual Tuple localNormalAt(Tuple point, Intersection *hit) = 0;
|
virtual Tuple localNormalAt(Tuple point, Intersection *hit) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
|
|
||||||
ShapeType getType() { return this->type; };
|
ShapeType getType() { return this->type; };
|
||||||
|
|
||||||
virtual Intersect intersect(Ray r);
|
virtual void intersect(Ray &r, Intersect &xs);
|
||||||
Tuple normalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple normalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
/* Bounding box points are always world value */
|
/* Bounding box points are always world value */
|
||||||
@@ -92,8 +92,8 @@ public:
|
|||||||
|
|
||||||
void setTransform(Matrix transform);
|
void setTransform(Matrix transform);
|
||||||
void setMaterial(Material material) { this->material = material; this->materialSet = true; };
|
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 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 invTransform(Ray &r) { return Ray(this->inverseTransform * r.origin, this->inverseTransform * r.direction); };
|
||||||
|
|
||||||
bool operator==(const Shape &b) const { return this->material == b.material &&
|
bool operator==(const Shape &b) const { return this->material == b.material &&
|
||||||
this->type == b.type &&
|
this->type == b.type &&
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
class Sphere : public Shape
|
class Sphere : public Shape
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
class TestShape : public Shape
|
class TestShape : public Shape
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
class Triangle : public Shape
|
class Triangle : public Shape
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Intersect localIntersect(Ray r);
|
void localIntersect(Ray r, Intersect &xs);
|
||||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public:
|
|||||||
Colour reflectColour(Computation comps, uint32_t depthCount = 4);
|
Colour reflectColour(Computation comps, uint32_t depthCount = 4);
|
||||||
Colour refractedColour(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);
|
void finalise(WorldOptimiser &opt);
|
||||||
|
|
||||||
|
|||||||
@@ -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) -
|
double A = (r.direction.x * r.direction.x) -
|
||||||
(r.direction.y * r.direction.y) +
|
(r.direction.y * r.direction.y) +
|
||||||
(r.direction.z * r.direction.z);
|
(r.direction.z * r.direction.z);
|
||||||
@@ -70,7 +68,7 @@ Intersect Cone::localIntersect(Ray r)
|
|||||||
if ((fabs(A) <= getEpsilon()) && (fabs(B) >= getEpsilon()))
|
if ((fabs(A) <= getEpsilon()) && (fabs(B) >= getEpsilon()))
|
||||||
{
|
{
|
||||||
double t = -C / (2*B);
|
double t = -C / (2*B);
|
||||||
ret.add(Intersection(t, this));
|
xs.add(Intersection(t, this));
|
||||||
}
|
}
|
||||||
else if (fabs(A) >= getEpsilon())
|
else if (fabs(A) >= getEpsilon())
|
||||||
{
|
{
|
||||||
@@ -83,20 +81,18 @@ Intersect Cone::localIntersect(Ray r)
|
|||||||
double y0 = r.origin.y + t0 * r.direction.y;
|
double y0 = r.origin.y + t0 * r.direction.y;
|
||||||
if ((this->minCap < y0) && (y0 < this->maxCap))
|
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;
|
double y1 = r.origin.y + t1 * r.direction.y;
|
||||||
if ((this->minCap < y1) && (y1 < this->maxCap))
|
if ((this->minCap < y1) && (y1 < this->maxCap))
|
||||||
{
|
{
|
||||||
ret.add(Intersection(t1, this));
|
xs.add(Intersection(t1, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->intersectCaps(r, ret);
|
this->intersectCaps(r, xs);
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple Cone::localNormalAt(Tuple point, Intersection *hit)
|
Tuple Cone::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -24,31 +24,24 @@ CSG::CSG(OperationType operation, Shape *left, Shape *right) : Shape(Shape::CSG)
|
|||||||
this->bounds | this->right->getBounds();
|
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;
|
int i;
|
||||||
Intersect ret = Intersect();
|
Intersect tmp = Intersect();
|
||||||
|
|
||||||
if (this->bounds.intesectMe(r))
|
if (this->bounds.intesectMe(r))
|
||||||
{
|
{
|
||||||
Intersect leftxs = this->left->intersect(r);
|
this->left->intersect(r, tmp);
|
||||||
Intersect rightxs = this->right->intersect(r);
|
this->right->intersect(r, tmp);
|
||||||
|
|
||||||
for (i = 0 ; i < rightxs.count() ; i++)
|
this->filterIntersections(tmp, xs);
|
||||||
{
|
|
||||||
leftxs.add(rightxs[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this->filterIntersections(leftxs, ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple CSG::localNormalAt(Tuple point, Intersection *hit)
|
Tuple CSG::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -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 xtMin, xtMax, ytMin, ytMax, ztMin, ztMax;
|
||||||
double tMin, tMax;
|
double tMin, tMax;
|
||||||
|
|
||||||
@@ -52,11 +50,9 @@ Intersect Cube::localIntersect(Ray r)
|
|||||||
|
|
||||||
if (tMin <= tMax)
|
if (tMin <= tMax)
|
||||||
{
|
{
|
||||||
ret.add(Intersection(tMin, this));
|
xs.add(Intersection(tMin, this));
|
||||||
ret.add(Intersection(tMax, this));
|
xs.add(Intersection(tMax, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple Cube::localNormalAt(Tuple point, Intersection *hit)
|
Tuple Cube::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -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;
|
double A = r.direction.x * r.direction.x + r.direction.z * r.direction.z;
|
||||||
|
|
||||||
/* Ray is parallel to the Y axis */
|
/* 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;
|
double y0 = r.origin.y + t0 * r.direction.y;
|
||||||
if ((this->minCap < y0) && (y0 < this->maxCap))
|
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;
|
double y1 = r.origin.y + t1 * r.direction.y;
|
||||||
if ((this->minCap < y1) && (y1 < this->maxCap))
|
if ((this->minCap < y1) && (y1 < this->maxCap))
|
||||||
{
|
{
|
||||||
ret.add(Intersection(t1, this));
|
xs.add(Intersection(t1, this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->intersectCaps(r, ret);
|
this->intersectCaps(r, xs);
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple Cylinder::localNormalAt(Tuple point, Intersection *hit)
|
Tuple Cylinder::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -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;
|
int i, j;
|
||||||
if (this->objectCount > 0)
|
if (this->objectCount > 0)
|
||||||
{
|
{
|
||||||
@@ -46,14 +45,7 @@ Intersect Group::intersect(Ray r)
|
|||||||
{
|
{
|
||||||
for (i = 0 ; i < this->objectCount ; i++)
|
for (i = 0 ; i < this->objectCount ; i++)
|
||||||
{
|
{
|
||||||
Intersect xs = this->objectList[i]->intersect(r);
|
this->objectList[i]->intersect(r, xs);
|
||||||
if (xs.count() > 0)
|
|
||||||
{
|
|
||||||
for (j = 0 ; j < xs.count() ; j++)
|
|
||||||
{
|
|
||||||
ret.add(xs[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,17 +55,9 @@ Intersect Group::intersect(Ray r)
|
|||||||
{
|
{
|
||||||
for(i = 0; i < this->unboxableObjectCount; i++)
|
for(i = 0; i < this->unboxableObjectCount; i++)
|
||||||
{
|
{
|
||||||
Intersect xs = this->unboxableObjectList[i]->intersect(r);
|
this->unboxableObjectList[i]->intersect(r, xs);
|
||||||
if (xs.count() > 0)
|
|
||||||
{
|
|
||||||
for(j = 0; j < xs.count(); j++)
|
|
||||||
{
|
|
||||||
ret.add(xs[j]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Group::includes(Shape *b)
|
bool Group::includes(Shape *b)
|
||||||
@@ -104,9 +88,9 @@ bool Group::includes(Shape *b)
|
|||||||
return false;
|
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)
|
Tuple Group::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -160,9 +160,9 @@ Group *OBJFile::groups(const char *groupName)
|
|||||||
return nullptr;
|
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)
|
bool OBJFile::includes(Shape *b)
|
||||||
@@ -170,9 +170,9 @@ bool OBJFile::includes(Shape *b)
|
|||||||
return this->baseGroup->includes(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)
|
Tuple OBJFile::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -12,22 +12,20 @@
|
|||||||
#include <plane.h>
|
#include <plane.h>
|
||||||
#include <math_helper.h>
|
#include <math_helper.h>
|
||||||
|
|
||||||
Intersect Plane::localIntersect(Ray r)
|
void Plane::localIntersect(Ray r, Intersect &xs)
|
||||||
{
|
{
|
||||||
double t;
|
double t;
|
||||||
Intersect ret = Intersect();
|
|
||||||
|
|
||||||
if (fabs(r.direction.y) < getEpsilon())
|
if (fabs(r.direction.y) < getEpsilon())
|
||||||
{
|
{
|
||||||
/* With a direction == 0, the ray can't intersect the plane */
|
/* 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));
|
xs.add(Intersection(t, this));
|
||||||
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple Plane::localNormalAt(Tuple point, Intersection *hit)
|
Tuple Plane::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -25,9 +25,9 @@ Shape::Shape(ShapeType type)
|
|||||||
this->updateTransform();
|
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)
|
Tuple Shape::normalToWorld(Tuple normalVector)
|
||||||
|
|||||||
@@ -13,9 +13,8 @@
|
|||||||
#include <tuple.h>
|
#include <tuple.h>
|
||||||
#include <intersect.h>
|
#include <intersect.h>
|
||||||
|
|
||||||
Intersect Sphere::localIntersect(Ray r)
|
void Sphere::localIntersect(Ray r, Intersect &xs)
|
||||||
{
|
{
|
||||||
Intersect ret;
|
|
||||||
double a, b, c, discriminant;
|
double a, b, c, discriminant;
|
||||||
|
|
||||||
Tuple sphere_to_ray = r.origin - Point(0, 0, 0);
|
Tuple sphere_to_ray = r.origin - Point(0, 0, 0);
|
||||||
@@ -28,11 +27,9 @@ Intersect Sphere::localIntersect(Ray r)
|
|||||||
|
|
||||||
if (discriminant >= 0)
|
if (discriminant >= 0)
|
||||||
{
|
{
|
||||||
ret.add(Intersection((-b - sqrt(discriminant)) / (2 * a), this));
|
xs.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));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple Sphere::localNormalAt(Tuple point, Intersection *hit)
|
Tuple Sphere::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -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;
|
this->localRay = r;
|
||||||
return Intersect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple TestShape::localNormalAt(Tuple point, Intersection *hit)
|
Tuple TestShape::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -21,15 +21,13 @@ Triangle::Triangle(Point p1, Point p2, Point p3) : Shape(Shape::TRIANGLE), p1(p1
|
|||||||
this->normal = e2.cross(e1).normalise();
|
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);
|
Tuple dirCrossE2 = r.direction.cross(this->e2);
|
||||||
double determinant = this->e1.dot(dirCrossE2);
|
double determinant = this->e1.dot(dirCrossE2);
|
||||||
if (fabs(determinant) < getEpsilon())
|
if (fabs(determinant) < getEpsilon())
|
||||||
{
|
{
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double f = 1.0 / determinant;
|
double f = 1.0 / determinant;
|
||||||
@@ -40,18 +38,16 @@ Intersect Triangle::localIntersect(Ray r)
|
|||||||
|
|
||||||
if ((u < 0) || (u > 1))
|
if ((u < 0) || (u > 1))
|
||||||
{
|
{
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((v < 0) || ((u + v) > 1))
|
if ((v < 0) || ((u + v) > 1))
|
||||||
{
|
{
|
||||||
return ret;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
double t = f * this->e2.dot(originCrossE1);
|
double t = f * this->e2.dot(originCrossE1);
|
||||||
ret.add(Intersection(t, this, u, v));
|
xs.add(Intersection(t, this, u, v));
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Tuple Triangle::localNormalAt(Tuple point, Intersection *hit)
|
Tuple Triangle::localNormalAt(Tuple point, Intersection *hit)
|
||||||
|
|||||||
@@ -75,9 +75,9 @@ bool World::objectIsIn(Shape &s)
|
|||||||
return this->worldGroup.includes(&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)
|
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)
|
Tuple World::colourAt(Ray r, uint32_t depthCount)
|
||||||
{
|
{
|
||||||
Intersect allHits = this->intersect(r);
|
Intersect allHits;
|
||||||
|
this->intersect(r, allHits);
|
||||||
Intersection hit = allHits.hit();
|
Intersection hit = allHits.hit();
|
||||||
|
|
||||||
stats.setMaxDepth(depthCount);
|
stats.setMaxDepth(depthCount);
|
||||||
@@ -131,7 +132,8 @@ bool World::isShadowed(Tuple point, Tuple lightPosition)
|
|||||||
|
|
||||||
Ray r = Ray(point, direction);
|
Ray r = Ray(point, direction);
|
||||||
stats.addLightRay();
|
stats.addLightRay();
|
||||||
Intersect xs = this->intersect(r);
|
Intersect xs;
|
||||||
|
this->intersect(r, xs);
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < xs.count(); i++)
|
for(i = 0; i < xs.count(); i++)
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ int main()
|
|||||||
double worldX = -(wallSize / 2) + pixelSize * x;
|
double worldX = -(wallSize / 2) + pixelSize * x;
|
||||||
Point position = Point(worldX, worldY, wallDistance);
|
Point position = Point(worldX, worldY, wallDistance);
|
||||||
Ray r = Ray(cameraOrigin, (position - cameraOrigin).normalise());
|
Ray r = Ray(cameraOrigin, (position - cameraOrigin).normalise());
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs;
|
||||||
|
s.intersect(r, xs);
|
||||||
|
|
||||||
if (!xs.hit().nothing())
|
if (!xs.hit().nothing())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ int main()
|
|||||||
double worldX = -(wallSize / 2) + pixelSize * x;
|
double worldX = -(wallSize / 2) + pixelSize * x;
|
||||||
Point position = Point(worldX, worldY, wallDistance);
|
Point position = Point(worldX, worldY, wallDistance);
|
||||||
Ray r = Ray(cameraOrigin, (position - cameraOrigin).normalise());
|
Ray r = Ray(cameraOrigin, (position - cameraOrigin).normalise());
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs;
|
||||||
|
s.intersect(r, xs);
|
||||||
|
|
||||||
Intersection hit = xs.hit();
|
Intersection hit = xs.hit();
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ TEST(ConeTest, Intersecting_a_cone_with_a_ray)
|
|||||||
Tuple direction = Directions[i].normalise();
|
Tuple direction = Directions[i].normalise();
|
||||||
Ray r = Ray(Origins[i], direction);
|
Ray r = Ray(Origins[i], direction);
|
||||||
|
|
||||||
Intersect xs = cone.intersect(r);
|
Intersect xs; cone.intersect(r, xs);
|
||||||
|
|
||||||
/* Temporary lower the precision */
|
/* Temporary lower the precision */
|
||||||
set_equal_precision(0.00001);
|
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();
|
Cone cone = Cone();
|
||||||
Tuple direction = Vector(0, 1, 1).normalise();
|
Tuple direction = Vector(0, 1, 1).normalise();
|
||||||
Ray r = Ray(Point(0, 0, -1), direction);
|
Ray r = Ray(Point(0, 0, -1), direction);
|
||||||
Intersect xs = cone.intersect(r);
|
Intersect xs; cone.intersect(r, xs);
|
||||||
ASSERT_EQ(xs.count(), 1);
|
ASSERT_EQ(xs.count(), 1);
|
||||||
|
|
||||||
/* Temporary lower the precision */
|
/* Temporary lower the precision */
|
||||||
@@ -102,7 +102,8 @@ TEST(ConeTest, Intersecting_a_cone_end_cap)
|
|||||||
Tuple direction = Directions[i].normalise();
|
Tuple direction = Directions[i].normalise();
|
||||||
Ray r = Ray(Origins[i], direction);
|
Ray r = Ray(Origins[i], direction);
|
||||||
|
|
||||||
Intersect xs = cone.intersect(r);
|
Intersect xs;
|
||||||
|
cone.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), Counts[i]);
|
ASSERT_EQ(xs.count(), Counts[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
class CSGTest : public CSG
|
class CSGTest : public CSG
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Intersect doLocalIntersect(Ray r) {
|
void doLocalIntersect(Ray r, Intersect &xs) {
|
||||||
return this->localIntersect(r);
|
return this->localIntersect(r, xs);
|
||||||
};
|
};
|
||||||
Tuple doLocalNormalAt(Tuple point, Intersection *hit = nullptr) {
|
Tuple doLocalNormalAt(Tuple point, Intersection *hit = nullptr) {
|
||||||
return this->localNormalAt(point, hit);
|
return this->localNormalAt(point, hit);
|
||||||
@@ -202,7 +202,7 @@ TEST(CSGTest, A_ray_misses_a_csg_object)
|
|||||||
CSGTest c = CSGTest(CSG::UNION, &s1, &s2);
|
CSGTest c = CSGTest(CSG::UNION, &s1, &s2);
|
||||||
|
|
||||||
Ray r = Ray(Point(0, 2, -5), Vector(0, 0, 1));
|
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);
|
ASSERT_EQ(xs.count(), 0);
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ TEST(CSGTest, A_ray_hits_a_csg_object)
|
|||||||
CSGTest c = CSGTest(CSG::UNION, &s1, &s2);
|
CSGTest c = CSGTest(CSG::UNION, &s1, &s2);
|
||||||
|
|
||||||
Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
|
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_EQ(xs.count(), 2);
|
||||||
ASSERT_TRUE(double_equal(xs[0].t, 4));
|
ASSERT_TRUE(double_equal(xs[0].t, 4));
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ TEST(CubeTest, A_ray_intersects_a_cube)
|
|||||||
for(i = 0; i < 7; i++)
|
for(i = 0; i < 7; i++)
|
||||||
{
|
{
|
||||||
Ray r = Ray(Origins[i], Directions[i]);
|
Ray r = Ray(Origins[i], Directions[i]);
|
||||||
Intersect xs = c.intersect(r);
|
Intersect xs; c.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 2);
|
ASSERT_EQ(xs.count(), 2);
|
||||||
EXPECT_EQ(xs[0].t, t1[i]);
|
EXPECT_EQ(xs[0].t, t1[i]);
|
||||||
@@ -77,7 +77,7 @@ TEST(CubeTest, A_ray_miss_a_cube)
|
|||||||
for(i = 0; i < 6; i++)
|
for(i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
Ray r = Ray(Origins[i], Directions[i]);
|
Ray r = Ray(Origins[i], Directions[i]);
|
||||||
Intersect xs = c.intersect(r);
|
Intersect xs; c.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 0);
|
ASSERT_EQ(xs.count(), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ TEST(CylinderTest, A_ray_miss_a_cylinder)
|
|||||||
Tuple direction = Directions[i].normalise();
|
Tuple direction = Directions[i].normalise();
|
||||||
Ray r = Ray(Origins[i], direction);
|
Ray r = Ray(Origins[i], direction);
|
||||||
|
|
||||||
Intersect xs = cyl.intersect(r);
|
Intersect xs; cyl.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 0);
|
ASSERT_EQ(xs.count(), 0);
|
||||||
}
|
}
|
||||||
@@ -65,7 +65,7 @@ TEST(CylinderTest, A_ray_hit_a_cylinder)
|
|||||||
Tuple direction = Directions[i].normalise();
|
Tuple direction = Directions[i].normalise();
|
||||||
Ray r = Ray(Origins[i], direction);
|
Ray r = Ray(Origins[i], direction);
|
||||||
|
|
||||||
Intersect xs = cyl.intersect(r);
|
Intersect xs; cyl.intersect(r, xs);
|
||||||
|
|
||||||
/* Temporary lower the precision */
|
/* Temporary lower the precision */
|
||||||
set_equal_precision(0.00001);
|
set_equal_precision(0.00001);
|
||||||
@@ -142,7 +142,7 @@ TEST(CylinderTest, Intersecting_a_constrained_cylinder)
|
|||||||
Tuple direction = Directions[i].normalise();
|
Tuple direction = Directions[i].normalise();
|
||||||
Ray r = Ray(Origins[i], direction);
|
Ray r = Ray(Origins[i], direction);
|
||||||
|
|
||||||
Intersect xs = cyl.intersect(r);
|
Intersect xs; cyl.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), Counts[i]);
|
ASSERT_EQ(xs.count(), Counts[i]);
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,7 @@ TEST(CylinderTest, Intersecting_the_caps_of_a_close_cylinder)
|
|||||||
Tuple direction = Directions[i].normalise();
|
Tuple direction = Directions[i].normalise();
|
||||||
Ray r = Ray(Origins[i], direction);
|
Ray r = Ray(Origins[i], direction);
|
||||||
|
|
||||||
Intersect xs = cyl.intersect(r);
|
Intersect xs; cyl.intersect(r, xs);
|
||||||
ASSERT_EQ(xs.count(), Counts[i]);
|
ASSERT_EQ(xs.count(), Counts[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ TEST(GroupTest, Intersecting_a_ray_with_an_empty_group)
|
|||||||
{
|
{
|
||||||
Group g = Group();
|
Group g = Group();
|
||||||
Ray r = Ray(Point(0, 0, 0), Vector(0, 0, 1));
|
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);
|
ASSERT_EQ(xs.count(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ TEST(GroupTest, Intersecting_a_ray_with_an_nonempty_group)
|
|||||||
g.addObject(&s3);
|
g.addObject(&s3);
|
||||||
|
|
||||||
Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
|
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);
|
ASSERT_EQ(xs.count(), 4);
|
||||||
EXPECT_EQ(xs[0].object, &s2);
|
EXPECT_EQ(xs[0].object, &s2);
|
||||||
EXPECT_EQ(xs[1].object, &s2);
|
EXPECT_EQ(xs[1].object, &s2);
|
||||||
@@ -77,7 +77,7 @@ TEST(GroupTest, Intersecting_a_transformed_group)
|
|||||||
g.addObject(&s);
|
g.addObject(&s);
|
||||||
|
|
||||||
Ray r = Ray(Point(10, 0, -50), Vector(0, 0, 1));
|
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);
|
ASSERT_EQ(xs.count(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ TEST(IntersectTest, Intersect_sets_the_object_on_the_intersection)
|
|||||||
{
|
{
|
||||||
Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
|
Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
|
||||||
Sphere s = Sphere();
|
Sphere s = Sphere();
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs; s.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 2);
|
ASSERT_EQ(xs.count(), 2);
|
||||||
ASSERT_EQ(xs[0].object, (Shape *)&s);
|
ASSERT_EQ(xs[0].object, (Shape *)&s);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ TEST(PlaneTest, Intersect_with_a_ray_parallel_to_the_plane)
|
|||||||
Plane p = Plane();
|
Plane p = Plane();
|
||||||
Ray r = Ray(Point(0, 10, 0), Vector(0, 0, 1));
|
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);
|
ASSERT_EQ(xs.count(), 0);
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ TEST(PlaneTest, Intersect_with_a_coplanar_ray)
|
|||||||
Plane p = Plane();
|
Plane p = Plane();
|
||||||
Ray r = Ray(Point(0, 0, 0), Vector(0, 0, 1));
|
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);
|
ASSERT_EQ(xs.count(), 0);
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,7 @@ TEST(PlaneTest, A_ray_intersecting_a_plane_from_above)
|
|||||||
Plane p = Plane();
|
Plane p = Plane();
|
||||||
Ray r = Ray(Point(0, 1, 0), Vector(0, -1, 0));
|
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.count(), 1);
|
||||||
ASSERT_EQ(xs[0].t, 1);
|
ASSERT_EQ(xs[0].t, 1);
|
||||||
@@ -63,7 +63,7 @@ TEST(PlaneTest, A_ray_intersecting_a_plane_from_below)
|
|||||||
Plane p = Plane();
|
Plane p = Plane();
|
||||||
Ray r = Ray(Point(0, -1, 0), Vector(0, 1, 0));
|
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.count(), 1);
|
||||||
ASSERT_EQ(xs[0].t, 1);
|
ASSERT_EQ(xs[0].t, 1);
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ TEST(ShapeTest, Intersecting_a_scaled_shape_with_a_ray)
|
|||||||
TestShape s = TestShape();
|
TestShape s = TestShape();
|
||||||
|
|
||||||
s.setTransform(scaling(2, 2, 2));
|
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.origin, Point(0, 0, -2.5));
|
||||||
ASSERT_EQ(s.localRay.direction, Vector(0, 0, 0.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();
|
TestShape s = TestShape();
|
||||||
|
|
||||||
s.setTransform(translation(5, 0, 0));
|
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.origin, Point(-5, 0, -5));
|
||||||
ASSERT_EQ(s.localRay.direction, Vector(0, 0, 1));
|
ASSERT_EQ(s.localRay.direction, Vector(0, 0, 1));
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ class SmoothTriTest : public SmoothTriangle
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SmoothTriTest(Point p1, Point p2, Point p3, Vector n1, Vector n2, Vector n3) : SmoothTriangle(p1, p2, p3, n1, n2, n3) {};
|
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)
|
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));
|
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].u, 0.45));
|
||||||
ASSERT_TRUE(double_equal(xs[0].v, 0.25));
|
ASSERT_TRUE(double_equal(xs[0].v, 0.25));
|
||||||
|
|||||||
@@ -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));
|
Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
|
||||||
Sphere s = Sphere();
|
Sphere s = Sphere();
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs; s.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 2);
|
ASSERT_EQ(xs.count(), 2);
|
||||||
ASSERT_EQ(xs[0].t, 4.0);
|
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));
|
Ray r = Ray(Point(0, 1, -5), Vector(0, 0, 1));
|
||||||
Sphere s = Sphere();
|
Sphere s = Sphere();
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs; s.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 2);
|
ASSERT_EQ(xs.count(), 2);
|
||||||
ASSERT_EQ(xs[0].t, 5.0);
|
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));
|
Ray r = Ray(Point(0, 2, -5), Vector(0, 0, 1));
|
||||||
Sphere s = Sphere();
|
Sphere s = Sphere();
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs; s.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 0);
|
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));
|
Ray r = Ray(Point(0, 0, 0), Vector(0, 0, 1));
|
||||||
Sphere s = Sphere();
|
Sphere s = Sphere();
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs; s.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 2);
|
ASSERT_EQ(xs.count(), 2);
|
||||||
ASSERT_EQ(xs[0].t, -1.0);
|
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));
|
Ray r = Ray(Point(0, 0, 5), Vector(0, 0, 1));
|
||||||
Sphere s = Sphere();
|
Sphere s = Sphere();
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs; s.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 2);
|
ASSERT_EQ(xs.count(), 2);
|
||||||
ASSERT_EQ(xs[0].t, -6.0);
|
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));
|
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.count(), 2);
|
||||||
ASSERT_EQ(xs[0].t, 3.0);
|
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));
|
s.setTransform(translation(5, 0, 0));
|
||||||
|
|
||||||
Intersect xs = s.intersect(r);
|
Intersect xs; s.intersect(r, xs);
|
||||||
|
|
||||||
ASSERT_EQ(xs.count(), 0);
|
ASSERT_EQ(xs.count(), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
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));
|
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);
|
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));
|
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));
|
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);
|
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));
|
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));
|
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);
|
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));
|
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));
|
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);
|
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));
|
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));
|
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);
|
ASSERT_EQ(xs.count(), 1);
|
||||||
EXPECT_EQ(xs[0].t, 2);
|
EXPECT_EQ(xs[0].t, 2);
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ TEST(WorldTest, Intersect_a_world_with_a_ray)
|
|||||||
World w = DefaultWorld();
|
World w = DefaultWorld();
|
||||||
Ray r = Ray(Point(0, 0, -5), Vector(0, 0, 1));
|
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.count(), 4);
|
||||||
ASSERT_EQ(xs[0].t, 4);
|
ASSERT_EQ(xs[0].t, 4);
|
||||||
|
|||||||
Reference in New Issue
Block a user