Smooth triangles! And support for them in the OBJ File parser.
Also add an interesting tea party scene!
This commit is contained in:
@@ -19,7 +19,7 @@ class Cone : public Shape {
|
||||
protected:
|
||||
Intersect localIntersect(Ray r);
|
||||
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
bool checkCap(Ray r, double t, double y);
|
||||
void intersectCaps(Ray r, Intersect &xs);
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
#include <stdio.h>
|
||||
|
||||
class Cube : public Shape {
|
||||
private:
|
||||
protected:
|
||||
void checkAxis(double axeOrigin, double axeDirection, double *axeMin, double *axeMax);
|
||||
|
||||
Intersect localIntersect(Ray r);
|
||||
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
public:
|
||||
Cube() : Shape(SHAPE_CUBE) { stats.addCube(); };
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
#include <stdio.h>
|
||||
|
||||
class Cylinder : public Shape {
|
||||
private:
|
||||
|
||||
protected:
|
||||
Intersect localIntersect(Ray r);
|
||||
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
bool checkCap(Ray r, double t);
|
||||
void intersectCaps(Ray r, Intersect &xs);
|
||||
|
||||
@@ -27,7 +27,7 @@ private:
|
||||
|
||||
protected:
|
||||
Intersect localIntersect(Ray r);
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
BoundingBox bounds;
|
||||
|
||||
|
||||
@@ -74,8 +74,10 @@ public:
|
||||
double t;
|
||||
Shape *object;
|
||||
|
||||
double u, v;
|
||||
|
||||
public:
|
||||
Intersection(double t, Shape *object) : t(t), object(object) { stats.addIntersection(); };
|
||||
Intersection(double t, Shape *object, double u = NAN, double v = NAN) : t(t), object(object), u(u), v(v) { stats.addIntersection(); };
|
||||
bool nothing() { return (this->object == nullptr); };
|
||||
|
||||
Computation prepareComputation(Ray r, Intersect *xs = nullptr);
|
||||
|
||||
@@ -26,9 +26,13 @@ private:
|
||||
Point* *vertexList;
|
||||
uint32_t vertexCount;
|
||||
|
||||
uint32_t allocatedVertexNormalCount;
|
||||
Vector* *vertexNormalList;
|
||||
uint32_t vertexNormalCount;
|
||||
|
||||
private:
|
||||
Intersect localIntersect(Ray r);
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
public:
|
||||
/* Some stats */
|
||||
@@ -37,6 +41,7 @@ public:
|
||||
protected:
|
||||
void addGroup(Group *group);
|
||||
void addVertex(Point *vertex);
|
||||
void addVertexNormal(Vector *vertexNormal);
|
||||
|
||||
void parseLine(char *line, uint32_t currentLine);
|
||||
int execLine(int argc, char *argv[], uint32_t currentLine);
|
||||
@@ -50,6 +55,7 @@ public:
|
||||
|
||||
/* OBJ file expect the first vertice to be 1 and not 0 */
|
||||
Point vertices(uint32_t i) { return *this->vertexList[i - 1]; };
|
||||
Vector verticesNormal(uint32_t i) { return *this->vertexNormalList[i - 1]; };
|
||||
Group *groups(uint32_t i) { return this->faceGroupList[i]; };
|
||||
Intersect intersect(Ray r);
|
||||
BoundingBox getLocalBounds();
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
class Plane : public Shape
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
Intersect localIntersect(Ray r);
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
public:
|
||||
Plane() : Shape(SHAPE_PLANE) { stats.addPlane(); };
|
||||
|
||||
@@ -14,15 +14,16 @@
|
||||
class RenderStats
|
||||
{
|
||||
private:
|
||||
uint64_t coneCount; /* Total number of cones */
|
||||
uint64_t cylinderCount; /* Total number of cylinder */
|
||||
uint64_t cubeCount; /* Total number of cubes */
|
||||
uint64_t groupCount; /* Total number of groups */
|
||||
uint64_t lightCount; /* Total number of light */
|
||||
uint64_t planeCount; /* Total number of plane */
|
||||
uint64_t sphereCount; /* Total number of sphere */
|
||||
uint64_t triangleCount; /* Total number of triangle */
|
||||
uint64_t objfileCount; /* Total number of OBJ File */
|
||||
uint64_t coneCount; /* Total number of cones */
|
||||
uint64_t cylinderCount; /* Total number of cylinder */
|
||||
uint64_t cubeCount; /* Total number of cubes */
|
||||
uint64_t groupCount; /* Total number of groups */
|
||||
uint64_t lightCount; /* Total number of light */
|
||||
uint64_t planeCount; /* Total number of plane */
|
||||
uint64_t sphereCount; /* Total number of sphere */
|
||||
uint64_t triangleCount; /* Total number of triangle */
|
||||
uint64_t smoothTriangleCount; /* Total number of smooth triangle */
|
||||
uint64_t objfileCount; /* Total number of OBJ File */
|
||||
|
||||
uint64_t pixelCount; /* Total number of rendered pixels */
|
||||
uint64_t rayCount; /* Total number of rays */
|
||||
@@ -40,7 +41,7 @@ private:
|
||||
public:
|
||||
RenderStats() : coneCount(0), cylinderCount(0), cubeCount(0), groupCount(0), lightCount(0), planeCount(0), sphereCount(0), triangleCount(0),
|
||||
pixelCount(0), rayCount(0), lightRayEmitedCount(0), reflectionRayCount(0), refractedRayCount(0),
|
||||
intersectCount(0), intersectionCount(0), reallocCallCount(0), mallocCallCount(0),
|
||||
intersectCount(0), intersectionCount(0), reallocCallCount(0), mallocCallCount(0), smoothTriangleCount(0),
|
||||
discardedIntersectCount(0), maxDepthAttained(UINT64_MAX), maxIntersectOnARay(0), objfileCount(0) {};
|
||||
#ifdef RENDER_STATS
|
||||
void addCone();
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
void addSphere();
|
||||
void addOBJFile();
|
||||
void addTriangle();
|
||||
void addSmoothTriangle();
|
||||
void printStats();
|
||||
void addPixel();
|
||||
void addRay();
|
||||
@@ -74,6 +76,7 @@ public:
|
||||
static void addPlane() {};
|
||||
static void addSphere() {};
|
||||
static void addTriangle() {};
|
||||
static void addSmoothTriangle() {};
|
||||
static void printStats() {};
|
||||
static void addPixel() {};
|
||||
static void addRay() {};
|
||||
|
||||
@@ -30,17 +30,19 @@ enum ShapeType
|
||||
SHAPE_GROUP,
|
||||
SHAPE_TRIANGLE,
|
||||
SHAPE_OBJFILE,
|
||||
SHAPE_SMOOTHTRIANGLE,
|
||||
};
|
||||
|
||||
/* Base class for all object that can be presented in the world */
|
||||
class Shape
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
ShapeType type;
|
||||
Matrix localTransformMatrix;
|
||||
|
||||
protected:
|
||||
virtual Intersect localIntersect(Ray r) = 0;
|
||||
virtual Tuple localNormalAt(Tuple point) = 0;
|
||||
virtual Tuple localNormalAt(Tuple point, Intersection *hit) = 0;
|
||||
|
||||
public:
|
||||
Matrix transformMatrix;
|
||||
@@ -50,13 +52,14 @@ public:
|
||||
Material material;
|
||||
bool dropShadow;
|
||||
Shape *parent;
|
||||
bool materialSet;
|
||||
|
||||
public:
|
||||
Shape(ShapeType = SHAPE_NONE);
|
||||
|
||||
virtual Intersect intersect(Ray r);
|
||||
virtual Intersect intersectOOB(Ray r) { return this->intersect(r); };
|
||||
Tuple normalAt(Tuple point);
|
||||
Tuple normalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
/* Bounding box points are always world value */
|
||||
virtual BoundingBox getLocalBounds();
|
||||
|
||||
28
source/include/smoothtriangle.h
Normal file
28
source/include/smoothtriangle.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* DoRayMe - a quick and dirty Raytracer
|
||||
* Smooth Triangle header
|
||||
*
|
||||
* Created by Manoël Trapier
|
||||
* Copyright (c) 2020 986-Studio.
|
||||
*
|
||||
*/
|
||||
#ifndef DORAYME_SMOOTHTRIANGLE_H
|
||||
#define DORAYME_SMOOTHTRIANGLE_H
|
||||
|
||||
#include <triangle.h>
|
||||
|
||||
class SmoothTriangle : public Triangle
|
||||
{
|
||||
public:
|
||||
Vector n1;
|
||||
Vector n2;
|
||||
Vector n3;
|
||||
|
||||
protected:
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit);
|
||||
|
||||
public:
|
||||
SmoothTriangle(Point p1, Point p2, Point p3, Vector n1, Vector n2, Vector n3);
|
||||
};
|
||||
|
||||
#endif /* DORAYME_SMOOTHTRIANGLE_H */
|
||||
@@ -19,7 +19,7 @@ class Sphere : public Shape
|
||||
{
|
||||
protected:
|
||||
Intersect localIntersect(Ray r);
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
public:
|
||||
Sphere() : Shape(SHAPE_SPHERE) { stats.addSphere(); };
|
||||
|
||||
@@ -17,7 +17,7 @@ class TestShape : public Shape
|
||||
{
|
||||
private:
|
||||
Intersect localIntersect(Ray r);
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
public:
|
||||
Ray localRay;
|
||||
|
||||
@@ -14,8 +14,9 @@
|
||||
|
||||
class Triangle : public Shape
|
||||
{
|
||||
protected:
|
||||
Intersect localIntersect(Ray r);
|
||||
Tuple localNormalAt(Tuple point);
|
||||
Tuple localNormalAt(Tuple point, Intersection *hit = nullptr);
|
||||
|
||||
public:
|
||||
Tuple p1, p2, p3;
|
||||
|
||||
@@ -60,7 +60,7 @@ void Intersect::add(Intersection i)
|
||||
this->list = (Intersection **)realloc(this->list, sizeof(Intersection *) * this->allocated);
|
||||
}
|
||||
|
||||
this->list[this->num++] = new Intersection(i.t, i.object);
|
||||
this->list[this->num++] = new Intersection(i.t, i.object, i.u, i.v);
|
||||
|
||||
stats.setMaxIntersect(this->num);
|
||||
|
||||
|
||||
@@ -16,7 +16,18 @@ Computation Intersection::prepareComputation(Ray r, Intersect *xs)
|
||||
double n2 = 1.0;
|
||||
|
||||
Tuple hitP = r.position(this->t);
|
||||
Tuple normalV = this->object->normalAt(hitP);
|
||||
Tuple normalV;
|
||||
|
||||
if (xs != nullptr)
|
||||
{
|
||||
Intersection hit = xs->hit();
|
||||
normalV = this->object->normalAt(hitP, &hit);
|
||||
}
|
||||
else
|
||||
{
|
||||
normalV = this->object->normalAt(hitP, nullptr);
|
||||
}
|
||||
|
||||
Tuple eyeV = -r.direction;
|
||||
bool inside = false;
|
||||
|
||||
@@ -70,8 +81,9 @@ Computation Intersection::prepareComputation(Ray r, Intersect *xs)
|
||||
}
|
||||
|
||||
Shape *s = this->object;
|
||||
|
||||
/* For now don't get root group material */
|
||||
//while(s->parent != nullptr) { s = s->parent; }
|
||||
while((!s->materialSet) && (s->parent != nullptr)) { s = s->parent; }
|
||||
|
||||
return Computation(this->object,
|
||||
this->t,
|
||||
|
||||
@@ -61,6 +61,12 @@ void RenderStats::addTriangle()
|
||||
this->triangleCount++;
|
||||
};
|
||||
|
||||
void RenderStats::addSmoothTriangle()
|
||||
{
|
||||
#pragma omp atomic
|
||||
this->smoothTriangleCount++;
|
||||
};
|
||||
|
||||
void RenderStats::addOBJFile()
|
||||
{
|
||||
#pragma omp atomic
|
||||
@@ -154,6 +160,8 @@ void RenderStats::printStats()
|
||||
printf("Planes : %lld\n", this->planeCount);
|
||||
printf("Spheres : %lld\n", this->sphereCount);
|
||||
printf("Triangles : %lld\n", this->triangleCount);
|
||||
printf("Smooth Triangles : %lld\n", this->smoothTriangleCount);
|
||||
printf("OBJ File : %lld\n", this->objfileCount);
|
||||
printf("==================================================\n");
|
||||
printf("Pixel rendered : %lld\n", this->pixelCount);
|
||||
printf("Ray casted : %lld\n", this->rayCount);
|
||||
|
||||
@@ -99,7 +99,7 @@ Intersect Cone::localIntersect(Ray r)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Tuple Cone::localNormalAt(Tuple point)
|
||||
Tuple Cone::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
/* Compute the square of the distance from the Y axis */
|
||||
double dist = point.x * point.x + point.z * point.z;
|
||||
|
||||
@@ -59,7 +59,7 @@ Intersect Cube::localIntersect(Ray r)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Tuple Cube::localNormalAt(Tuple point)
|
||||
Tuple Cube::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
double maxC = max3(fabs(point.x), fabs(point.y), fabs(point.z));
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ Intersect Cylinder::localIntersect(Ray r)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Tuple Cylinder::localNormalAt(Tuple point)
|
||||
Tuple Cylinder::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
/* Compute the square of the distance from the Y axis */
|
||||
double dist = point.x * point.x + point.z * point.z;
|
||||
|
||||
@@ -72,7 +72,7 @@ Intersect Group::localIntersect(Ray r)
|
||||
return Intersect();
|
||||
}
|
||||
|
||||
Tuple Group::localNormalAt(Tuple point)
|
||||
Tuple Group::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
return Vector(1, 0, 0);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <math_helper.h>
|
||||
#include <group.h>
|
||||
#include <triangle.h>
|
||||
#include <smoothtriangle.h>
|
||||
|
||||
#define MIN_ALLOC (2)
|
||||
#define DEFAULT_GROUP (0)
|
||||
@@ -33,6 +34,11 @@ OBJFile::OBJFile() : Shape(SHAPE_OBJFILE), ignoredLines(0)
|
||||
this->vertexList = (Point **)calloc(sizeof(Point **), MIN_ALLOC);
|
||||
this->vertexCount = 0;
|
||||
|
||||
|
||||
this->allocatedVertexNormalCount = MIN_ALLOC;
|
||||
this->vertexNormalList = (Vector **)calloc(sizeof(Vector **), MIN_ALLOC);
|
||||
this->vertexNormalCount = 0;
|
||||
|
||||
/* There is always a default group */
|
||||
this->addGroup(new Group());
|
||||
};
|
||||
@@ -89,13 +95,24 @@ void OBJFile::addVertex(Point *vertex)
|
||||
this->vertexList[this->vertexCount++] = vertex;
|
||||
}
|
||||
|
||||
void OBJFile::addVertexNormal(Vector *vertexNormal)
|
||||
{
|
||||
if ((this->vertexNormalCount + 1) > this->allocatedVertexNormalCount)
|
||||
{
|
||||
this->allocatedVertexNormalCount *= 2;
|
||||
this->vertexNormalList = (Vector **)realloc(this->vertexNormalList, sizeof(Vector **) * this->allocatedVertexNormalCount);
|
||||
}
|
||||
|
||||
this->vertexNormalList[this->vertexNormalCount++] = vertexNormal;
|
||||
}
|
||||
|
||||
Intersect OBJFile::intersect(Ray r)
|
||||
{
|
||||
Intersect ret;
|
||||
int i, j;
|
||||
if (this->faceGroupCount > 0)
|
||||
{
|
||||
//if (this->bounds.intesectMe(r))
|
||||
if (this->bounds.intesectMe(r))
|
||||
{
|
||||
for (i = 0 ; i < this->faceGroupCount ; i++)
|
||||
{
|
||||
@@ -118,7 +135,7 @@ Intersect OBJFile::localIntersect(Ray r)
|
||||
return Intersect();
|
||||
}
|
||||
|
||||
Tuple OBJFile::localNormalAt(Tuple point)
|
||||
Tuple OBJFile::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
return Vector(0, 1, 0);
|
||||
}
|
||||
@@ -262,11 +279,51 @@ void OBJFile::parseLine(char *line, uint32_t currentLine)
|
||||
}
|
||||
}
|
||||
|
||||
static int parseFaceVertex(char *buf, uint32_t &v, uint32_t &vt, uint32_t &vn)
|
||||
{
|
||||
uint32_t bufPos = 0;
|
||||
uint32_t lineLength = strlen(buf);
|
||||
char *tmp = buf;
|
||||
vt = INT32_MAX;
|
||||
vn = INT32_MAX;
|
||||
int ret = 0;
|
||||
int token = 0;
|
||||
|
||||
while(bufPos < lineLength)
|
||||
{
|
||||
char *next = strchr(buf, '/');
|
||||
if (next != nullptr)
|
||||
{
|
||||
*next = '\0';
|
||||
bufPos = next - buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufPos = lineLength;
|
||||
}
|
||||
|
||||
if (strlen(buf) > 0)
|
||||
{
|
||||
switch(token)
|
||||
{
|
||||
case 0: v = atol(buf); break;
|
||||
case 1: vt = atol(buf); break;
|
||||
case 2: vn = atol(buf); break;
|
||||
default: printf("ERROR: Too many entry for a face vertice!"); ret = 1;
|
||||
}
|
||||
}
|
||||
buf = next + 1;
|
||||
token++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Actually execute the line */
|
||||
int OBJFile::execLine(int argc, char *argv[], uint32_t currentLine)
|
||||
{
|
||||
int ret = 1;
|
||||
if (strncmp(argv[0], "v", 1) == 0)
|
||||
if (strncmp(argv[0], "v", 2) == 0)
|
||||
{
|
||||
/* Vertice entry */
|
||||
if (argc != 4)
|
||||
@@ -279,25 +336,71 @@ int OBJFile::execLine(int argc, char *argv[], uint32_t currentLine)
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[0], "f", 1) == 0)
|
||||
else if (strncmp(argv[0], "vn", 3) == 0)
|
||||
{
|
||||
/* Vertice entry */
|
||||
/* Vertice Normal entry */
|
||||
if (argc != 4)
|
||||
{
|
||||
printf("ERROR: Malformed file at line %d: Vertices normal expect 3 parameters!\n", currentLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->addVertexNormal(new Vector(atof(argv[1]), atof(argv[2]), atof(argv[3])));
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[0], "f", 2) == 0)
|
||||
{
|
||||
/* Faces entry */
|
||||
int i;
|
||||
uint32_t v[MAX_ARGS], vt[MAX_ARGS], vn[MAX_ARGS];
|
||||
for(i = 1; i < argc; i++)
|
||||
{
|
||||
parseFaceVertex(argv[i], v[i], vt[i], vn[i]);
|
||||
}
|
||||
|
||||
if (argc == 4)
|
||||
{
|
||||
Shape *t = new Triangle(this->vertices(atoi(argv[1])),
|
||||
this->vertices(atoi(argv[2])),
|
||||
this->vertices(atoi(argv[3])));
|
||||
Shape *t;
|
||||
if (vn[1] == INT32_MAX)
|
||||
{
|
||||
t = new Triangle(this->vertices(v[1]),
|
||||
this->vertices(v[2]),
|
||||
this->vertices(v[3]));
|
||||
}
|
||||
else
|
||||
{
|
||||
t = new SmoothTriangle(this->vertices(v[1]),
|
||||
this->vertices(v[2]),
|
||||
this->vertices(v[3]),
|
||||
this->verticesNormal(vn[1]),
|
||||
this->verticesNormal(vn[2]),
|
||||
this->verticesNormal(vn[3]));
|
||||
}
|
||||
this->faceGroupList[this->faceGroupCount - 1]->addObject(t);
|
||||
ret = 0;
|
||||
}
|
||||
else if (argc > 4)
|
||||
{
|
||||
int i;
|
||||
for(i = 2; i < (argc - 1); i++)
|
||||
{
|
||||
Shape *t = new Triangle(this->vertices(atoi(argv[1])),
|
||||
this->vertices(atoi(argv[i])),
|
||||
this->vertices(atoi(argv[i+1])));
|
||||
|
||||
Shape *t;
|
||||
if (vn[1] == INT32_MAX)
|
||||
{
|
||||
t = new Triangle(this->vertices(v[1]),
|
||||
this->vertices(v[i]),
|
||||
this->vertices(v[i + 1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
t = new SmoothTriangle(this->vertices(v[1]),
|
||||
this->vertices(v[i]),
|
||||
this->vertices(v[i + 1]),
|
||||
this->verticesNormal(vn[1]),
|
||||
this->verticesNormal(vn[i]),
|
||||
this->verticesNormal(vn[i + 1]));
|
||||
}
|
||||
this->faceGroupList[this->faceGroupCount - 1]->addObject(t);
|
||||
}
|
||||
ret = 0;
|
||||
@@ -307,7 +410,7 @@ int OBJFile::execLine(int argc, char *argv[], uint32_t currentLine)
|
||||
printf("ERROR: Malformed file at line %d: Too few/many parameters!\n", currentLine);
|
||||
}
|
||||
}
|
||||
else if (strncmp(argv[0], "g", 1) == 0)
|
||||
else if (strncmp(argv[0], "g", 2) == 0)
|
||||
{
|
||||
if (argc == 2)
|
||||
{
|
||||
|
||||
@@ -30,7 +30,7 @@ Intersect Plane::localIntersect(Ray r)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Tuple Plane::localNormalAt(Tuple point)
|
||||
Tuple Plane::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
return Vector(0, 1, 0);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ Shape::Shape(ShapeType type)
|
||||
this->type = type;
|
||||
this->localTransformMatrix = Matrix4().identity();
|
||||
this->updateTransform();
|
||||
this->materialSet = false;
|
||||
}
|
||||
|
||||
Intersect Shape::intersect(Ray r)
|
||||
@@ -37,11 +38,11 @@ Tuple Shape::normalToWorld(Tuple normalVector)
|
||||
return world_normal.normalise();
|
||||
};
|
||||
|
||||
Tuple Shape::normalAt(Tuple point)
|
||||
Tuple Shape::normalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
Tuple local_point = this->worldToObject(point);
|
||||
|
||||
Tuple local_normal = this->localNormalAt(local_point);
|
||||
Tuple local_normal = this->localNormalAt(local_point, hit);
|
||||
|
||||
Tuple world_normal = this->normalToWorld(local_normal);
|
||||
|
||||
|
||||
28
source/shapes/smoothtriangle.cpp
Normal file
28
source/shapes/smoothtriangle.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* DoRayMe - a quick and dirty Raytracer
|
||||
* Smooth Triangle implementation
|
||||
*
|
||||
* Created by Manoël Trapier
|
||||
* Copyright (c) 2020 986-Studio.
|
||||
*
|
||||
*/
|
||||
#include <ray.h>
|
||||
#include <shape.h>
|
||||
#include <triangle.h>
|
||||
#include <smoothtriangle.h>
|
||||
#include <math_helper.h>
|
||||
#include <renderstat.h>
|
||||
|
||||
SmoothTriangle::SmoothTriangle(Point p1, Point p2, Point p3, Vector n1, Vector n2, Vector n3) : Triangle(p1, p2, p3),
|
||||
n1(n1), n2(n2), n3(n3)
|
||||
{
|
||||
this->type = SHAPE_SMOOTHTRIANGLE;
|
||||
stats.addSmoothTriangle();
|
||||
}
|
||||
|
||||
Tuple SmoothTriangle::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
return (this->n2 * hit->u +
|
||||
this->n3 * hit->v +
|
||||
this->n1 * (1 - hit->u - hit->v)).normalise();
|
||||
}
|
||||
@@ -35,7 +35,7 @@ Intersect Sphere::localIntersect(Ray r)
|
||||
return ret;
|
||||
}
|
||||
|
||||
Tuple Sphere::localNormalAt(Tuple point)
|
||||
Tuple Sphere::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
return (point - Point(0, 0, 0)).normalise();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ Intersect TestShape::localIntersect(Ray r)
|
||||
return Intersect();
|
||||
}
|
||||
|
||||
Tuple TestShape::localNormalAt(Tuple point)
|
||||
Tuple TestShape::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
return Vector(point.x, point.y, point.z);
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* DoRayMe - a quick and dirty Raytracer
|
||||
* Cone implementation
|
||||
* Triangle implementation
|
||||
*
|
||||
* Created by Manoël Trapier
|
||||
* Copyright (c) 2020 986-Studio.
|
||||
@@ -49,12 +49,12 @@ Intersect Triangle::localIntersect(Ray r)
|
||||
}
|
||||
|
||||
double t = f * this->e2.dot(originCrossE1);
|
||||
ret.add(Intersection(t, this));
|
||||
ret.add(Intersection(t, this, u, v));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Tuple Triangle::localNormalAt(Tuple point)
|
||||
Tuple Triangle::localNormalAt(Tuple point, Intersection *hit)
|
||||
{
|
||||
return this->normal;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user