Browse Source

Started working on boundingboxes.

Godzil 4 years ago
parent
commit
3011544e8f

+ 21 - 0
source/include/boundingbox.h

@@ -0,0 +1,21 @@
+/*
+ *  DoRayMe - a quick and dirty Raytracer
+ *  Bounding box header
+ *
+ *  Created by Manoël Trapier
+ *  Copyright (c) 2020 986-Studio.
+ *
+ */
+#ifndef DORAYME_BOUNDINGBOX_H
+#define DORAYME_BOUNDINGBOX_H
+
+struct BoundingBox
+{
+    Tuple min;
+    Tuple max;
+
+    BoundingBox() : min(-0, -0, -0), max(0, 0, 0) { };
+    BoundingBox(Tuple min, Tuple max) : min(min), max(max) { };
+};
+
+#endif //DORAYME_BOUNDINGBOX_H

+ 1 - 0
source/include/cone.h

@@ -28,6 +28,7 @@ public:
     double maxCap;
 
     Cone() : minCap(-INFINITY), maxCap(INFINITY), isClosed(false), Shape(SHAPE_CONE) {};
+    BoundingBox getBounds();
 };
 
 #endif /* DORAYME_CONE_H */

+ 2 - 0
source/include/cylinder.h

@@ -28,6 +28,8 @@ public:
     double maxCap;
 
     Cylinder() : minCap(-INFINITY), maxCap(INFINITY), isClosed(false), Shape(SHAPE_CYLINDER) {};
+
+    BoundingBox getBounds();
 };
 
 #endif //DORAYME_CYLINDER_H

+ 2 - 0
source/include/group.h

@@ -32,6 +32,8 @@ public:
 
     Intersect intersect(Ray r);
 
+    BoundingBox getBounds();
+
     Group();
 };
 

+ 1 - 0
source/include/plane.h

@@ -17,6 +17,7 @@ private:
 
 public:
     Plane() : Shape(SHAPE_PLANE) { };
+    BoundingBox getBounds();
 };
 
 #endif //DORAYME_PLANE_H

+ 5 - 2
source/include/shape.h

@@ -16,6 +16,7 @@ class Shape;
 #include <matrix.h>
 #include <intersect.h>
 #include <material.h>
+#include <boundingbox.h>
 
 enum ShapeType
 {
@@ -51,13 +52,15 @@ public:
 public:
     Shape(ShapeType = SHAPE_NONE);
 
-    Intersect intersect(Ray r);
+    virtual Intersect intersect(Ray r);
     Tuple normalAt(Tuple point);
 
-    //virtual Bounds getBounds();
+    /* Bouding box points are always world value */
+    virtual BoundingBox getBounds();
 
     void updateTransform();
     Tuple worldToObject(Tuple point) { return this->inverseTransform * point; };
+    Tuple objectToWorld(Tuple point) { return this->transformMatrix * point; };
     Tuple normalToWorld(Tuple normalVector);
 
     void setTransform(Matrix transform);

+ 4 - 0
source/include/tuple.h

@@ -17,6 +17,7 @@ public:
     double x, y, z, w;
 
 public:
+    Tuple() : x(0), y(0), z(0), w(0.0) {};
     Tuple(double x, double y, double z) : x(x), y(y), z(z), w(0.0) {};
     Tuple(double x, double y, double z, double w)  : x(x), y(y), z(z), w(w) {};
     bool isPoint()  { return (this->w == 1.0); };
@@ -39,6 +40,7 @@ public:
     Tuple operator/(const double &b) const { return Tuple(this->x / b, this->y / b,
                                                           this->z / b, this->w / b); };
 
+    void set(double nX, double nY, double nZ) { this->x = nX; this->y = nY; this->z = nZ; };
     double magnitude();
     Tuple normalise();
     double dot(const Tuple &b);
@@ -49,12 +51,14 @@ public:
 class Point: public Tuple
 {
 public:
+    Point() : Tuple(0, 0, 0, 1.0) {};
     Point(double x, double y, double z) : Tuple(x, y, z, 1.0) {};
 };
 
 class Vector: public Tuple
 {
 public:
+    Vector() : Tuple(0, 0, 0, 0.0) {};
     Vector(double x, double y, double z) : Tuple(x, y, z, 0.0) {};
 };
 

+ 10 - 0
source/shapes/cone.cpp

@@ -122,3 +122,13 @@ Tuple Cone::localNormalAt(Tuple point)
     }
     return Vector(point.x, y, point.z);
 }
+
+BoundingBox Cone::getBounds()
+{
+    BoundingBox ret;
+
+    ret.min = this->objectToWorld(Point(-1, this->minCap, -1));
+    ret.max = this->objectToWorld(Point(1, this->maxCap, 1));
+
+    return ret;
+}

+ 10 - 0
source/shapes/cylinder.cpp

@@ -107,3 +107,13 @@ Tuple Cylinder::localNormalAt(Tuple point)
 
     return Vector(point.x, 0, point.z);
 }
+
+BoundingBox Cylinder::getBounds()
+{
+    BoundingBox ret;
+
+    ret.min = this->objectToWorld(Point(-1, this->minCap, -1));
+    ret.max = this->objectToWorld(Point(1, this->maxCap, 1));
+
+    return ret;
+}

+ 27 - 0
source/shapes/group.cpp

@@ -70,4 +70,31 @@ void Group::addObject(Shape *s)
 bool Group::isEmpty()
 {
     return (this->objectCount == 0);
+}
+
+BoundingBox Group::getBounds()
+{
+    BoundingBox ret;
+
+    if (this->objectCount > 0)
+    {
+        ret.min = Point(INFINITY, INFINITY, INFINITY);
+        ret.max = Point(-INFINITY, -INFINITY, -INFINITY);
+
+        int i;
+        for(i = 0; i < this->objectCount; i++)
+        {
+            BoundingBox obj = this->objectList[i]->getBounds();
+
+            if (ret.min.x > obj.min.x) {  ret.min.x = obj.min.x; }
+            if (ret.min.y > obj.min.y) {  ret.min.y = obj.min.y; }
+            if (ret.min.z > obj.min.z) {  ret.min.z = obj.min.z; }
+
+            if (ret.max.x < obj.max.x) {  ret.max.x = obj.max.x; }
+            if (ret.max.y < obj.max.y) {  ret.max.y = obj.max.y; }
+            if (ret.max.z < obj.max.z) {  ret.max.z = obj.max.z; }
+        }
+    }
+
+    return ret;
 }

+ 10 - 0
source/shapes/plane.cpp

@@ -33,4 +33,14 @@ Intersect Plane::localIntersect(Ray r)
 Tuple Plane::localNormalAt(Tuple point)
 {
     return Vector(0, 1, 0);
+}
+
+BoundingBox Plane::getBounds()
+{
+    BoundingBox ret;
+
+    ret.min = this->objectToWorld(Point(-INFINITY, 0-getEpsilon(), -INFINITY));
+    ret.max = this->objectToWorld(Point(INFINITY, 0+getEpsilon(), INFINITY));
+
+    return ret;
 }

+ 9 - 0
source/shapes/shape.cpp

@@ -65,3 +65,12 @@ void Shape::setTransform(Matrix transform)
     this->localTransformMatrix = transform;
     this->updateTransform();
 }
+
+BoundingBox Shape::getBounds()
+{
+    BoundingBox ret;
+
+    ret.min = this->objectToWorld(Point(-1, -1, -1));
+    ret.max = this->objectToWorld(Point(1, 1, 1));
+    return ret;
+}

+ 12 - 1
tests/shape_test.cpp

@@ -163,4 +163,15 @@ TEST(TestShape, Finding_the_normal_on_a_child_object)
     ASSERT_EQ(p, Vector(0.2857, 0.4286, -0.8571));
 
     set_equal_precision(FLT_EPSILON);
-}
+}
+
+TEST(TestShape, Test_the_bouding_box_of_the_test_shape)
+{
+    TestShape t = TestShape();
+    BoundingBox b = BoundingBox(Point(-1, -1, -1), Point(1, 1, 1));
+
+    BoundingBox res = t.getBounds();
+
+    ASSERT_EQ(res.min, b.min);
+    ASSERT_EQ(res.max, b.max);
+}