Browse Source

Working on worlds.

It's currently crashing.
Godzil 4 years ago
parent
commit
a82b67faa4

+ 4 - 0
source/include/light.h

@@ -27,6 +27,10 @@ public:
 public:
     Light(LightType type = POINT_LIGHT, Tuple position=Point(0, 0, 0),
           Colour intensity=Colour(1, 1, 1)) : type(type), position(position), intensity(intensity) { };
+
+    bool operator==(const Light &b) const { return this->intensity == b.intensity &&
+                                                   this->position == b.position &&
+                                                   this->type == b.type; };
 };
 
 #endif //DORAYME_LIGHT_H

+ 15 - 1
source/include/shape.h

@@ -17,16 +17,25 @@ class Shape;
 #include <intersect.h>
 #include <material.h>
 
+enum ShapeType
+{
+    SHAPE_NONE,
+    SHAPE_SPHERE,
+};
+
 /* Base class for all object that can be presented in the world */
 class Shape
 {
+private:
+    ShapeType type;
+
 public:
     Matrix transformMatrix;
     Matrix inverseTransform;
     Material material;
 
 public:
-    Shape();
+    Shape(ShapeType = SHAPE_NONE);
 
     virtual Intersect intersect(Ray r);
     virtual Tuple normalAt(Tuple point);
@@ -35,6 +44,11 @@ public:
     void setMaterial(Material material) { this->material = material; };
     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 &&
+                                                   this->transformMatrix == b.transformMatrix; };
+
 };
 
 #endif //DORAYME_SHAPE_H

+ 1 - 0
source/include/sphere.h

@@ -16,6 +16,7 @@
 class Sphere : public Shape
 {
 public:
+    Sphere() : Shape(SHAPE_SPHERE) { };
     /* All sphere are at (0, 0, 0) and radius 1 in the object space */
     virtual Intersect intersect(Ray r);
     virtual Tuple normalAt(Tuple point);

+ 16 - 3
source/include/world.h

@@ -12,6 +12,8 @@
 #include <stdint.h>
 #include <light.h>
 #include <shape.h>
+#include <intersect.h>
+#include <ray.h>
 
 class World
 {
@@ -23,11 +25,22 @@ private:
     uint32_t allocatedObjectCount;
     uint32_t allocatedLightCount;
 
-    Light *lightList;
-    Shape *shapeList;
+    Light* *lightList;
+    Shape* *objectList;
 
 public:
-    World() : objectCount(0), lightCount(0) { };
+    World();
+    ~World();
+
+    void addObject(Shape *s);
+    void addLight(Light *l);
+
+    /* Some debug things */
+    bool lightIsIn(Light &l);
+    bool objectIsIn(Shape &s);
+
+    Intersect intersect(Ray r);
+
 };
 
 #endif //DORAYME_WORLD_H

+ 2 - 2
source/include/worldbuilder.h

@@ -13,14 +13,14 @@
 
 /* Let's keep a single header for now, will see later */
 
-class DefaultWorld : World
+class DefaultWorld : public World
 {
 public:
     DefaultWorld();
 };
 
 /* Not implemented yet */
-class Hw3File : World
+class Hw3File : public World
 {
 public:
     Hw3File(const char *filename);

+ 3 - 3
source/intersect.cpp

@@ -17,16 +17,16 @@
 Intersect::Intersect()
 {
     this->allocated = MIN_ALLOC;
-    this->list = (Intersection *)calloc(sizeof(Shape *), MIN_ALLOC);
+    this->list = (Intersection *)calloc(sizeof(Intersection *), MIN_ALLOC);
     this->num = 0;
 }
 
 void Intersect::add(Intersection i)
 {
-    if ((this->num + 1) < this->allocated)
+    if ((this->num + 1) > this->allocated)
     {
         this->allocated *= 2;
-        this->list = (Intersection *)realloc(this->list, sizeof(Shape *) * this->allocated);
+        this->list = (Intersection *)realloc(this->list, sizeof(Intersection *) * this->allocated);
     }
     this->list[this->num++] = i;
 }

+ 2 - 1
source/shapes/shape.cpp

@@ -13,8 +13,9 @@
 #include <tuple.h>
 #include <intersect.h>
 
-Shape::Shape()
+Shape::Shape(ShapeType type)
 {
+    this->type = type;
     this->transformMatrix = Matrix4().identity();
     this->inverseTransform = this->transformMatrix.inverse();
 }

+ 86 - 1
source/world.cpp

@@ -5,4 +5,89 @@
  *  Created by Manoël Trapier
  *  Copyright (c) 2020 986-Studio.
  *
- */
+ */
+#include <world.h>
+#include <light.h>
+#include <shape.h>
+
+#define MIN_ALLOC (2)
+
+World::World() : objectCount(0), lightCount(0)
+{
+    this->allocatedLightCount = MIN_ALLOC;
+    this->lightList = (Light **)calloc(sizeof(Light *), MIN_ALLOC);
+    this->lightCount = 0;
+
+    this->allocatedObjectCount = MIN_ALLOC;
+    this->objectList = (Shape **)calloc(sizeof(Shape *), MIN_ALLOC);
+    this->objectCount = 0;
+};
+
+World::~World()
+{
+    /* We need to do some cleanup... */
+}
+
+void World::addObject(Shape *s)
+{
+    if ((this->objectCount + 1) > this->allocatedObjectCount)
+    {
+        this->allocatedObjectCount *= 2;
+        this->objectList = (Shape **)realloc(this->objectList, sizeof(Shape **) * this->allocatedObjectCount);
+    }
+    this->objectList[this->objectCount++] = s;
+}
+
+void World::addLight(Light *l)
+{
+    if ((this->lightCount + 1) > this->allocatedLightCount)
+    {
+        this->allocatedLightCount *= 2;
+        this->lightList = (Light **)realloc(this->lightList, sizeof(Light **) * this->allocatedLightCount);
+    }
+    this->lightList[this->lightCount++] = l;
+}
+
+bool World::lightIsIn(Light &l)
+{
+    int i;
+    for(i = 0; i < this->lightCount; i++)
+    {
+        if (*this->lightList[i] == l)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool World::objectIsIn(Shape &s)
+{
+    int i;
+    for(i = 0; i < this->objectCount; i++)
+    {
+        if (*this->objectList[i] == s)
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+Intersect World::intersect(Ray r)
+{
+    Intersect ret;
+    int i, j;
+
+    for(i = 0; i < this->objectCount; i++)
+    {
+        Intersect xs = this->objectList[i]->intersect(r);
+
+        for(j = 0; xs.count(); j++)
+        {
+            ret.add(xs[i]);
+        }
+    }
+
+    return ret;
+}

+ 20 - 1
source/worldbuilder/default_world.cpp

@@ -9,7 +9,26 @@
 #include <worldbuilder.h>
 #include <world.h>
 
+#include <sphere.h>
+#include <light.h>
+#include <material.h>
+#include <transformation.h>
+
 DefaultWorld::DefaultWorld()
 {
+    Light *l = new Light(POINT_LIGHT, Point(-10, 10, -10), Colour(1, 1, 1));
+    Sphere *s1 = new Sphere();
+    Sphere *s2 = new Sphere();
+    Material s1Mat = Material();
+    s1Mat.colour = Colour(0.8, 1.0, 0.6);
+    s1Mat.diffuse = 0.7;
+    s1Mat.specular = 0.2;
+    s1->setMaterial(s1Mat);
+
+    s2->setTransform(scaling(0.5, 0.5,0.5));
+
+    this->addLight(l);
 
-}
+    this->addObject(s1);
+    this->addObject(s2);
+}

+ 1 - 1
tests/CMakeLists.txt

@@ -4,7 +4,7 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
 find_package(Threads REQUIRED)
 
 set(TESTS_SRC tuple_test.cpp colour_test.cpp canvas_test.cpp matrix_test.cpp transformation_test.cpp ray_test.cpp
-        intersect_test.cpp sphere_test.cpp light_test.cpp material_test.cpp)
+        intersect_test.cpp sphere_test.cpp light_test.cpp material_test.cpp world_test.cpp)
 
 add_executable(testMyRays)
 target_include_directories(testMyRays PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})

+ 45 - 2
tests/world_test.cpp

@@ -7,11 +7,54 @@
  *
  */
 #include <world.h>
+#include <light.h>
+#include <sphere.h>
+#include <material.h>
+#include <transformation.h>
+#include <worldbuilder.h>
 #include <math.h>
 #include <gtest/gtest.h>
 
 
-TEST(WorldTest, Test_for_an_empty_world)
+TEST(WorldTest, Creating_a_world)
 {
+    World w;
+
+    ASSERT_EQ(w.lightCount, 0);
+    ASSERT_EQ(w.objectCount, 0);
+}
+
+TEST(WorldTest, The_default_world)
+{
+    World w = DefaultWorld();
+
+    Light l = Light(POINT_LIGHT, Point(-10, 10, -10), Colour(1, 1, 1));
+    Sphere s1 = Sphere();
+    Sphere s2 = Sphere();
+    Material s1Mat = Material();
+    s1Mat.colour = Colour(0.8, 1.0, 0.6);
+    s1Mat.diffuse = 0.7;
+    s1Mat.specular = 0.2;
+    s1.setMaterial(s1Mat);
+
+    s2.setTransform(scaling(0.5, 0.5,0.5));
+
+    ASSERT_TRUE(w.lightIsIn(l));
+    ASSERT_TRUE(w.objectIsIn(s1));
+    ASSERT_TRUE(w.objectIsIn(s2));
+};
+
+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);
+
+    ASSERT_EQ(xs.count(), 4);
+    ASSERT_EQ(xs[0].t, 4);
+    ASSERT_EQ(xs[1].t, 4.5);
+    ASSERT_EQ(xs[2].t, 5.5);
+    ASSERT_EQ(xs[3].t, 6);
+}
 
-}