docs: public void initAnimationsAndInteractivity() {
          for (InteractiveObject interactiveObject : interactiveObjects) {
              GVRAnimationChannel gvrAnimationChannel = null;
              GVRNodeAnimation gvrKeyFrameAnimation = null;
              GVRSceneObject gvrAnimatedObject = null;
  
              // both animated and interactive objects currently must have a time
              // sensor, interpolator and a Transform node with a DEF="..." parameter
              if ((interactiveObject.getTimeSensor() != null) &&
                      (interactiveObject.getInterpolator() != null) &&
                      (interactiveObject.getDefinedItem() != null)) {
                  // Set up the animation objects, properties
                  //   first construct the animation channel based on translation, rotation, scale, etc.
                  if ((interactiveObject.getDefinedItemToField().toLowerCase().endsWith(TRANSLATION)) ||
                          (interactiveObject.getDefinedItemToField().toLowerCase().endsWith(POSITION))) {
                      gvrAnimatedObject = root
                              .getSceneObjectByName((interactiveObject.getDefinedItem().getName() + x3dObject.TRANSFORM_TRANSLATION_));
                      gvrAnimationChannel = new GVRAnimationChannel(
                              gvrAnimatedObject.getName(),
                              interactiveObject.getInterpolator().key.length, 0, 0,
                              GVRAnimationBehavior.LINEAR, GVRAnimationBehavior.LINEAR);
                      for (int j = 0; j < interactiveObject.getInterpolator().key.length; j++) {
                          gvrAnimationChannel.setPosKeyVector(j,
                                  interactiveObject.getInterpolator().key[j]
                                          * interactiveObject.getTimeSensor().getCycleInterval(),
                                          new float[] { interactiveObject.getInterpolator().keyValue[j * 3],
                                          interactiveObject.getInterpolator().keyValue[j * 3 + 1],
                                          interactiveObject.getInterpolator().keyValue[j * 3 + 2] });
                      }
                  }  //  end translation
  
                  else if ((interactiveObject.getDefinedItemToField().toLowerCase().endsWith(ROTATION)) ||
                          (interactiveObject.getDefinedItemToField().toLowerCase().endsWith(ORIENTATION))) {
                      gvrAnimatedObject = root
                              .getSceneObjectByName((interactiveObject.getDefinedItem().getName() + x3dObject.TRANSFORM_ROTATION_));
                      gvrAnimationChannel = new GVRAnimationChannel(
                              gvrAnimatedObject.getName(), 0,
                              interactiveObject.getInterpolator().key.length, 0,
                              GVRAnimationBehavior.DEFAULT, GVRAnimationBehavior.DEFAULT);
  
                      for (int j = 0; j < interactiveObject.getInterpolator().key.length; j++) {
                          AxisAngle4f axisAngle4f = new AxisAngle4f(
                                  interactiveObject.getInterpolator().keyValue[j * 4 + 3],
                                  interactiveObject.getInterpolator().keyValue[j * 4],
                                  interactiveObject.getInterpolator().keyValue[j * 4 + 1],
                                  interactiveObject.getInterpolator().keyValue[j * 4 + 2]);
                          Quaternionf q = new Quaternionf(axisAngle4f);
                          float[] tmp = new float[]{ q.x, q.y, q.z, q.w};
                          gvrAnimationChannel.setRotKeyQuaternion(j,
                                  interactiveObject.getInterpolator().key[j]
                                          * interactiveObject.getTimeSensor().getCycleInterval(),
                                          tmp);
                      }
                  }   //  end rotation
  
                  else if (interactiveObject.getDefinedItemToField().toLowerCase().endsWith(SCALE)) {
                      gvrAnimatedObject = root
                              .getSceneObjectByName((interactiveObject.getDefinedItem().getName() + x3dObject.TRANSFORM_SCALE_));
                      gvrAnimationChannel = new GVRAnimationChannel(
                              gvrAnimatedObject.getName(), 0, 0,
                              interactiveObject.getInterpolator().key.length, GVRAnimationBehavior.DEFAULT,
                              GVRAnimationBehavior.DEFAULT);
                      for (int j = 0; j < interactiveObject.getInterpolator().key.length; j++) {
                          gvrAnimationChannel.setScaleKeyVector(j,
                                  interactiveObject.getInterpolator().key[j]
                                          * interactiveObject.getTimeSensor().getCycleInterval(),
                                          new float[] { interactiveObject.getInterpolator().keyValue[j * 3],
                                          interactiveObject.getInterpolator().keyValue[j * 3 + 1],
                                          interactiveObject.getInterpolator().keyValue[j * 3 + 2] });
                      }
                  }  //  end scale
                  else {
                      Log.e(TAG, "'" + interactiveObject.getDefinedItemToField() + "' not implemented");
                  }
  
                  // Second, set up the KeyFrameAnimation object
                  if (gvrAnimatedObject != null) {
                      gvrKeyFrameAnimation = new GVRNodeAnimation(
                              gvrAnimatedObject.getName() + KEY_FRAME_ANIMATION + animationCount,
                              gvrAnimatedObject,
                              interactiveObject.getTimeSensor().getCycleInterval(),
                              gvrAnimationChannel);
                      if (interactiveObject.getTimeSensor().getLoop()) {
                          gvrKeyFrameAnimation.setRepeatMode(GVRRepeatMode.REPEATED);
                          gvrKeyFrameAnimation.setRepeatCount(-1);
                      }
                      animationCount++;
                      interactiveObject.getTimeSensor().addGVRKeyFrameAnimation( gvrKeyFrameAnimation );
  
                      // Third, determine if this will be animation only, or
                      // interactive triggered in picking
                      if (interactiveObject.getSensor() == null) {
                          // this is an animation without interactivity
                          gvrAnimator.addAnimation(gvrKeyFrameAnimation);
  
                      } else {
                          // this is an interactive object
                          final InteractiveObject interactiveObjectFinal = interactiveObject;
                          final GVRNodeAnimation gvrKeyFrameAnimationFinal = gvrKeyFrameAnimation;
                          interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                                  new GVRSceneObject.SceneVisitor()
                                  {
                                      public boolean visit (GVRSceneObject obj)
                                      {
                                          obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                          return true;
                                      }
                                  });
  
                          interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                              boolean isRunning;
  
                              @Override
                              public void onSensorEvent(SensorEvent event) {
                                  //Setup SensorEvent callback here
                                  if ((event.isOver() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_OVER)) ||
                                          (event.isActive() && interactiveObjectFinal.getSensorFromField().equals(Sensor
                                                  .IS_ACTIVE))) {
                                      if (!isRunning) {
                                          isRunning = true;
                                          interactiveObjectFinal.getSensor().setHitPoint(event.getPickedObject().getHitLocation());
                                          gvrKeyFrameAnimationFinal.start(gvrContext.getAnimationEngine())
                                                  .setOnFinish(new GVROnFinish() {
                                                      @Override
                                                      public void finished(GVRAnimation animation) {
                                                          isRunning = false;
                                                      }
                                                  });
                                      }
                                  }
                              }
                          });
  
                      }
                  } else {
                      Log.e(TAG, "'" + interactiveObject.getDefinedItem().getName() + "' possibly not found in the scene.");
                  }
              }  // end if at least timer, interpolator and defined object
  
              // Sensor (such as TouchSensor) to an EventUnity (such as BoleanToggle)
              //   to a DEFined Object
              else if ((interactiveObject.getSensor() != null) &&
                      (interactiveObject.getEventUtility() != null) &&
                      (interactiveObject.getDefinedItem() != null)) {
                  // a sensor, eventUtility (such as BooleanToggle) and defined object found
                  final InteractiveObject interactiveObjectFinal = interactiveObject;
                  final Vector<InteractiveObject> interactiveObjectsFinal = interactiveObjects;
  
                  if (interactiveObject.getSensor().getSensorType() == Sensor.Type.TOUCH) {
                      interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                              new GVRSceneObject.SceneVisitor()
                              {
                                  public boolean visit (GVRSceneObject obj)
                                  {
                                      obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                      return true;
                                  }
                              });
                      interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                          boolean stateChanged = false;
  
                          @Override
                          public void onSensorEvent(SensorEvent event) {
                              if ((event.isOver() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_OVER)) ||
                                      (event.isActive() && interactiveObjectFinal.getSensorFromField().equals(Sensor
                                              .IS_ACTIVE))) {
                                  if (!stateChanged) {
                                      stateChanged = true;
                                      EventUtility eventUtility = interactiveObjectFinal.getEventUtility();
                                      eventUtility.setToggle(!eventUtility.getToggle());
                                      for (InteractiveObject interactiveObject : interactiveObjectsFinal) {
                                          if (interactiveObject.getEventUtility() == interactiveObjectFinal.getEventUtility()) {
                                              GVRSceneObject gvrSceneObject = root
                                                      .getSceneObjectByName(interactiveObject.getDefinedItem().getName());
                                              GVRComponent gvrComponent = gvrSceneObject.getComponent(
                                                      GVRLight.getComponentType());
                                              gvrComponent.setEnable(eventUtility.getToggle());
                                          }
                                      }
                                  }
                              } else if (!event.isActive() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_ACTIVE)) {
                                  stateChanged = false;
                              } else if (!event.isOver() && interactiveObjectFinal.getSensorFromField().equals(Sensor
                                      .IS_OVER)) {
                                  stateChanged = false;
                              }
                          }
                      });
                  }  // end if sensor == TOUCH
              }  // end if at least sensor, eventUtility and defined object
  
              // Sensor (PlaneSensor, TouchSensor, etc) to a Script
              //   that sets properties of a DEFined Object
              else if (interactiveObject.getScriptObject() != null) {
                  // A Sensor with a Script and defined object found
                  final InteractiveObject interactiveObjectFinal = interactiveObject;
  
                  if (interactiveObject.getSensor() != null) {
                      if (interactiveObject.getSensor().getSensorType() == Sensor.Type.PLANE) {
                          // a Plane Sensor
                          interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                                  new GVRSceneObject.SceneVisitor()
                                  {
                                      public boolean visit (GVRSceneObject obj)
                                      {
                                          obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                          return true;
                                      }
                                  });
                          interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                              boolean initialized = false;
                              GVRCameraRig gvrCameraRig = gvrContext.getMainScene().getMainCameraRig();
                              Vector3f initCameraDir = null;
                              float[] initPlaneTranslation = new float[3];
                              float[] initHitLocation = null;
                              float[] planeTranslation = new float[3];
                              GVRSceneObject gvrSceneObject = null;
  
                              @Override
                              public void onSensorEvent(SensorEvent event) {
                                  if (event.isActive()) {
                                      GVRPicker.GVRPickedObject gvrPickedObject = event.getPickedObject();
                                      if ( !initialized ) {
                                          initialized = true;
                                          float[] lookAt = gvrCameraRig.getLookAt();
                                          initCameraDir = new Vector3f(lookAt[0], lookAt[1], lookAt[2]);
                                          initHitLocation = gvrPickedObject.getHitLocation();
                                          GVRSceneObject hitObjectSceneObject = gvrPickedObject.getHitObject();
                                          // Primitives are a child of the GVRSceneObject with the name.
                                          if ( hitObjectSceneObject.getName().isEmpty() ) {
                                              hitObjectSceneObject = hitObjectSceneObject.getParent();
                                          }
                                          gvrSceneObject = root
                                                  .getSceneObjectByName((hitObjectSceneObject.getName() + x3dObject.TRANSFORM_TRANSLATION_));
  
                                          initPlaneTranslation[0] = gvrSceneObject.getTransform().getPositionX();
                                          initPlaneTranslation[1] = gvrSceneObject.getTransform().getPositionY();
                                          initPlaneTranslation[2] = gvrSceneObject.getTransform().getPositionZ();
                                      }
                                      // initialize the input values for planeSensor and run the javaScript.
                                      planeTranslation[0] = gvrSceneObject.getTransform().getPositionX();
                                      planeTranslation[1] = gvrSceneObject.getTransform().getPositionY();
                                      Object[] parameters = SetJavaScriptArguments(interactiveObjectFinal, planeTranslation[0], planeTranslation[1], 0, 0,true);
                                      ScriptObject scriptObject = interactiveObjectFinal.getScriptObject();
                                      ScriptObject.Field firstField = scriptObject.getField(0);
                                      RunScript(interactiveObjectFinal, scriptObject.getFieldName(firstField), parameters);
  
                                  }
                                  else {
                                      initialized = false;
                                  }
                              }
                          });
  
                      }  // end if sensor == PLANESensor
                      else if (interactiveObject.getSensor().getSensorType() == Sensor.Type.TOUCH) {
                          // A Touch Sensor
                          interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                                  new GVRSceneObject.SceneVisitor()
                                  {
                                      public boolean visit (GVRSceneObject obj)
                                      {
                                          obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                          return true;
                                      }
                                  });
                          interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                              boolean stateChanged = false;
                              boolean isActiveDone = false;
  
                              @Override
                              public void onSensorEvent(SensorEvent event) {
  
                                  Object[] parameters = SetJavaScriptArguments(interactiveObjectFinal, event.isOver(), 0, 0, 0, stateChanged);
                                  ScriptObject scriptObject = interactiveObjectFinal.getScriptObject();
                                  ScriptObject.Field firstField = scriptObject.getField(0);
                                  String functionName = scriptObject.getFieldName(firstField);
  
                                  if (interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_OVER)) {
                                      parameters[0] = event.isOver();
                                  }
                                  else if (interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_ACTIVE)) {
                                      parameters[0] = stateChanged;
                                  }
                                  if (scriptObject.getTimeStampParameter()) {
                                      parameters[1] = 0;  // set timeStamp to 0.  This isn't used for isOver/isActive events
                                  }
  
                                  if ((event.isOver() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_OVER))) {
                                      // OVER an object with a sensor
                                      if (!stateChanged) {
                                          stateChanged = true;
                                          // Run this SCRIPT's actual JavaScript function
                                          RunScript(interactiveObjectFinal, functionName, parameters);
                                      }
                                  } else if (event.isActive() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_ACTIVE)) {
                                      // CLICKED while over a sensored object
                                      stateChanged = !stateChanged;
                                      if (!isActiveDone) {
                                          // Run this SCRIPT's actual JavaScript function
                                          RunScript(interactiveObjectFinal, functionName, parameters);
                                      }
                                      isActiveDone = true;
                                  } else if (!event.isOver() && interactiveObjectFinal.getSensorFromField().equals(Sensor
                                          .IS_OVER)) {
                                      // An "isOver event', but just existed being over the object - i.e. TouchSensor = false
                                      stateChanged = false;
                                      // Run this SCRIPT's actual JavaScript function
                                      RunScript(interactiveObjectFinal, functionName, parameters);
                                  } else if (!event.isActive() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_ACTIVE)) {
                                      isActiveDone = false;
                                  }
                              }
                          });
                      }  // end if sensor == TOUCH
                      else if (interactiveObject.getSensor().getSensorType() == Sensor.Type.CYLINDER) {
                          interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                                  new GVRSceneObject.SceneVisitor()
                                  {
                                      public boolean visit (GVRSceneObject obj)
                                      {
                                          obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                          return true;
                                      }
                                  });
                          Sensor cylSensor = interactiveObject.getSensor();
                          final float minAngleFinal = cylSensor.getMinAngle().getValue();
                          final float maxAngleFinal = cylSensor.getMaxAngle().getValue();
  
                          interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                              boolean initialized = false;
                              Quaternionf cylinderRotation = new Quaternionf();
                              AxisAngle4f cylRotAxisAngle = new AxisAngle4f();
                              GVRSceneObject gvrSceneObject = null;
  
                              @Override
                              public void onSensorEvent(SensorEvent event) {
                                  if (event.isActive()) {
                                      GVRPicker.GVRPickedObject gvrPickedObject = event.getPickedObject();
                                      if ( !initialized ) {
                                          initialized = true;
                                          GVRSceneObject hitObjectSceneObject = gvrPickedObject.getHitObject();
                                          // Primitives are a child of the GVRSceneObject with the name.
                                          while ( hitObjectSceneObject.getName().isEmpty() ) {
                                              hitObjectSceneObject = hitObjectSceneObject.getParent();
                                          }
                                          gvrSceneObject = root
                                                  .getSceneObjectByName((hitObjectSceneObject.getName() + x3dObject.TRANSFORM_ROTATION_));
                                      }  //  end initialization
                                      // initialize the input values for planeSensor and run the javaScript.
                                      cylinderRotation.w = gvrSceneObject.getTransform().getRotationW();
                                      cylinderRotation.x = gvrSceneObject.getTransform().getRotationX();
                                      cylinderRotation.y = gvrSceneObject.getTransform().getRotationY();
                                      cylinderRotation.z = gvrSceneObject.getTransform().getRotationZ();
                                      cylinderRotation.get( cylRotAxisAngle );
  
                                      // Quaternion to Axis-Angle flips the sign on the rotation
                                      if ( cylRotAxisAngle.angle > Math.PI) cylRotAxisAngle.angle = (float)(2*Math.PI - cylRotAxisAngle.angle);
                                      else cylRotAxisAngle.angle = -cylRotAxisAngle.angle;
                                      if (cylRotAxisAngle.angle < minAngleFinal ) cylRotAxisAngle.angle = minAngleFinal;
                                      else if (cylRotAxisAngle.angle > maxAngleFinal ) cylRotAxisAngle.angle = maxAngleFinal;
  
                                      Object[] parameters = SetJavaScriptArguments(interactiveObjectFinal, cylRotAxisAngle.angle, cylRotAxisAngle.x,
                                              cylRotAxisAngle.y, cylRotAxisAngle.z,true);
                                      ScriptObject scriptObject = interactiveObjectFinal.getScriptObject();
                                      ScriptObject.Field firstField = scriptObject.getField(0);
                                      RunScript(interactiveObjectFinal, scriptObject.getFieldName(firstField), parameters);
                                  }
                                  else {
                                      initialized = false;
                                  }
                              }
                          });
                      }  //  end if Cylinder Sensor
                      else if (interactiveObject.getSensor().getSensorType() == Sensor.Type.SPHERE) {
  
                          //Set up the Sensor call back
                          interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                                  new GVRSceneObject.SceneVisitor()
                                  {
                                      public boolean visit (GVRSceneObject obj)
                                      {
                                          obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                          return true;
                                      }
                                  });
                          interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                              boolean initialized = false;
                              Quaternionf sphereRotation = new Quaternionf();
                              AxisAngle4f sphereRotAxisAngle = new AxisAngle4f();
                              GVRSceneObject gvrSceneObject = null;
  
                              @Override
                              public void onSensorEvent(SensorEvent event) {
                                  if (event.isActive()) {
                                      GVRPicker.GVRPickedObject gvrPickedObject = event.getPickedObject();
                                      if ( !initialized ) {
                                          initialized = true;
                                          GVRSceneObject hitObjectSceneObject = gvrPickedObject.getHitObject();
                                          // Primitives are a child of the GVRSceneObject with the name.
                                          while ( hitObjectSceneObject.getName().isEmpty() ) {
                                              hitObjectSceneObject = hitObjectSceneObject.getParent();
                                          }
                                          gvrSceneObject = root
                                                  .getSceneObjectByName((hitObjectSceneObject.getName() + x3dObject.TRANSFORM_ROTATION_));
  
                                      }  //  end initialization
                                      // initialize the input values for planeSensor and run the javaScript.
                                      sphereRotation.w = gvrSceneObject.getTransform().getRotationW();
                                      sphereRotation.x = gvrSceneObject.getTransform().getRotationX();
                                      sphereRotation.y = gvrSceneObject.getTransform().getRotationY();
                                      sphereRotation.z = gvrSceneObject.getTransform().getRotationZ();
                                      sphereRotation.get( sphereRotAxisAngle );
  
                                      // Quaternion to Axis-Angle flips the sign on the rotation
                                      if ( sphereRotAxisAngle.angle > Math.PI) sphereRotAxisAngle.angle = (float)(2*Math.PI - sphereRotAxisAngle.angle);
                                      else sphereRotAxisAngle.angle = -sphereRotAxisAngle.angle;
                                      Object[] parameters = SetJavaScriptArguments(interactiveObjectFinal, sphereRotAxisAngle.angle, sphereRotAxisAngle.x,
                                              sphereRotAxisAngle.y, sphereRotAxisAngle.z,true);
                                      ScriptObject scriptObject = interactiveObjectFinal.getScriptObject();
                                      ScriptObject.Field firstField = scriptObject.getField(0);
                                      RunScript(interactiveObjectFinal, scriptObject.getFieldName(firstField), parameters);
                                  }
                                  else {
                                      initialized = false;
                                  }
                              }  // end onSensorEvent
                          });
                      } // end if sphere Sensor
                  }   // end if sensor != null
                  else if (interactiveObject.getTimeSensor() != null) {
                      // TimeSensor means this Script will be called per-frame
                      // set up the call-back
                      interactiveObject.getScriptObject().setScriptCalledPerFrame(true);
                      perFrameScripting.setInteractiveObjectVars(interactiveObjectFinal);
                  } // time sensor != null
  
              }  // end if a Script (that likely includes a sensor)
  
              else if ((interactiveObject.getSensor() != null) &&
                      (interactiveObject.getDefinedItem() != null)) {
                  // a sensor and defined object, such as a TouchSensor
                  //    to a Boolean such as light on/off
                  final InteractiveObject interactiveObjectFinal = interactiveObject;
                  if (interactiveObject.getSensor().getSensorType() == Sensor.Type.TOUCH) {
                      interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                              new GVRSceneObject.SceneVisitor() {
                                  public boolean visit(GVRSceneObject obj) {
                                      obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                      return true;
                                  }
                              });
                      interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                          boolean isMovieStateSet = false;
  
                          @Override
                          public void onSensorEvent(SensorEvent event) {
                              //Setup SensorEvent callback here
                              GVRSceneObject gvrSceneObject = root
                                      .getSceneObjectByName(interactiveObjectFinal.getDefinedItem().getName());
                              GVRComponent gvrComponent = gvrSceneObject.getComponent(GVRLight.getComponentType());
  
                              if (gvrComponent != null) {
                                  if (event.isOver() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_OVER)) {
                                      if (gvrComponent != null) gvrComponent.setEnable(true);
                                  } else {
                                      if (gvrComponent != null) gvrComponent.setEnable(false);
                                  }
                              } else if (gvrSceneObject instanceof GVRVideoSceneObject) {
                                  // isOver, but only go thru once per isOver.
                                  if (event.isOver() && !isMovieStateSet) {
                                      GVRVideoSceneObject gvrVideoSceneObject = (GVRVideoSceneObject) gvrSceneObject;
                                      GVRVideoSceneObjectPlayer gvrVideoSceneObjectPlayer = gvrVideoSceneObject.getMediaPlayer();
                                      try {
                                          if (interactiveObjectFinal.getSensorFromField().contains("touchTime")) {
                                              if (interactiveObjectFinal.getDefinedItemToField().endsWith("stopTime")) {
                                                  gvrVideoSceneObjectPlayer.pause();
                                                  ExoPlayer exoPlayer = (ExoPlayer) gvrVideoSceneObjectPlayer.getPlayer();
                                                  exoPlayer.seekTo(0);
                                              } else if (interactiveObjectFinal.getDefinedItemToField().endsWith("pauseTime")) {
                                                  gvrVideoSceneObjectPlayer.pause();
                                              } else if (interactiveObjectFinal.getDefinedItemToField().endsWith("startTime")) {
                                                  gvrVideoSceneObjectPlayer.start();
                                              } else {
                                                  Log.e(TAG, "Error: ROUTE to MovieTexture, " + interactiveObjectFinal.getDefinedItemToField() + " not implemented");
                                              }
                                          } else {
                                              Log.e(TAG, "Error: ROUTE to MovieTexture, " + interactiveObjectFinal.getSensorFromField() + " not implemented");
                                          }
                                      } catch (IllegalStateException e) {
                                          Log.e(TAG, "X3D Movie Texture: IllegalStateException: " + e);
                                          e.printStackTrace();
                                      } catch (Exception e) {
                                          Log.e(TAG, "X3D Movie Texture Exception: " + e);
                                          e.printStackTrace();
                                      }
                                      isMovieStateSet = true;
                                  } // end if event.isOver()
                                  else if (!event.isOver() && isMovieStateSet) {
                                      // No longer over the TouchSensor
                                      isMovieStateSet = false;
                                  }
                              } // end if gvrSceneObject
                          }
                      });
                  }  // end if sensor == TOUCH
                  else if (interactiveObject.getSensor().getSensorType() == Sensor.Type.PLANE) {
                      interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                              new GVRSceneObject.SceneVisitor() {
                                  public boolean visit(GVRSceneObject obj) {
                                      obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                      return true;
                                  }
                              });
                      interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                          boolean isActive = false;
  
                          @Override
                          public void onSensorEvent(SensorEvent event) {
                              if (interactiveObjectFinal.getSensor().getEnabled()) {
                                  if (event.isActive() && !isActive) {
                                      isActive = true;
                                      GVRPicker.GVRPickedObject gvrPickedObject = event.getPickedObject();
  
                                      sensorImplementation.registerDrawFrameListerner(gvrPickedObject, interactiveObjectFinal);
                                  } else if (!event.isActive() || !event.isOver()) {
                                      sensorImplementation.unregisterDrawFrameListerner();
                                      GVRPicker.GVRPickedObject gvrPickedObject = null;
                                      isActive = false;
                                  }
                              }// if PlaneSensor is enabled
                          }   // end onSensorEvent
                      });
                  }  // end if sensor == PLANESensor
                  else if (interactiveObject.getSensor().getSensorType() == Sensor.Type.CYLINDER) {
                      interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                              new GVRSceneObject.SceneVisitor()
                              {
                                  public boolean visit (GVRSceneObject obj)
                                  {
                                      obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                      return true;
                                  }
                              });
                      interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                          boolean isActive = false;
  
                          @Override
                          public void onSensorEvent(SensorEvent event) {
                              if (interactiveObjectFinal.getSensor().getEnabled()) {
                                  if (event.isActive() && !isActive) {
                                      isActive = true;
                                      GVRPicker.GVRPickedObject gvrPickedObject = event.getPickedObject();
                                      sensorImplementation.registerDrawFrameListerner(gvrPickedObject, interactiveObjectFinal);
                                  } else if (!event.isActive() || !event.isOver()) {
                                      sensorImplementation.unregisterDrawFrameListerner();
                                      isActive = false;
                                  }
                              }// if CylinderSensor is enabled
                          }   // end onSensorEvent
                      });
                  }  // end if sensor == CylinderSensor
                  else if (interactiveObject.getSensor().getSensorType() == Sensor.Type.SPHERE) {
                      interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                              new GVRSceneObject.SceneVisitor()
                              {
                                  public boolean visit (GVRSceneObject obj)
                                  {
                                      obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                      return true;
                                  }
                              });
                      interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                          boolean isActive = false;
  
                          @Override
                          public void onSensorEvent(SensorEvent event) {
                              if (interactiveObjectFinal.getSensor().getEnabled()) {
                                  if (event.isActive() && !isActive) {
                                      isActive = true;
                                      GVRPicker.GVRPickedObject gvrPickedObject = event.getPickedObject();
                                      sensorImplementation.registerDrawFrameListerner(gvrPickedObject, interactiveObjectFinal);
                                  } else if (!event.isActive() || !event.isOver()) {
                                      sensorImplementation.unregisterDrawFrameListerner();
                                      isActive = false;
                                  }
                              }// if SphereSensor is enabled
                          }   // end onSensorEvent
                      });
                  }  // end if sensor == SphereSensor
  
              }  //  end sensor and definedItem != null
              // Sensor (such as TouchSensor) to an EventUnity (such as BoleanToggle)
              else if ((interactiveObject.getSensor() != null) &&
                      (interactiveObject.getEventUtility() != null)) {
                  // a sensor, eventUtility (such as BooleanToggle) and defined object found
                  final InteractiveObject interactiveObjectFinal = interactiveObject;
                  final Vector<InteractiveObject> interactiveObjectsFinal = interactiveObjects;
  
                  if (interactiveObject.getSensor().getSensorType() == Sensor.Type.TOUCH) {
                      interactiveObject.getSensor().getOwnerObject().forAllDescendants(
                              new GVRSceneObject.SceneVisitor()
                              {
                                  public boolean visit (GVRSceneObject obj)
                                  {
                                      obj.attachCollider(new GVRMeshCollider(gvrContext, true));
                                      return true;
                                  }
                              });
                      interactiveObject.getSensor().addISensorEvents(new ISensorEvents() {
                          boolean stateChanged = false;
  
                          @Override
                          public void onSensorEvent(SensorEvent event) {
                              if ((event.isOver() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_OVER)) ||
                                      (event.isActive() && interactiveObjectFinal.getSensorFromField().equals(Sensor
                                              .IS_ACTIVE))) {
                                  if (!stateChanged) {
                                      // only change state upon first rollover, not the 'roll off'
                                      stateChanged = true;
                                      EventUtility eventUtility = interactiveObjectFinal.getEventUtility();
                                      eventUtility.setToggle(!eventUtility.getToggle());
                                  }
                              } else if (!event.isActive() && interactiveObjectFinal.getSensorFromField().equals(Sensor.IS_ACTIVE)) {
                                  stateChanged = false;
                              } else if (!event.isOver() && interactiveObjectFinal.getSensorFromField().equals(Sensor
                                      .IS_OVER)) {
                                  stateChanged = false;
                              }
                          }
                      });
                  }  // end if sensor == TOUCH
              }  // end if at least sensor, and eventUtility
              else if (interactiveObject.getSensor() != null) {
                  // Likely this is an Anchor tag since there are no routes with it
                  if ( interactiveObject.getSensor().getSensorType() == Sensor.Type.ANCHOR) {
                      anchorImplementation.AnchorInteractivity( interactiveObject );
                  }  //  end if Sensor Type is Anchor
              } // end sensor != null
  
          }  // end for loop traversing through all interactive objects
          // Initiate all the animations, both keyframe and procedural
          if (perFrameScripting.getRunState()) {
              final GVRDrawFrameListener mOnDrawFrame = new DrawFrame();
              gvrContext.registerDrawFrameListener(mOnDrawFrame);
          }
      }