views:

107

answers:

4

I'm writing a raytracer in C++ and need to be able to check intersections with every object in a scene (optimizations will come later), and to do this, I need to keep a running list of class instances. A list of pointers, updated when a new instance is created, won't work because as far as I know there is no way to increase the size of the array after it is initialized. I'd really like a built-in (to C++) solution if there is one.

+3  A: 

A std::vector should be fine (and it is part of the C++ standard).

Alex Martelli
Since the memory location for each object will be unique (as each object is created independently), you only need to store a pointer to each object in the vector, which makes things a little easier.
fluffels
+3  A: 

Create a vector (or set) of pointers to the objects in your scene as a static class member, and have all your ctors insert this into the collection, and the dtor delete this from the collection:

// really pseudo-code -- not intended to compile as-is, but I hope it helps
// convey the general idea.
//
class scene_object { 
    static std::set<scene_object const *> instances;
public:

    scene_object() : { instances.insert(this); }
    scene_object(scene_object const &other) { instances.insert(this); }
    // probably more ctors here...

    ~scene_object() { instances.delete(this); }
};

std::set<scene_object> scene_object::instances;
Jerry Coffin
+5  A: 

There are any number of STL Containers you could use.

STL Container Reference

DrDeth
+3  A: 

I'm writing a raytracer in C++ and need to be able to check intersections with every object in a scene [...]

The standard approach is a spatial graph. Most commonly, octrees are used, since they can express location in 3-dimensional space. Trivially, the spatial tree would look something like this:

struct SpatialNode {
    SpatialNode * children[8];
    std::vector<object*> objects;
};

Each node has an (implicit or explicit) position and size. When a new object is added to the world scene, the tree is walked through the children (which occupy the octants that are split by the x-y, y-z, and z-x planes: 4 above, 4 below; 4 left, 4 right; 4 behind, 4 in front) and the object is added only to the smallest node that can fully contain it. (Obviously, you'll need to be able to calculate the dimensions of your object and whether they can be fully contained within a given region.)

This has the benefit of being fairly fast (only the portions of the tree that are examined are actually relevant), both in populating it and in searching it. There are several articles on it that you can read at Wikipedia, GameDev.net, and elsewhere.

greyfade
I'm accepting this answer because it showed me why I should use an optimized structure to begin with. Thanks!
Andre Boos