Apologies for the vague title, but I can’t summarize my question in a few words.
I’m trying to figure out the best way to instance objects within my homebrew renderer (C++) without incuring too much overhead. I would also like to make the relationship between an object and an instance of an object as transparent as possible to the ray-hit framework.
Question 1) Where’s the best place to store an object’s scaling/translation/rotation matrixes. It seems to me that an object’s coordinates should remain in “object space (OS)”, thus an object’s OS position and orientation should be contained within it’s class.
And if an object isn’t instanced, then it should be ok to keep the matrixes required to move the object into “world space (WS)”.
But, if an object is instanced, then it seems rational to me to keep the matrixes in a seperate object (say InstanceObject) along with a pointer to the object. This way, we only have to load all of the polygons, splines, whatever into the object once, then create an InstanceObject object, passing in the pointer and a string as an identifier, and assign it a bunch of matrixes.
This leads me to question 2…
- Will this method bring my CPU to its knees?
If I were to implement such a system, then everytime that a ray/object-boundingvolume is encountered, then I’ll have to calculate all of those matrix translations/etc… on the fly. I really don’t like that idea very much.
Below are some snippets of a few of my class headers. Hopefully they’ll help illustrate the path that I’m taking, and maybe someone will notice any logic errors.
First, the class header to my Abstract Base Class, the “obj” class:
class obj
{
public:
virtual ~obj() {};
virtual bool hit( const Imath::V3f & p ) = 0;
virtual const Imath::V3f & normal() = 0;
virtual const Imath::Sphere3f & getSphere() const { return _sphere; };
protected:
Imath::Sphere3f _sphere;
};
Now the ObjInstance class, used to hold the matrixes and pointer to the object:
A class to hold a group of “obj” pointers:
class ObjGroup
{
public:
ObjGroup( const char * groupName );
bool addMember( obj * o );
unsigned int count() const;
private:
std::deque< obj * > _objList;
};
class ObjInstance
{
public:
ObjInstance( ObjGroup * group, const char * groupName );
virtual ~ObjInstance();
const char * getName() const;
const ObjGroup * getObjGroup() const;
void setTranslationMatrix( const Imath::M44f & translationMatrix );
void setRotationMatrix( const Imath::M44f & rotationMatrix );
void setScaleMatrix( const Imath::M44f & scaleMatrix );
const Imath::M44f & getTranslationMatrix() const;
const Imath::M44f & getRotationMatrix() const;
const Imath::M44f & getScaleMatrix() const;
typedef std::pair< const char *, ObjGroup * > InstancePair;
private:
InstancePair _pair;
Imath::M44f _translationMatrix;
Imath::M44f _rotationMatrix;
Imath::M44f _scaleMatrix;
};
And finally, a typedef to hold all of the instances:
typedef std::map< const char *, ObjGroup * > ObjGroupMap;
ObjGroupMap instanceDB;
It’s late, and I may not have been as clear as I could’ve been during more reasonable hours, but this is driving me crazy. Any help/pointers would be greatly appreciated.