I am creating a raytracer and I can't implement Scene
class. I want it to have a std::vector
with every object in the scene (Sphere
, Polygon
, Mesh
, etc.) and a std::vector
with every light source in scene (DirectionalLight
, PointLight
, etc.)
So I want to have multiple types (that are derived from one base class) in one container. Is anything like this possible? Or, do I even need something like this, and there is a better solution?
I have tried creating std::vector<std::unique_ptr<PrimitiveObject>>
and std::vector<std::unique_ptr<Light>>
, that is, tried to save objects as base class unique pointers, but I stumbled upon a problem described here.
Update:
Here is what I tried exactly (minimal reproducible example):
#include <iostream>
#include <vector>
#include <memory>
struct color_t
{
unsigned char r, g, b, a;
};
struct vec3d
{
double x, y, z;
};
class Object
{
public:
vec3d position;
};
class Sphere : public Object
{
public:
Sphere(vec3d center, double radius, color_t color)
{
this->position = center;
this->radius = radius;
this->color = color;
}
double radius;
color_t color;
};
int main()
{
std::unique_ptr<Sphere> p_sphere = std::make_unique<Sphere>(Sphere({0, 0, 2}, 1, {0, 0, 255, 255}));
std::cout << p_sphere->position.x << std::endl;
std::cout << p_sphere->radius << std::endl; // okay here
// I want this vector to be able to hold a unique pointer to an
// object of any class that is derived from `Object` class
std::vector<std::unique_ptr<Object>> objects;
objects.push_back(std::move(p_sphere));
std::cout << objects[0]->position.x << std::endl;
std::cout << objects[0]->radius << std::endl; // error: ‘class Object’ has no member named ‘radius’
}