Un-parented MeshObjectNode being disposed? - Printable Version
+- AB4D Forum (https://forum.ab4d.com)
+-- Forum: Products Forums (https://forum.ab4d.com/forumdisplay.php?fid=4)
+--- Forum: Ab3d.DXEngine (https://forum.ab4d.com/forumdisplay.php?fid=11)
+--- Thread: Un-parented MeshObjectNode being disposed? (/showthread.php?tid=4094)
Un-parented MeshObjectNode being disposed? - Hamish - 03-04-2018
I've removed a MeshObjectNode instance from it's parent, and when I call DXScene.RenderScene, the MeshObjectNode's gets disposed.
I'm definitely not calling dispose. When I add a Disposing event handler and set a breakpoint in it to see the callstack, it seems to be coming from the DXScene.RenderScene method.
Is this expected? How can I stop this MeshObjectNode from being disposed? I want to keep the node around and attach/remove this node from the DXScene as necessary.
RE: Un-parented MeshObjectNode being disposed? - Hamish - 03-04-2018
Looks like the same things happens if I change the "IsActive" property to false. Is this to be expected? The docs simply say that the "IsActive" property controls an object's visibility in the scene.
RE: Un-parented MeshObjectNode being disposed? - abenedik - 03-07-2018
DXEngine is using reference counting for most of its objects including SceneNodes (all that are derived from SharedDXResource class). When you create such object its ReferencesCount property is set to one. You can increase reference count by calling AddRef method. When you call Dispose method the ReferencesCount value is decreased. When it reaches zero, the DirectX resources are actually disposed (released).
The DXScene has an automatic disposal mechanism that automatically disposes all SceneNodes that are removed from it but still allows moving SceneNodes from one parent node to another. This means that a SceneNode that is removed from DXScene will be disposed in the beginning of the next frame (inside Update method).
I understand that this is not the best solution.
The good news is that only the SceneNode is disposed, but its Materal and Mesh object are not (because reference count for both is increased when added to ObjectMeshNode and decreased when ObjectMeshNode is disposed). This means that you can reuse Material and Mesh and create a new ObjectMeshNode when you want to show it again (you will not need to recreate the DirectX resources).
Anyway, I know that hiding and showing objects is a very common task for every 3D application. Therefore I am planning to improve that in the future version.
RE: Un-parented MeshObjectNode being disposed? - Hamish - 03-08-2018
While that makes a bit more sense, I still don't understand what causes the ref count to be decremented.
In my code, I've added a call to node.AddRef() immediately after I unparent the child - which should counteract the ref decrement from the unparent operation.
But my node is still being disposed. I'm not calling dispose anywhere - I'm merely unparenting.
So clearly there is something else decrementing the reference count that is out of my control. When does this value get decremented and how do I counteract this?
RE: Un-parented MeshObjectNode being disposed? - abenedik - 03-09-2018
There is actually a bug in the code, that happens when you add a SceneNode back to the scene and that SceneNode was before removed from the scene. In this case the Dipose method will be called on the SceneNode again. So another AddRef would be needed when you add the SceneNode back to the tree.
This process will be improved in the next version so you will be able to remove and add SceneNodes from and to the DXScene without any problems.
Therefore you should not use AddRef methods in this case because this would break the reference count when the next version is out.
A current workaround is to create a new SceneNode (for example MeshObjectNode) when you want to add it back to the scene (you can reuse the material and mesh).