Replies: 4 comments 2 replies
-
Directly removing the child by accessing group->children is the correct way to remove the child. However, the timing of when the subgraph is removed from the scene graph and when it's finally deleted is important. If you just remove the child in a background thread and the record traversal is running at the same time you can invalidate the iterators or delete the subgraph that is being traversed. To avoid this issue you need to remove the subgraph during the update phase of the frame and avoid doing when the record traversal is running. If you remove the subgraph in the update phase you avoid potential for a crash in record traversal but problems can still occur if that subgraph is deleted along with it's Vulkan resources while a previous submitted frame uses that Vulkan resources associated with that subgraph. To prevent this problem you can either do a device wait idle or wait on fence before you do the removal so that you ensure all the rendering is complete, or keep a ref_ptr<> to the subgraph alive for as many frames as may be queued up for rendering - 3 frames will be enough to handle triple buffering. I have a plan to add a class for scheduling deletion of subgraphs to avoid the second issue, this would enable one to pass a subgraph to be sheduled for deletion and then have a background thread do the deletion after a user controlled number of frames. I don't have a plan to make access to members of the scene graph generally thread safe to avoid the first issue, mutex locks around all members would be prohibitively expensive and destroy the performance of the scene graph, it's far more efficient to just manage the scene graph at a high level and have certain type of operation done in sequence to avoid race conditions. For users used to using the OpenSceneGraph these constraints for when and how you can delete subgraphs is the same, though OpenGL's FIFO hides some of the possible threading issues by effectively multi-buffering pars of the data. This means while the same constraints apply you could sometimes getting away with dangerous usage. |
Beta Was this translation helpful? Give feedback.
-
Hi Cam. Thanks for your explanation. That makes sense to me now. The deletion happens at record traversal because it is triggered by a button click from ImGui UI which is inherited from vsg::Command. So, my application crashed due to the first reason you mentioned. This was probably an issue with invalidating an iterator as the record traversal will have descended down to the ImGui UI node but if you delete a sibling child or a node/sibling in the parental chain then the children vectors being streped through can be invalidated when then containers change size. Potentially even the self could be deleted.
... You shouldn't need a separate thread, the viewer has an update operations list that you add an operation to and have this called when viewer.update() is called. |
Beta Was this translation helpful? Give feedback.
-
Reagrding this issue, how can I set the Node visible or invisible ? This would help to the purpose, hide and unhide the node would e faster. |
Beta Was this translation helpful? Give feedback.
-
The vsg::Switch node is designed for switch off the traversal of it's children. Each child of the Switch has a Mask (a 64bit mask( that is combined with the Visitor's traversalMask and if it's not 0 then the child is traversed. To switch on a child use vsg::MASK_ALL, and switch off a child use vsg::MASK_OFF. |
Beta Was this translation helpful? Give feedback.
-
Hi
Let's say my root object in the scene graph is
vsg::ref_ptr<vsg::Group> scene
. Then, I added objectsNow I want to remove it. I see there is no public API regarding the removal of a child, but
children
member variable is public so I directly manipulate it. So my test code is.When I remove the last element in the scene, the application freezes. What am I missing here?
Thanks,
Cam
Beta Was this translation helpful? Give feedback.
All reactions