Browse Source

Sample scene for CSG \o/

Godzil 4 years ago
parent
commit
57eff4830e

+ 28 - 46
README.md

@@ -17,101 +17,83 @@ as texture, also use [NanoJPEG](https://keyj.emphy.de/nanojpeg/) to use jpeg fil
 Examples outputs
 ----------------
 
-**From chapter 05 - Sphere intersections:**
-
+#### From chapter 05 - Sphere intersections:
 ![Chapter 5 rendering test](output/ch5_test.png)
 
-**From Chapter 06 - Phong shading:**
-
+#### From Chapter 06 - Phong shading:
 ![Chapter 6 rendering test](output/ch6_test.png)
 
-**From Chapter 07 - World / Camera / Scenes:**
-
+#### From Chapter 07 - World / Camera / Scenes:
 ![Chapter 7 rendering test](output/ch7_test.png)
 
-**From Chapter 08 - Shadows:**
-
+#### From Chapter 08 - Shadows:
 ![Chapter 8 rendering test](output/ch8_test.png)
 
-**From Chapter 09 - Planes:**
-
+#### From Chapter 09 - Planes:
 ![Chapter 9 rendering test](output/ch9_test.png)
 
-**From Chapter 10 - Patterns:**
-
+#### From Chapter 10 - Patterns:
 ![Chapter 10 rendering test](output/ch10_test.png)
 
-**From Chapter 11 - Reflections, Transparency & Refractions:**
-
+#### From Chapter 11 - Reflections, Transparency & Refractions:
 ![Chapter 11 reflections rendering test](output/ch11_reflection.png)
 
-Bonus: Zooming on a reflective ball:
+###### Bonus: Zooming on a reflective ball:
 ![Chapter 11 zooming on a ball](output/ch11_zooming_on_reflective_ball.png)
 
-Zooming on a reflection on that ball:
+###### Zooming on a reflection on that ball:
 ![Chapter 11 zooming on a reflection](output/ch11_reflection_on_ball.png)
 
 ![Chapter 11 refraction rendering test](output/ch11_refraction.png)
 
 ![Chapter 11 rendering test](output/ch11_test.png)
 
-**From Chapter 12 - Cubes:**
-
+#### From Chapter 12 - Cubes:
 ![Chapter 12 rendering test](output/ch12_test.png)
 
-**From Chapter 13 - Cylinders:**
-
+#### From Chapter 13 - Cylinders:
 ![Chapter 13 rendering test](output/ch13_test.png)
-Bonus:
+###### Bonus:
 ![Chapter 13 cone test](output/ch13_cone.png)
 
-**From Chapter 14 - Groups & Bounding boxes:**
+#### From Chapter 14 - Groups & Bounding boxes:
 ![Chapter 14 rendering test](output/ch14_test.png)
 
-**From Chapter 15 - Triangles, Wavefrom OBJ files - Smooth trianges:**
+#### From Chapter 15 - Triangles, Wavefrom OBJ files - Smooth trianges:
 ![Chapter 15 Triangles and teapots](output/ch15_teapot_objfile.png)
 
-**Bonus (from the forum):**
+#### From Chapter 16 - Constructive Solid Geomety:
+![Chapter 16 CSG](output/ch16_test.png)
 
+#### Bonus (from the forum):
 [Merry Christmas](https://forum.raytracerchallenge.com/thread/16/merry-christmas-scene-description)
 ![Merry Christmas](output/christmasball.png)
-
 (about 1min render time using OpenMP on a 2.6Ghz Core i7 3720QM)
 
-**Bonus chapter - Soft shadow / Area light**
-
-Without jitter:
+#### Bonus chapter - Soft shadow / Area light
+###### Without jitter:
 ![Area light without jitter](output/arealight_test_nojitter.png)
-
-With jitter:
+###### With jitter:
 ![Area light witht jitter](output/arealight_test.png)
 
-**Bonus chapter - Texture mapping**
-
-Spherical mapping:
-
+#### Bonus chapter - Texture mapping
+###### Spherical mapping:
 ![Spherical mapping](output/uvmap_checkeredsphere.png)
 
-Planar mapping:
-
+######Planar mapping:
 ![Planar mapping](output/uvmap_checkeredplane.png)
 
-Cylindrical mapping:
-
+###### Cylindrical mapping:
 ![Cylindrical mapping](output/uvmap_checkeredcylinder.png)
 
-Aligncheck plane:
-
+###### Aligncheck plane:
 ![Aligncheck plane](output/uvmap_aligncheckplane.png)
 
-Cubical mapping:
-
+###### Cubical mapping:
 ![Cubical mapping](output/uvmap_checkeredcube.png)
 
-Image mapping:
-
+###### Image mapping:
 ![Image mapping](output/uvmap_earth.png)
 
-Skybox:
-
+###### Skybox:
 ![Skybox](output/uvmap_skybox.png)

BIN
output/ch16_test.png


+ 4 - 4
source/canvas.cpp

@@ -132,12 +132,12 @@ Canvas::~Canvas()
     }
 }
 
-void Canvas::putPixel(uint32_t x, uint32_t y, Tuple colour)
+void Canvas::putPixel(uint32_t x, uint32_t y, Tuple c)
 {
     uint32_t offset = y * this->stride + x * BytePP;
-    this->bitmap[offset + 0] = MAX(MIN(colour.x * 255, 255), 0);
-    this->bitmap[offset + 1] = MAX(MIN(colour.y * 255, 255), 0);
-    this->bitmap[offset + 2] = MAX(MIN(colour.z * 255, 255), 0);
+    this->bitmap[offset + 0] = MAX(MIN(c.x * 255, 255), 0);
+    this->bitmap[offset + 1] = MAX(MIN(c.y * 255, 255), 0);
+    this->bitmap[offset + 2] = MAX(MIN(c.z * 255, 255), 0);
 }
 
 Colour Canvas::getPixel(uint32_t x, uint32_t y)

+ 2 - 0
source/include/csg.h

@@ -42,6 +42,8 @@ protected:
 public:
     CSG(OperationType operation, Shape *left, Shape *right);
 
+    Intersect intersect(Ray r);
+
     bool includes(Shape *b);
 
     void updateTransform();

+ 1 - 1
source/intersection.cpp

@@ -45,7 +45,7 @@ Computation Intersection::prepareComputation(Ray r, Intersect *xs)
     if ((xs != nullptr)  && (xs->hit().object->material.transparency > 0))
     {
         List containers;
-        int j, k;
+        int j;
 
         for (j = 0 ; j < xs->count() ; j++)
         {

+ 5 - 0
source/shapes/csg.cpp

@@ -40,6 +40,11 @@ Intersect CSG::localIntersect(Ray r)
     return ret;
 }
 
+Intersect CSG::intersect(Ray r)
+{
+    return localIntersect(r);
+}
+
 Tuple CSG::localNormalAt(Tuple point, Intersection *hit)
 {
     return Vector(1, 0, 0);

+ 2 - 2
source/shapes/group.cpp

@@ -18,11 +18,11 @@ Group::Group() : Shape(SHAPE_GROUP)
 {
     stats.addGroup();
     this->allocatedObjectCount = MIN_ALLOC;
-    this->objectList = (Shape **)calloc(sizeof(Shape *), MIN_ALLOC);
+    this->objectList = (Shape **)calloc(sizeof(Shape **), MIN_ALLOC);
     this->objectCount = 0;
 
     this->allocatedUnboxableObjectCount = MIN_ALLOC;
-    this->unboxableObjectList = (Shape **)calloc(sizeof(Shape *), MIN_ALLOC);
+    this->unboxableObjectList = (Shape **)calloc(sizeof(Shape **), MIN_ALLOC);
     this->unboxableObjectCount = 0;
 
 }

+ 0 - 1
source/shapes/light.cpp

@@ -41,7 +41,6 @@ double Light::intensityAt(World &w, Tuple point)
             }
         }
         return total / this->samples;
-        break;
     }
 }
 

+ 0 - 1
source/shapes/objfile.cpp

@@ -299,7 +299,6 @@ 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;

+ 100 - 11
tests/ch16_test.cpp

@@ -33,21 +33,37 @@ int main()
     World w = World();
 
     /* Add lights */
-    Light light1 = Light(POINT_LIGHT, Point(100, 100, -100), Colour(1, 1, 1));
+    Light light1 = Light(POINT_LIGHT, Point(6, 10, 10), Colour(0.5, 0.4, 0.5));
     w.addLight(&light1);
 
+    /* Add lights */
+    Light light2 = Light(POINT_LIGHT, Point(6, 10, -2.5), Colour(0.5, 0.6, 0.5));
+    w.addLight(&light2);
+
     /* ----------------------------- */
 
-    /* White background */
+    /* Floor */
     Plane p = Plane();
-    p.setTransform(translation(0, 0, 100) *  rotationX(1.5708));
-    p.material.colour = Colour(1, 1, 1);
-    p.material.ambient = 1;
-    p.material.diffuse = 0;
+    CheckersPattern checkered = CheckersPattern(Colour(0.35, 0.35, 0.35), Colour(0.4, 0.4, 0.4));
+    p.material.pattern = &checkered;
+    p.material.ambient = 0.2;
+    p.material.diffuse = 1;
     p.material.specular = 0;
+    p.material.reflective = 0.1;
+    p.setTransform(translation(0, 0, 0));
     w.addObject(&p);
 
+    Plane p2 = Plane();
+    p2.setTransform(translation(0, 0, -3) * rotationX(M_PI/2));
+    p2.material.pattern = &checkered;
+    p2.material.ambient = 0.2;
+    p2.material.diffuse = 1;
+    p2.material.specular = 0;
+    w.addObject(&p2);
+
+    /* ----------------------------- */
 
+    /* Funky cube */
     Cylinder c1 = Cylinder();
     c1.minCap = -2;
     c1.maxCap = 2;
@@ -77,22 +93,95 @@ int main()
     CSG leaf2 = CSG(CSG::UNION, &leaf1, &c3);
 
     Cube cb = Cube();
-    //cb.materialSet = true;
-    //cb.material.reflective = 1;
+    cb.materialSet = true;
+    cb.material.reflective = 0.5;
+    cb.material.colour = Colour(0.3, 0.3, 0.3);
+    cb.material.ambient = 0;
+    cb.material.diffuse = 0.3;
+    cb.material.specular = 0.3;
+    cb.material.shininess = 20;
 
     Sphere sp = Sphere();
     sp.setTransform(scaling(1.35, 1.35, 1.35));
+    sp.materialSet = true;
+    sp.material.colour = Colour(0, 0, 0);
+    sp.material.ambient = 0;
+    sp.material.specular = 0.3;
+    sp.material.shininess = 20;
+    sp.material.reflective = 0.05;
+    sp.material.diffuse = 0.3;
     CSG leaf3 = CSG(CSG::INTERSECTION, &sp, &cb);
 
     CSG leaf4 = CSG(CSG::DIFFERENCE, &leaf3, &leaf2);
-
+    leaf4.setTransform(translation(0, 1, 0.8) * rotationY(-0.45));
     w.addObject(&leaf4);
 
     /* ----------------------------- */
 
+    /* Tricylinder weirdy */
+    Cylinder sp1 = Cylinder();
+    sp1.minCap = -2;
+    sp1.maxCap = 2;
+    sp1.isClosed = true;
+    sp1.materialSet = true;
+    sp1.material.colour = Colour(1, 0, 0);
+    Cylinder sp2 = Cylinder();
+    sp2.minCap = -2;
+    sp2.maxCap = 2;
+    sp2.isClosed = true;
+    sp2.materialSet = true;
+    sp2.setTransform(rotationX(M_PI/2));
+    sp2.material.colour = Colour(0, 1, 0);
+    Cylinder sp3 = Cylinder();
+    sp3.minCap = -2;
+    sp3.maxCap = 2;
+    sp3.isClosed = true;
+    sp3.materialSet = true;
+    sp3.setTransform(rotationZ(M_PI/2));
+    sp3.material.colour = Colour(0, 0, 1);
+
+    CSG spleaf1 = CSG(CSG::INTERSECTION, &sp1, &sp2);
+    CSG spleaf2 = CSG(CSG::INTERSECTION, &spleaf1, &sp3);
+
+    spleaf2.setTransform(translation(4, 1, -0.1) *  rotationY(0.35));
+    w.addObject(&spleaf2);
+
+    /* ----------------------------- */
+
+    Group grp = Group();
+    int i;
+#define SLICE_NUM (12)
+    for(i = 0; i < SLICE_NUM; i++)
+    {
+        Cube *c = new Cube();
+
+        c->setTransform(rotationY((2*M_PI / SLICE_NUM) * i) * scaling(0.1, 1.1, 0.7) * translation(0, 0, 0.9));
+        c->dropShadow = false;
+        grp.addObject(c);
+    }
+
+    grp.materialSet = true;
+    grp.dropShadow = false;
+    grp.material.ambient = 0;
+    grp.material.diffuse = 0.1;
+    grp.material.specular = 0;
+    grp.material.transparency = 1;
+    grp.material.reflective = 1;
+    grp.material.refractiveIndex = 1;
+
+    Sphere ballSp = Sphere();
+    ballSp.materialSet = true;
+    ballSp.material.colour = Colour(0.7, 0.2, 0.1);
+    CSG ballLeaf = CSG(CSG::INTERSECTION, &grp, &ballSp);
+
+    ballLeaf.setTransform(translation(-4, 1, -0.1) *  rotationY(-0.35) * rotationZ(0.1));
+    w.addObject(&ballLeaf);
+
+    /* ----------------------------- */
+
     /* Set the camera */
-    Camera camera = Camera(800, 400, M_PI / 2);
-    camera.setTransform(viewTransform(Point(-4, 4, -9),
+    Camera camera = Camera(80, 40, M_PI / 2);
+    camera.setTransform(viewTransform(Point(0, 3, 5),
                                       Point(0, 1, 0),
                                       Vector(0, 1, 0)));
 

+ 1 - 1
tests/cylinder_test.cpp

@@ -59,7 +59,7 @@ TEST(CylinderTest, A_ray_hit_a_cylinder)
     double t0s[] = { 5, 4, 6.80798 };
     double t1s[] = { 5, 6, 7.08872 };
 
-    int i, j;
+    int i;
     for(i = 0; i < 3; i++)
     {
         Tuple direction = Directions[i].normalise();

+ 0 - 1
tests/plane_test.cpp

@@ -73,7 +73,6 @@ TEST(PlaneTest, A_ray_intersecting_a_plane_from_below)
 TEST(PlaneTest, The_bounding_box_of_a_plane)
 {
     Plane t = Plane();
-    BoundingBox b = BoundingBox(Point(-8, -5, -8), Point(8, 8, 8));
     BoundingBox res = t.getBounds();
 
     ASSERT_FALSE(res.min.isRepresentable());

+ 1 - 1
tests/test_render.cpp

@@ -54,7 +54,7 @@ int main()
     Plane p4 = Plane();
     p3.setTransform(translation(6, 0, 0) * rotationZ(M_PI/2) );
     p3.material.pattern = new CheckersPattern(Colour(1, 1, 1), Colour(0.1, 0.1, 0.1));
-    w.addObject(&p3);
+    w.addObject(&p4);
 
     Plane p5 = Plane();
     p5.material.pattern = new CheckersPattern(Colour(1, 1, 1), Colour(0.1, 0.1, 0.1));

+ 1 - 1
tests/uvmap_skybox.cpp

@@ -31,7 +31,7 @@ int main()
     Light light = Light(POINT_LIGHT, Point(0, 100, 0), Colour(1, 1, 1));
     w.addLight(&light);
 
-    Sphere sp = Sphere();;
+    Sphere sp = Sphere();
     sp.setTransform(translation(0, 0, 5) * scaling(0.75, 0.75, 0.75));
     sp.material.diffuse = 0.4;
     sp.material.specular = 0.6;

+ 2 - 2
tests/world_test.cpp

@@ -44,7 +44,7 @@ TEST(WorldTest, The_default_world)
     ASSERT_TRUE(w.lightIsIn(l));
     ASSERT_TRUE(w.objectIsIn(s1));
     ASSERT_TRUE(w.objectIsIn(s2));
-};
+}
 
 TEST(WorldTest, Intersect_a_world_with_a_ray)
 {
@@ -169,7 +169,7 @@ TEST(WorldTest, Shade_hit_is_given_an_intersection_in_shadow)
     Tuple c = w.shadeHit(comps);
 
     ASSERT_EQ(c, Colour(0.1, 0.1, 0.1));
-};
+}
 
 TEST(WorldTest, The_reflected_colour_for_a_non_reflective_material)
 {