In a large code base like ours, with a lot of different plugins operating on scene nodes, it is very difficult to make sure that the !mCachedTransformOutOfDate assertion is never triggered by a Node::_getDerivedXXX(). I understand the reason for the changes in node updates, but I think usability has been sacrificed too much, and in the end it is very likely to lead to worse performance because the user will be tempted to use the _getDerivedXXXUpdated() over _getDerivedXXX() too often.
Below is a summary for some of the problems and potential fixes. I might have misunderstand some things though, so feel free to correct me.
Some problems:
1.
Code: Select all
node->_setDerivedPosition(Ogre::Vector3(10.0f, 0.0f, 0.0f));
...
Ogre::Vector3 derivedPos = node->_getDerivedPosition(); // assert( !mCachedTransformOutOfDate );
2.
Code: Select all
parentNode->_setDerivedPosition(Ogre::Vector3(10.0f, 0.0f, 0.0f));
childNode = parentNode->getChild(0);
...
childNode->_setDerivedPosition(Ogre::Vector3(20.0f, 0.0f, 0.0f)) // assert( !mCachedTransformOutOfDate );
3. Node::_updateFromParent() seems to potentially be much more expensive for a single node than in 1.x, since it updates transforms for multiple nodes (the SoA) and for all parents (and their SoA), and it does not skip the update if already up-to-date (checking mCachedTransformOutOfDate, or mNeedParentUpdate in Ogre 1.x).
4. Node::updateFromParentImpl() is only triggered when the user calls any of the _getDerivedXXXUpdated(), while Node::updateAllTransforms() is triggered by UpdateSceneGraph(). Then why is it necessary for Node::updateFromParentImpl() to update the SoA? Couldn't it just update its own transforms?
5. There is no function Node::_getCachedDerivedXXX(). If you are running RELEASE build and are not concerned about the last update, you can use _getDerivedXXX(), but in DEBUG you might get the mCachedTransformOutOfDate assertion, which makes it tempting to branch on the DEBUG code to use _getDerivedXXXUpdated() instead...
Suggestions of improvements:
* It should be quicker to update the derived transform of a single node.
* It should be possible to explicitly get the cached transform (using same code in RELEASE and DEBUG).
* These changes must not have performance impact on UpdateSceneGraph().
1. Change updateFromParentImpl() to only update its own transform, mTransform.mDerivedTransform[mTransform.mIndex].
2. Define mCachedTransformOutOfDate also in RELEASE build, but without assertions. Change _updateFromParent() to call updateFromParentImpl only if mCachedTransformOutOfDate is true.
3. Add _getCachedDerivedXXX() (similar to what is done in OgreCamera.h).
What do you think of these suggestion? Will they mess things up? I am thinking of implementing something like this in our own Ogre branch, but it would be best if it was integrated in the Ogre main branch.