Working on worlds.

It's currently crashing.
This commit is contained in:
Godzil
2020-02-19 18:05:48 +00:00
parent efe46e2864
commit a82b67faa4
11 changed files with 195 additions and 15 deletions

View File

@@ -27,6 +27,10 @@ public:
public: public:
Light(LightType type = POINT_LIGHT, Tuple position=Point(0, 0, 0), Light(LightType type = POINT_LIGHT, Tuple position=Point(0, 0, 0),
Colour intensity=Colour(1, 1, 1)) : type(type), position(position), intensity(intensity) { }; 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 #endif //DORAYME_LIGHT_H

View File

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

View File

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

View File

@@ -12,6 +12,8 @@
#include <stdint.h> #include <stdint.h>
#include <light.h> #include <light.h>
#include <shape.h> #include <shape.h>
#include <intersect.h>
#include <ray.h>
class World class World
{ {
@@ -23,11 +25,22 @@ private:
uint32_t allocatedObjectCount; uint32_t allocatedObjectCount;
uint32_t allocatedLightCount; uint32_t allocatedLightCount;
Light *lightList; Light* *lightList;
Shape *shapeList; Shape* *objectList;
public: 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 #endif //DORAYME_WORLD_H

View File

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

View File

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

View File

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

View File

@@ -6,3 +6,88 @@
* Copyright (c) 2020 986-Studio. * 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;
}

View File

@@ -9,7 +9,26 @@
#include <worldbuilder.h> #include <worldbuilder.h>
#include <world.h> #include <world.h>
#include <sphere.h>
#include <light.h>
#include <material.h>
#include <transformation.h>
DefaultWorld::DefaultWorld() 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);
} }

View File

@@ -4,7 +4,7 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED) 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 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) add_executable(testMyRays)
target_include_directories(testMyRays PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR}) target_include_directories(testMyRays PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})

View File

@@ -7,11 +7,54 @@
* *
*/ */
#include <world.h> #include <world.h>
#include <light.h>
#include <sphere.h>
#include <material.h>
#include <transformation.h>
#include <worldbuilder.h>
#include <math.h> #include <math.h>
#include <gtest/gtest.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);
}