Qt3D - [c++] SetEnabled is loosing objects after some time
-
Hi!
I have a scene with hundreds of QEntities.
When i change the view, i need to switch most of them off and on, relative to their positions.entity->setEnabled(false); // after some time entity->setEnabled(true);
As soon as i use setEnabled, ie. on a Material, the Sceneloader or the Entity, the Qt3D renderer is loosing objects, which do not reappear anymore, slightly from time to time, until the scene gets completely destroyed.
I used a trick, setting the parent of the entity to a "nullroot" - clipping them off and on instead of disabling the properties (visibility, material or loader). But with the sceneloader behind some of the objects, the objects do not appear properly.
(When i show a messagebox, before setting the nullroot pipeline without using setenabled at all, all the objects appear as desired. otherwise, the sceneloader->entities remain invisible!)
- How can i prevent the clipping pipe of not loosing objects?
- Is there a safe way of disabling and enabling objects fast and repeatably?
- Is there a way of retrigger the sceneloader to redraw its contents?
- Is there a way of copying the contents of the loader tree so to become independent from the loader, and the entities are persistet on the parent entity?
- Can i retrigger the renderer, as it seems to be possible when accepting a messagebox before applying the nullroots?
Many thanks.
Here is some code:
entity = new Qt3DCore::QEntity(root); entity->addComponent(sceneloader); // the trick: the nullroot has no parent. Do not set enabled to false. the render will loose it after some time Qt3DCore::QEntity nullroot = new Qt3DCore::QEntity; // disabling: works always for all objects, classical meshes and integrated loader trees. So i can prevent setenabled(false) entity->setParent(nullroot); // enabling. works only on classical Meshes, not always for sceneloader-entities. the sceneloader does not like setting a nullroot explicitely entity->setParent(root); if (transparent) loader->setParent(nullroot) else // works unstable. switching back to the previous setting causes the application to crash loader->setParent(root);
-
I could sail around the problem by a straight hack.
The idea with the nullroot seems to be feasible as i have no setEnabled(false/true) clipping issues.
The reason, the application crashes, is, when assigning the nullroot to the loader more than once.
After switching it once, the meshes of the loader get reshown/removed properly by setting the root/nullroot on the loader AND the hosting QEntity.This code seems to work so far:
void myItem::show(bool enable) { // get a nullroot. a simple QEntity with no parent if (nullroot == nullptr) nullroot = new Qt3DCore::QEntity; if (enable) { // this is the item with the loaded obj-data if (loader != nullptr) { //this is the hack if (reset_loader) { loader->setParent(root); // DO IT ONLY ONCE! reset_loader = false; } } // activate the host entity in any case entity->setParent(root); } // deactivate the item with or without loader entities else { if (loader != nullptr) { if (reset_loader) loader->setParent(nullroot); } entity->setParent(nullroot); } }
Notice, that the Object holds either a mesh-entity or a dynamic loader entity and reset_loader is a object member, so that the application of the nullroot to the loader is only happening once for each object.
The graphic is a little slow with this approach, but the scene seems to be stable when stressing the renderer.
Also, when already having switched the parent on the loader, the scene reacts faster than the first time, when the nullroot was applied primarily. -
If you like to have a look on how the scene-loader works with nested objects and materials, have a look on the topic:
https://forum.qt.io/topic/134729/q-qt3d-c-apply-qmaterial-on-a-loaded-obj-file/3