/** Called once per frame, before {@link #onDrawEyeView(int, float)}. */
  void onDrawFrame() {

    GVRPerspectiveCamera centerCamera = mMainScene.getMainCameraRig().getCenterCamera();
    cull(
        mMainScene.getNative(),
        centerCamera.getNative(),
        mRenderBundle.getMaterialShaderManager().getNative());

    if (mCurrentEye == 1) {
      mActivity.setCamera(mMainScene.getMainCameraRig().getLeftCamera());
    } else {
      mActivity.setCamera(mMainScene.getMainCameraRig().getRightCamera());
    }
  }
  /**
   * This is the code that needs to be executed before either eye is drawn.
   *
   * @return Current time, from {@link GVRTime#getCurrentTime()}
   */
  private long doMemoryManagementAndPerFrameCallbacks() {
    long currentTime = GVRTime.getCurrentTime();
    mFrameTime = (currentTime - mPreviousTimeNanos) / 1e9f;
    mPreviousTimeNanos = currentTime;

    /*
     * Without the sensor data, can't draw a scene properly.
     */
    if (!(mSensoredScene == null || !mMainScene.equals(mSensoredScene))) {
      Runnable runnable = null;
      while ((runnable = mRunnables.poll()) != null) {
        try {
          runnable.run();
        } catch (final Exception exc) {
          Log.e(TAG, "Runnable-on-GL %s threw %s", runnable, exc.toString());
          exc.printStackTrace();
        }
      }

      final List<GVRDrawFrameListener> frameListeners = mFrameListeners;
      for (GVRDrawFrameListener listener : frameListeners) {
        try {
          listener.onDrawFrame(mFrameTime);
        } catch (final Exception exc) {
          Log.e(TAG, "DrawFrameListener %s threw %s", listener, exc.toString());
          exc.printStackTrace();
        }
      }
    }
    NativeGLDelete.processQueues(mGlDeleterPtr);

    return currentTime;
  }
  boolean updateSensoredScene() {
    if (mSensoredScene != null && mMainScene.equals(mSensoredScene)) {
      return true;
    }

    if (null != mMainScene) {
      final GVRCameraRig cameraRig = mMainScene.getMainCameraRig();

      if (null != cameraRig && (mSensoredScene == null || !mMainScene.equals(mSensoredScene))) {
        Log.i(TAG, "camera rig yaw reset");
        cameraRig.resetYaw();
        mSensoredScene = mMainScene;
        return true;
      }
    }
    return false;
  }
 private void renderCamera(
     long activity_ptr, GVRScene scene, GVRCamera camera, GVRRenderBundle renderBundle) {
   renderCamera(
       activity_ptr,
       scene.getNative(),
       camera.getNative(),
       renderBundle.getMaterialShaderManager().getNative(),
       renderBundle.getPostEffectShaderManager().getNative(),
       renderBundle.getPostEffectRenderTextureA().getNative(),
       renderBundle.getPostEffectRenderTextureB().getNative());
 }
        public void beforeDrawEyes() {
          mMainScene.resetStats();

          GVRNotifications.notifyBeforeStep();

          doMemoryManagementAndPerFrameCallbacks();

          try {
            GVRViewManager.this.getEventManager().sendEvent(mScript, IScriptEvents.class, "onStep");
          } catch (final Exception exc) {
            Log.e(TAG, "Exception from onStep: %s", exc.toString());
            exc.printStackTrace();
          }
        }
 @Override
 public synchronized void setMainScene(GVRScene scene) {
   mMainScene = scene;
   if (mNextMainScene == scene) {
     mNextMainScene = null;
     if (mOnSwitchMainScene != null) {
       mOnSwitchMainScene.run();
       mOnSwitchMainScene = null;
     }
   }
   if (null != mMainScene) {
     getActivity().setCameraRig(mMainScene.getMainCameraRig());
     mInputManager.setScene(mMainScene);
   }
 }
  /**
   * Called to reset current sensor data.
   *
   * @param timeStamp current time stamp
   * @param rotationW Quaternion rotation W
   * @param rotationX Quaternion rotation X
   * @param rotationY Quaternion rotation Y
   * @param rotationZ Quaternion rotation Z
   * @param gyroX Gyro rotation X
   * @param gyroY Gyro rotation Y
   * @param gyroZ Gyro rotation Z
   */
  @Override
  public void onRotationSensor(
      long timeStamp,
      float rotationW,
      float rotationX,
      float rotationY,
      float rotationZ,
      float gyroX,
      float gyroY,
      float gyroZ) {
    GVRCameraRig cameraRig = null;
    if (mMainScene != null) {
      cameraRig = mMainScene.getMainCameraRig();
    }

    if (cameraRig != null) {
      cameraRig.setRotationSensorData(
          timeStamp, rotationW, rotationX, rotationY, rotationZ, gyroX, gyroY, gyroZ);
      updateSensoredScene();
    }
  }
 @Override
 public void afterDrawEyes() {
   GVRNotifications.notifyAfterStep();
   mMainScene.updateStats();
 }
  void onDrawEyeView(int eye, float fovDegrees) {
    mCurrentEye = eye;
    if (!(mSensoredScene == null || !mMainScene.equals(mSensoredScene))) {
      GVRCameraRig mainCameraRig = mMainScene.getMainCameraRig();

      if (eye == 1) {
        GVRCamera rightCamera = mainCameraRig.getRightCamera();
        renderCamera(mActivity.getAppPtr(), mMainScene, rightCamera, mRenderBundle);

        // if mScreenshotRightCallback is not null, capture right eye
        if (mScreenshotRightCallback != null) {
          readRenderResult();
          returnScreenshotToCaller(
              mScreenshotRightCallback, mReadbackBufferWidth, mReadbackBufferHeight);
          mScreenshotRightCallback = null;
        }

        mActivity.setCamera(rightCamera);
      } else {
        // if mScreenshotCenterCallback is not null, capture center eye
        if (mScreenshotCenterCallback != null) {
          GVRPerspectiveCamera centerCamera = mainCameraRig.getCenterCamera();

          renderCamera(mActivity.getAppPtr(), mMainScene, centerCamera, mRenderBundle);

          readRenderResult();
          returnScreenshotToCaller(
              mScreenshotCenterCallback, mReadbackBufferWidth, mReadbackBufferHeight);

          mScreenshotCenterCallback = null;
        }

        // if mScreenshot3DCallback is not null, capture 3D screenshot
        if (mScreenshot3DCallback != null) {
          byte[][] byteArrays = new byte[6][];
          renderSixCamerasAndReadback(mainCameraRig, byteArrays);
          returnScreenshot3DToCaller(
              mScreenshot3DCallback, byteArrays, mReadbackBufferWidth, mReadbackBufferHeight);

          mScreenshot3DCallback = null;
        }

        GVRCamera leftCamera = mainCameraRig.getLeftCamera();
        renderCamera(mActivity.getAppPtr(), mMainScene, leftCamera, mRenderBundle);

        // if mScreenshotLeftCallback is not null, capture left eye
        if (mScreenshotLeftCallback != null) {
          readRenderResult();
          returnScreenshotToCaller(
              mScreenshotLeftCallback, mReadbackBufferWidth, mReadbackBufferHeight);

          mScreenshotLeftCallback = null;
        }

        if (mScreenshotLeftCallback == null
            && mScreenshotRightCallback == null
            && mScreenshotCenterCallback == null
            && mScreenshot3DCallback == null) {
          mReadbackBuffer = null;
        }

        mActivity.setCamera(leftCamera);
      }
    }
  }
  @Override
  public void onInit(GVRContext gvrContext) {

    mGVRContext = gvrContext;

    mMetalOnlyShader = new MetalOnlyShader(mGVRContext);
    mDiffuseShader = new DiffuseShader(mGVRContext);
    mGlassShader = new GlassShader(mGVRContext);
    mReflectionShader = new ReflectionShader(mGVRContext);
    mPhongShader = new PhongShader(mGVRContext);

    mMetalShader2 = new MetalShader2(mGVRContext);
    mDiffuseShader2 = new DiffuseShader2(mGVRContext);
    mGlassShader2 = new GlassShader2(mGVRContext);
    mPhongShader2 = new PhongShader2(mGVRContext);
    mPhongShader3 = new PhongShader3(mGVRContext);

    GVRScene mainScene = mGVRContext.getNextMainScene();

    mainScene.getMainCameraRig().getLeftCamera().setBackgroundColor(1.0f, 1.0f, 1.0f, 1.0f);
    mainScene.getMainCameraRig().getRightCamera().setBackgroundColor(1.0f, 1.0f, 1.0f, 1.0f);

    try {
      GVRTexture env_tex = mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "env.jpg"));
      mReflectionMaterial = new GVRMaterial(mGVRContext, mReflectionShader.getShaderId());
      mReflectionMaterial.setVec4(ReflectionShader.COLOR_KEY, 1.0f, 1.0f, 1.0f, 1.0f);
      mReflectionMaterial.setFloat(ReflectionShader.RADIUS_KEY, 10.0f);
      mReflectionMaterial.setTexture(ReflectionShader.TEXTURE_KEY, env_tex);

      // ------------------------------------------------------ set
      // materials
      // watch
      mMetalMaterial = new GVRMaterial(mGVRContext, mMetalOnlyShader.getShaderId());
      mMetalMaterial.setVec4(MetalOnlyShader.COLOR_KEY, 1.7f, 1.4f, 1.0f, 1.0f);
      mMetalMaterial.setFloat(MetalOnlyShader.RADIUS_KEY, 10.0f);
      mMetalMaterial.setTexture(MetalOnlyShader.TEXTURE_KEY, env_tex);

      mGlassMaterial = new GVRMaterial(mGVRContext, mGlassShader.getShaderId());
      mGlassMaterial.setVec4(GlassShader.COLOR_KEY, 1.0f, 1.0f, 1.0f, 1.0f);
      mGlassMaterial.setFloat(MetalOnlyShader.RADIUS_KEY, 10.0f);
      mGlassMaterial.setTexture(GlassShader.TEXTURE_KEY, env_tex);

      GVRTexture board_tex =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "watch/board.jpg"));
      mDiffuseMaterial = new GVRMaterial(mGVRContext, mDiffuseShader.getShaderId());
      mDiffuseMaterial.setVec4(DiffuseShader.COLOR_KEY, 1.0f, 1.0f, 1.0f, 1.0f);
      mDiffuseMaterial.setTexture(DiffuseShader.TEXTURE_KEY, board_tex);

      // jar
      mPhongMaterial = new GVRMaterial(mGVRContext, mPhongShader.getShaderId());
      mPhongMaterial.setVec4(PhongShader.COLOR_KEY, 1.2f, 1.2f, 1.3f, 1.0f);
      mPhongMaterial.setFloat(PhongShader.RADIUS_KEY, 10.0f);
      mPhongMaterial.setTexture(PhongShader.TEXTURE_KEY, env_tex);

      // car
      GVRTexture car_body_tex =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "car/body.jpg"));
      mCarBodyMaterial = new GVRMaterial(mGVRContext, mPhongShader3.getShaderId());
      mCarBodyMaterial.setFloat(PhongShader3.RADIUS_KEY, 10.0f);
      mCarBodyMaterial.setTexture(PhongShader3.ENV_KEY, env_tex);
      mCarBodyMaterial.setTexture(PhongShader3.TEXTURE_KEY, car_body_tex);

      mCarWheelMaterial = new GVRMaterial(mGVRContext, mMetalShader2.getShaderId());
      mCarWheelMaterial.setVec4(MetalShader2.COLOR_KEY, 1.2f, 1.2f, 1.2f, 1.0f);
      mCarWheelMaterial.setFloat(MetalShader2.RADIUS_KEY, 10.0f);
      mCarWheelMaterial.setTexture(MetalShader2.TEXTURE_KEY, env_tex);

      mCarGlassMaterial = new GVRMaterial(mGVRContext, mGlassShader2.getShaderId());
      mCarGlassMaterial.setVec4(GlassShader2.COLOR_KEY, 1.0f, 1.0f, 1.0f, 1.0f);
      mCarGlassMaterial.setFloat(GlassShader2.RADIUS_KEY, 10.0f);
      mCarGlassMaterial.setTexture(GlassShader2.TEXTURE_KEY, env_tex);

      GVRTexture default_tex =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "car/default.bmp"));
      mCarTireMaterial = new GVRMaterial(mGVRContext, mDiffuseShader2.getShaderId());
      mCarTireMaterial.setVec4(DiffuseShader2.COLOR_KEY, 0.1f, 0.1f, 0.1f, 1.0f);
      mCarTireMaterial.setTexture(DiffuseShader2.TEXTURE_KEY, default_tex);

      GVRTexture back_tex =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "car/back.jpg"));
      mCarBackMaterial = new GVRMaterial(mGVRContext, mDiffuseShader2.getShaderId());
      mCarBackMaterial.setVec4(DiffuseShader2.COLOR_KEY, 1.0f, 1.0f, 1.0f, 1.0f);
      mCarBackMaterial.setTexture(DiffuseShader2.TEXTURE_KEY, back_tex);

      GVRTexture grill_tex =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "car/grill.jpg"));
      mCarGrillMaterial = new GVRMaterial(mGVRContext, mDiffuseShader2.getShaderId());
      mCarGrillMaterial.setVec4(DiffuseShader2.COLOR_KEY, 1.0f, 1.0f, 1.0f, 1.0f);
      mCarGrillMaterial.setTexture(DiffuseShader2.TEXTURE_KEY, grill_tex);

      mCarLightMaterial = new GVRMaterial(mGVRContext, mGlassShader2.getShaderId());
      mCarLightMaterial.setVec4(GlassShader2.COLOR_KEY, 2.5f, 2.5f, 2.5f, 1.0f);
      mCarLightMaterial.setFloat(GlassShader2.RADIUS_KEY, 10.0f);
      mCarLightMaterial.setTexture(GlassShader2.TEXTURE_KEY, env_tex);

      mCarInsideMaterial = new GVRMaterial(mGVRContext, mPhongShader2.getShaderId());
      mCarInsideMaterial.setVec4(PhongShader2.COLOR_KEY, 0.0f, 0.0f, 0.0f, 1.0f);
      mCarInsideMaterial.setFloat(PhongShader2.RADIUS_KEY, 10.0f);
      mCarInsideMaterial.setTexture(PhongShader2.TEXTURE_KEY, env_tex);

      // robot
      GVRTexture robot_head_tex =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "robot/head.jpg"));
      mRobotHeadMaterial = new GVRMaterial(mGVRContext, mPhongShader3.getShaderId());
      mRobotHeadMaterial.setFloat(PhongShader3.RADIUS_KEY, 10.0f);
      mRobotHeadMaterial.setTexture(PhongShader3.ENV_KEY, env_tex);
      mRobotHeadMaterial.setTexture(PhongShader3.TEXTURE_KEY, robot_head_tex);

      mRobotMetalMaterial = new GVRMaterial(mGVRContext, mMetalShader2.getShaderId());
      mRobotMetalMaterial.setVec4(MetalShader2.COLOR_KEY, 1.5f, 1.5f, 1.5f, 1.0f);
      mRobotMetalMaterial.setFloat(MetalShader2.RADIUS_KEY, 10.0f);
      mRobotMetalMaterial.setTexture(MetalShader2.TEXTURE_KEY, env_tex);

      mRobotBodyMaterial = new GVRMaterial(mGVRContext, mPhongShader2.getShaderId());
      mRobotBodyMaterial.setVec4(PhongShader2.COLOR_KEY, 1.0f, 1.0f, 1.0f, 1.0f);
      mRobotBodyMaterial.setFloat(PhongShader2.RADIUS_KEY, 10.0f);
      mRobotBodyMaterial.setTexture(PhongShader2.TEXTURE_KEY, env_tex);

      mRobotRubberMaterial = new GVRMaterial(mGVRContext, mDiffuseShader2.getShaderId());
      mRobotRubberMaterial.setVec4(DiffuseShader2.COLOR_KEY, 0.3f, 0.3f, 0.3f, 1.0f);
      mRobotRubberMaterial.setTexture(DiffuseShader2.TEXTURE_KEY, default_tex);

      // leaf
      GVRTexture leaf_box_tex =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "leaf/box.jpg"));
      mLeafBoxMaterial = new GVRMaterial(mGVRContext, mPhongShader3.getShaderId());
      mLeafBoxMaterial.setFloat(PhongShader3.RADIUS_KEY, 10.0f);
      mLeafBoxMaterial.setTexture(PhongShader3.ENV_KEY, env_tex);
      mLeafBoxMaterial.setTexture(PhongShader3.TEXTURE_KEY, leaf_box_tex);

      mLeafBodyMaterial = new GVRMaterial(mGVRContext, mMetalShader2.getShaderId());
      mLeafBodyMaterial.setVec4(MetalShader2.COLOR_KEY, 2.5f, 2.5f, 2.5f, 1.0f);
      mLeafBodyMaterial.setFloat(MetalShader2.RADIUS_KEY, 10.0f);
      mLeafBodyMaterial.setTexture(MetalShader2.TEXTURE_KEY, env_tex);

      // ------------------------------------------------------ set
      // objects

      for (int i = 0; i < THUMBNAIL_NUM; i++) Objects[i] = new GVRSceneObject(mGVRContext);

      // --------------watch

      GVRSceneObject obj1 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData1 = new GVRRenderData(mGVRContext);
      GVRMesh mesh1 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "watch/frame.obj"));
      renderData1.setMesh(mesh1);
      renderData1.setMaterial(mMetalMaterial);
      obj1.attachRenderData(renderData1);
      Objects[2].addChildObject(obj1);

      GVRSceneObject obj2 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData2 = new GVRRenderData(mGVRContext);
      GVRMesh mesh2 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "watch/board.obj"));
      renderData2.setMesh(mesh2);
      renderData2.setMaterial(mDiffuseMaterial);
      obj2.attachRenderData(renderData2);
      Objects[2].addChildObject(obj2);

      GVRSceneObject obj3 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData3 = new GVRRenderData(mGVRContext);
      GVRMesh mesh3 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "watch/glass.obj"));
      renderData3.setMesh(mesh3);
      renderData3.setMaterial(mGlassMaterial);
      obj3.attachRenderData(renderData3);

      obj3.getRenderData().setRenderingOrder(3000);
      Objects[2].addChildObject(obj3);

      Objects[2].getTransform().setPosition(0.0f, 0.0f, -EYE_TO_OBJECT);
      mainScene.addSceneObject(Objects[2]);

      // --------------jar

      GVRSceneObject obj5 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData5 = new GVRRenderData(mGVRContext);
      GVRMesh mesh5 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "jar/jar.obj"));
      renderData5.setMesh(mesh5);
      renderData5.setMaterial(mPhongMaterial);
      obj5.attachRenderData(renderData5);
      Objects[1].addChildObject(obj5);

      GVRSceneObject obj4 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData4 = new GVRRenderData(mGVRContext);
      GVRMesh mesh4 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "jar/edge.obj"));
      renderData4.setMesh(mesh4);
      renderData4.setMaterial(mMetalMaterial);
      obj4.attachRenderData(renderData4);
      obj4.getRenderData().setRenderingOrder(3000);
      Objects[1].addChildObject(obj4);

      Objects[1].getTransform().setPosition(0.0f, 0.0f, -EYE_TO_OBJECT);
      mainScene.addSceneObject(Objects[1]);

      // --------------car

      GVRSceneObject obj6 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData6 = new GVRRenderData(mGVRContext);
      GVRMesh mesh6 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "car/body.obj"));
      renderData6.setMesh(mesh6);
      renderData6.setMaterial(mCarBodyMaterial);
      obj6.attachRenderData(renderData6);
      obj6.getRenderData().setCullTest(false);
      Objects[3].addChildObject(obj6);

      GVRSceneObject obj9 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData9 = new GVRRenderData(mGVRContext);
      GVRMesh mesh9 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "car/tire.obj"));
      renderData9.setMesh(mesh9);
      renderData9.setMaterial(mCarTireMaterial);
      obj9.attachRenderData(renderData9);
      Objects[3].addChildObject(obj9);

      GVRSceneObject obj10 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData10 = new GVRRenderData(mGVRContext);
      GVRMesh mesh10 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "car/glass.obj"));
      renderData10.setMesh(mesh10);
      renderData10.setMaterial(mCarGlassMaterial);
      obj10.attachRenderData(renderData10);
      obj10.getRenderData().setCullTest(false);
      obj10.getRenderData().setRenderingOrder(3000);
      Objects[3].addChildObject(obj10);

      GVRSceneObject obj11 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData11 = new GVRRenderData(mGVRContext);
      GVRMesh mesh11 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "car/wheel.obj"));
      renderData11.setMesh(mesh11);
      renderData11.setMaterial(mCarWheelMaterial);
      obj11.attachRenderData(renderData11);
      Objects[3].addChildObject(obj11);

      GVRSceneObject obj12 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData12 = new GVRRenderData(mGVRContext);
      GVRMesh mesh12 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "car/back.obj"));
      renderData12.setMesh(mesh12);
      renderData12.setMaterial(mCarBackMaterial);
      obj12.attachRenderData(renderData12);
      Objects[3].addChildObject(obj12);

      GVRSceneObject obj13 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData13 = new GVRRenderData(mGVRContext);
      GVRMesh mesh13 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "car/grill.obj"));
      renderData13.setMesh(mesh13);
      renderData13.setMaterial(mCarGrillMaterial);
      obj13.attachRenderData(renderData13);
      obj10.getRenderData().setRenderingOrder(3000);
      Objects[3].addChildObject(obj13);

      GVRSceneObject obj14 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData14 = new GVRRenderData(mGVRContext);
      GVRMesh mesh14 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "car/glass2.obj"));
      renderData14.setMesh(mesh14);
      renderData14.setMaterial(mCarLightMaterial);
      obj14.attachRenderData(renderData14);
      obj14.getRenderData().setRenderingOrder(4000);
      Objects[3].addChildObject(obj14);

      GVRSceneObject obj19 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData19 = new GVRRenderData(mGVRContext);
      GVRMesh mesh19 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "car/inside.obj"));
      renderData19.setMesh(mesh19);
      renderData19.setMaterial(mCarInsideMaterial);
      obj19.attachRenderData(renderData19);
      Objects[3].addChildObject(obj19);

      Objects[3].getTransform().setPosition(0.0f, -2.0f, -EYE_TO_OBJECT - 3.0f);
      mainScene.addSceneObject(Objects[3]);

      // robot

      GVRSceneObject obj15 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData15 = new GVRRenderData(mGVRContext);
      GVRMesh mesh15 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "robot/body.obj"));
      renderData15.setMesh(mesh15);
      renderData15.setMaterial(mRobotBodyMaterial);
      obj15.attachRenderData(renderData15);
      Objects[4].addChildObject(obj15);

      GVRSceneObject obj16 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData16 = new GVRRenderData(mGVRContext);
      GVRMesh mesh16 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "robot/head.obj"));
      renderData16.setMesh(mesh16);
      renderData16.setMaterial(mRobotHeadMaterial);
      obj16.attachRenderData(renderData16);
      Objects[4].addChildObject(obj16);

      GVRSceneObject obj17 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData17 = new GVRRenderData(mGVRContext);
      GVRMesh mesh17 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "robot/metal.obj"));
      renderData17.setMesh(mesh17);
      renderData17.setMaterial(mRobotMetalMaterial);
      obj17.attachRenderData(renderData17);
      obj17.getRenderData().setRenderingOrder(3000);
      Objects[4].addChildObject(obj17);

      GVRSceneObject obj18 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData18 = new GVRRenderData(mGVRContext);
      GVRMesh mesh18 =
          mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "robot/rubber.obj"));
      renderData18.setMesh(mesh18);
      renderData18.setMaterial(mRobotRubberMaterial);
      obj18.attachRenderData(renderData18);
      Objects[4].addChildObject(obj18);

      Objects[4].getTransform().setPosition(0.0f, 0.0f, -EYE_TO_OBJECT);
      mainScene.addSceneObject(Objects[4]);

      // leaf

      GVRSceneObject obj20 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData20 = new GVRRenderData(mGVRContext);
      GVRMesh mesh20 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "leaf/leaf.obj"));
      renderData20.setMesh(mesh20);
      renderData20.setMaterial(mLeafBodyMaterial);
      obj20.attachRenderData(renderData20);
      Objects[0].addChildObject(obj20);

      GVRSceneObject obj21 = new GVRSceneObject(mGVRContext);
      GVRRenderData renderData21 = new GVRRenderData(mGVRContext);
      GVRMesh mesh21 = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "leaf/box.obj"));
      renderData21.setMesh(mesh21);
      renderData21.setMaterial(mLeafBoxMaterial);
      obj21.attachRenderData(renderData21);
      Objects[0].addChildObject(obj21);

      Objects[0].getTransform().setPosition(0.0f, 0.0f, -EYE_TO_OBJECT);
      mainScene.addSceneObject(Objects[0]);

      for (int I = 0; I < THUMBNAIL_NUM; I++)
        for (int i = 0; i < Objects[I].getChildrenCount(); i++)
          Objects[I].getChildByIndex(i).getRenderData().setRenderMask(0);
      // ------------------------------------------------------ set
      // thumbnails

      ThumbnailTextures[0] =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "leaf/leaf.jpg"));
      ThumbnailTextures[1] =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "jar/jar.png"));
      ThumbnailTextures[2] =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "watch/watch.png"));
      ThumbnailTextures[3] =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "car/car.bmp"));
      ThumbnailTextures[4] =
          mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "robot/robot.jpg"));

      ThumbnailTargetPosition[0][0] = -2.2f;
      ThumbnailTargetPosition[0][1] = 0.0f;
      ThumbnailTargetPosition[0][2] = -EYE_TO_OBJECT - 2.8f;
      ThumbnailTargetPosition[1][0] = -1.0f;
      ThumbnailTargetPosition[1][1] = 0.0f;
      ThumbnailTargetPosition[1][2] = -EYE_TO_OBJECT - 1.5f;
      ThumbnailTargetPosition[2][0] = 0.0f;
      ThumbnailTargetPosition[2][1] = 0.0f;
      ThumbnailTargetPosition[2][2] = -EYE_TO_OBJECT - 0.0f;
      ThumbnailTargetPosition[3][0] = 1.0f;
      ThumbnailTargetPosition[3][1] = 0.0f;
      ThumbnailTargetPosition[3][2] = -EYE_TO_OBJECT - 1.5f;
      ThumbnailTargetPosition[4][0] = 2.2f;
      ThumbnailTargetPosition[4][1] = 0.0f;
      ThumbnailTargetPosition[4][2] = -EYE_TO_OBJECT - 2.8f;

      for (int i = 0; i < THUMBNAIL_NUM; i++)
        for (int j = 0; j < 3; j++) ThumbnailCurrentPosition[i][j] = ThumbnailTargetPosition[i][j];
      for (int i = 0; i < THUMBNAIL_NUM; i++) ThumbnailTargetIndex[i] = i;

      ThumbnailOrder[0] = 10000;
      ThumbnailOrder[1] = 10001;
      ThumbnailOrder[2] = 10002;
      ThumbnailOrder[3] = 10001;
      ThumbnailOrder[4] = 10000;

      GVRMesh glass_mesh = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "glass.obj"));
      GVRMesh board_mesh = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "board.obj"));
      GVRMesh picks_mesh = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "pick.obj"));
      for (int i = 0; i < THUMBNAIL_NUM; i++) {
        ThumbnailObject[i] = new GVRSceneObject(mGVRContext);
        ThumbnailRotation[i] = new GVRSceneObject(mGVRContext);
        GVRSceneObject obj = new GVRSceneObject(mGVRContext);
        ThumbnailGlasses[i] = new GVRRenderData(mGVRContext);
        ThumbnailGlasses[i].setMesh(glass_mesh);
        ThumbnailGlasses[i].setMaterial(mReflectionMaterial);
        obj.attachRenderData(ThumbnailGlasses[i]);
        obj.getRenderData().setRenderingOrder(ThumbnailOrder[i]);
        ThumbnailRotation[i].addChildObject(obj);
        ThumbnailObject[i].addChildObject(ThumbnailRotation[i]);

        Thumbnails[i] = new GVRSceneObject(mGVRContext, board_mesh, ThumbnailTextures[i]);
        Thumbnails[i].getRenderData().setRenderingOrder(ThumbnailOrder[i] - 100);
        Thumbnails[i].getRenderData().setCullTest(false);
        Thumbnails[i].getTransform().setScale(1.0f, 1.2f, 1.0f);
        ThumbnailRotation[i].addChildObject(Thumbnails[i]);

        ThumbnailObject[i]
            .getTransform()
            .setPosition(
                ThumbnailTargetPosition[i][0],
                ThumbnailTargetPosition[i][1],
                ThumbnailTargetPosition[i][2]);
        mainScene.addSceneObject(ThumbnailObject[i]);

        GVREyePointeeHolder eyePointeeHolder = new GVREyePointeeHolder(gvrContext);
        GVRMeshEyePointee eyePointee = new GVRMeshEyePointee(gvrContext, picks_mesh);
        eyePointeeHolder.addPointee(eyePointee);
        ThumbnailObject[i].attachEyePointeeHolder(eyePointeeHolder);
      }

      GVRTexture m360 = mGVRContext.loadTexture(new GVRAndroidResource(mGVRContext, "env.jpg"));
      GVRMesh sphere = mGVRContext.loadMesh(new GVRAndroidResource(mGVRContext, "sphere.obj"));

      GVRSceneObject env_object = new GVRSceneObject(mGVRContext, sphere, m360);
      env_object.getRenderData().setCullTest(false);
      mainScene.addSceneObject(env_object);

      GVRSceneObject headTracker =
          new GVRSceneObject(
              gvrContext,
              gvrContext.createQuad(0.1f, 0.1f),
              gvrContext.loadTexture(
                  new GVRAndroidResource(mGVRContext, "Headtracking_pointer.png")));
      headTracker.getTransform().setPosition(0.0f, 0.0f, -EYE_TO_OBJECT);
      headTracker.getRenderData().setDepthTest(false);
      headTracker.getRenderData().setRenderingOrder(100000);
      mainScene.getMainCameraRig().getOwnerObject().addChildObject(headTracker);
    } catch (IOException e) {
      e.printStackTrace();
      mActivity.finish();
      Log.e(TAG, "Assets were not loaded. Stopping application!");
    }
    // activity was stored in order to stop the application if the mesh is
    // not loaded. Since we don't need anymore, we set it to null to reduce
    // chance of memory leak.
    mActivity = null;
  }