Does Ogre support custom visibility settings which are impossible to describe by the visibility flags?(...)
The short answer is no.
Now onto solutions (thinking out loud, just like you're doing):
Toggling visibility
it is necessary to iterate over all objects just before rendering each window. Is it the way to go? Is there something else?
Considering the alternative you were proposing, this isn't actually a bad idea
You could iterate each MovableObject and call MovableObject::setVisible() or a different pair of visibility flags.
You could do this in CompositorWorkspaceListener.
Suggestion:
For maximum performance you could use MovableObject::_getObjectData and iterate ObjectData::mVisibilityFlags instead. This is crazy fast and can also be parallelized.
Code: Select all
for( size_t i = 0u; i < NUM_SCENE_MEMORY_MANAGER_TYPES; ++i )
{
ObjectMemoryManager &objMemoryManager =
sceneManager->_getEntityMemoryManager( static_cast<SceneMemoryMgrTypes>( i ) );
const size_t numRenderQueues = objMemoryManager.getNumRenderQueues();
for( size_t j = 0u; j < numRenderQueues; ++j )
{
ObjectData objData;
const size_t totalObjs = objMemoryManager.getFirstObjectData( objData, j );
for( size_t k = 0u; k < totalObjs; k += ARRAY_PACKED_REALS )
{
for( size_t l = 0; l < ARRAY_PACKED_REALS; ++l )
{
// owner is guaranteed to NOT be a nullptr.
// However it can be a dummy ptr, see ObjectMemoryManager::mDummyObject.
// Do not set the dummy ptr to being visible.
MovableObject *owner = objData.mOwner[l];
objData.mVisibilityFlags[l] = whatever; // based on owner.
}
objData.advanceCullLightPack();
}
}
}
Remember that you can use MovableObject::getUserObjectBindings for storing arbitrary data (though this isn't exactly fast I think).
Separate Scene Graphs
Beware that a MovableObject can only be attached one SceneNode, it can't be attached to multiple SceneNodes at the same time. Furthermore SceneNode::setVisible just ends up calling MovableObject::setVisible.
However you can have multiple MovableObjects (i.e. duplicated Items) attached to the same SceneNode with different flags. That would work.
If memory is a concern, you could try creating a custom MovableObject (see Samples/2.0/ApiUsage/CustomRenderable) but unlike MyCustomRenderable, you only derive from MovableObject but not Renderable. Then add the SubItem's to MyCustomRenderable::mRenderables
. Something like this (pseudo C++):
Code: Select all
class MyCustomRenderable final : public MovableObject
{
MyCustomRenderable( /*...*/ , Item *item )
{
// Do not worry about the WorldAabb/Radius. They'll fill themselves.
mObjectData.mLocalAabb->setFromAabb( item->getLocalAabb(), mObjectData.mIndex );
mObjectData.mLocalRadius[mObjectData.mIndex] = item->getLocalRadius();
for( each subitem in item )
mRenderables.push_back( subitem );
}
/* Other overrides like MyCustomRenderable::getWorldTransforms et al stay the same */
}
I don't know if it will work, but it may; as long as you're not using skeletons (if you do, it may need a bit more work so your MyCustomRenderable replicates the Item's functionality and then use useSkeletonInstanceFrom).
The advantage is that you will have:
-
Same SceneNode (share position, rotation, scale) as long as you attach the clones to the same node.
-
Same materials (since they share the SubItems).
-
Separate visibility settings.
-
Separate RenderQueue IDs.
Custom Compositor Pass
Copy paste OgreCompositorPassScene.cpp and its headers into your project. Then render however you like.
See Colibri which uses a custom compositor pass to render the 2D UI.
It delegates all the work to m_colibriManager->prepareRenderCommands()
and m_colibriManager->render()
.
This sounds a bit overkill and you will be duplicating a lot of work that OgreNext is already doing, so I am not convinced of this approach.
Thus in short the easiest and simplest way is just toggle settings by iterating through them.
Using an Item clone (or an custom MovableObject that references SubItems) would be more efficient on the long run.
This also depends on the number of Items you have. If you have 100 items in your scene and 10 windows, 1000 iterations may very well be acceptable.
If you have 100k Items, then the clone may be a better deal.