GearVRf icon indicating copy to clipboard operation
GearVRf copied to clipboard

removeAllSceneObjects() is detaching the Camera Rig

Open SteveGreatApe opened this issue 7 years ago • 5 comments

This problem is on the master branch.

GVRScene.removeAllSceneObjects() was recently changed with the addition of a call to child.detachAllComponents(); on each child object being removed. This is causing a problem as the main GVRCameraRig is being detached from it's owner object. This causes GVRCameraRig .getTransform() to return null triggering NullPointerException's.

I've made this change to my build which has fixed the problem for me:

--- a/GVRf/Framework/framework/src/main/java/org/gearvrf/GVRScene.java
+++ b/GVRf/Framework/framework/src/main/java/org/gearvrf/GVRScene.java
@@ -143,7 +143,9 @@ public class GVRScene extends GVRHybridObject implements PrettyPrint, IScriptabl

         rig.removeAllChildren();
         for (GVRSceneObject child : mSceneRoot.getChildren()) {
-            child.detachAllComponents();
+            if (child != head) {
+                child.detachAllComponents();
+            }
             child.getParent().removeChildObject(child);
         }
         NativeScene.removeAllSceneObjects(getNative());

SteveGreatApe avatar Feb 18 '18 17:02 SteveGreatApe

Actually, it's also hitting the controller, here's an updated workaround fix:

--- a/GVRf/Framework/framework/src/main/java/org/gearvrf/GVRScene.java +++ b/GVRf/Framework/framework/src/main/java/org/gearvrf/GVRScene.java @@ -143,7 +143,9 @@ public class GVRScene extends GVRHybridObject implements PrettyPrint, IScriptabl

         rig.removeAllChildren();
         for (GVRSceneObject child : mSceneRoot.getChildren()) {
-            child.detachAllComponents();
+            if (child != head && !child.getName().equals("GearCursorController_Pivot")) {
+                child.detachAllComponents();
+            }
             child.getParent().removeChildObject(child);
         }
         NativeScene.removeAllSceneObjects(getNative());

SteveGreatApe avatar Feb 18 '18 18:02 SteveGreatApe

Here is my version of removeAllSceneObjects. Yes, it does remove the controller model at first. But the selectControllers() call should put the controller back. Does it do that for your application?

public void removeAllSceneObjects() { GVRCameraRig rig = getMainCameraRig(); GVRSceneObject head = rig.getOwnerObject(); int numControllers = getGVRContext().getInputManager().clear();

    rig.removeAllChildren();
    for (final GVRSceneObject child : mSceneRoot.getChildren())
    {
        child.getParent().removeChildObject(child);
    }
    NativeScene.removeAllSceneObjects(getNative());
    mSceneRoot = new GVRSceneObject(getGVRContext());
    if (null != head) {
        mSceneRoot.addChildObject(head);
    }
    NativeScene.addSceneObject(getNative(), mSceneRoot.getNative());
    if (numControllers > 0)
    {
        getGVRContext().getInputManager().selectController();
    }
    getGVRContext().runOnGlThread(new Runnable() {
        @Override
        public void run() {
            NativeScene.deleteLightsAndDepthTextureOnRenderThread(getNative());
        }
    });
}

NolaDonato avatar Feb 22 '18 01:02 NolaDonato

Your function is okay with the way it puts the controller back, the trouble is the master version has added a new call to child.detachAllComponents(); which yours doesn't have, that's the bit that's causing the problem. I assume it was added for a good reason, but it needs protection to stop it detaching components from the Controller & Camera Rig.

SteveGreatApe avatar Feb 22 '18 14:02 SteveGreatApe

We have shutdown issues because of the way Java and C++ objects interact. I think we will have to do without detatchAllComponents there.

NolaDonato avatar Feb 22 '18 21:02 NolaDonato

I think detachAllComponent's problem is the bi-directional link a SceneObject and its components have more than anything else.

liaxim avatar Feb 22 '18 23:02 liaxim