The aim of this post is to develop an efficient mechanism for attaching meshes to other meshes, such as weapons to animated models.
When we load a model (static or animated), we must remember to always treat that loaded object as a REFERENCE OBJECT, because we intend to have N INSTANCES of that Ref object, sharing ONE resource.
Therefore it seems a bad idea to manipulate the frame hierarchy of our Ref object when it comes to attaching one hierarchy to another, unless we wish ALL INSTANCES to have this new attachment.
Let's assume we want individual instances to have different attachments.
The problem now is that since we're memory-conscious asm coders, our 'instance struct' doesn't have its own copy of the model's frame hierarchy - we're relying on the one shared copy of that.
So how can our instance know where the attachment should go?
If we merely keep framepointers in our instance structs, then we'll be required to enumerate all instances from within the Model's Frame Update function, which is recursive, so that's a REALLY BAD IDEA.
Maybe altering the Ref object isn't such a bad idea after all, IF we do it conscientiously.
Let's extend our already derived Frame struct a little further, so that we can tag Frames as being of various Types.
Now we can mark all Frames (during loading) as being of 'Original Type', and if we go adding any other Frames to the hierarchy later, we can mark those as being of 'OTHER Types'.
Our Model is responsible for deallocating only the Frames marked as ORIGINAL Type, but it will happily calculate the Combined Matrix for ALL FRAMES in the Hierarchy. Note that this behaviour can be switched selectively for a given Type at runtime.
Now we can attach Ref objects to other Ref objects, and have a way to tell within a hierarchy which Frames are 'glue-ons' and which are 'original'.
During Rendering, we walk all the Original frames, and we SELECTIVELY walk the OTHER Frames.
But what's all this got to do with Scene Graphs?
Well, our SceneGraph is a frame hierarchy too, but ALL its frames (nodes) are of 'Other Type'.
Each node in our SceneGraph represents an INSTANCE of a Ref object in our World.
The structure of our SceneGraph is almost identical to that of our Ref object frame hierarchies, in fact its simpler, it contains ONLY a tree of instances.
It makes sense to use the SAME derived frame struct and take advantage of the new Type field for this purpose also !!
The render logic is as follows:
We walk the SceneGraph (which may also contain space partitioning data), and for each Potentially Visible (unculled) instance, we update and render, following any 'Switch' frames that are specified by that Instance, and disregarding any which are not.
Yes, we have to walk the Ref object N times.
This can ONLY be avoided if the Combined Ref Object CONTAINS NO ANIMATIONS.
In this special case ALONE, we can precalculate the COMBINED MATRICES just ONCE, storing it within the Instance, and then combining it at the last moment with one dynamic matrix for last-moment position,rotation and scale of the combined object.
We never have to Walk such an object's hierarchy :)