Working on worlds.
It's currently crashing.
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
@@ -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})
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user