public RenderController(Scene s, Vector2 viewSize) {
   scene = s;
   queue = new SceneEventQueue(scene);
   scene.addListener(queue);
   env = RenderTreeBuilder.build(scene, viewSize);
   animEngine = new AnimationEngine(scene);
   for (SceneObject o : scene.objects) {
     if (o instanceof SceneCamera) {
       System.out.println("Camera " + o.getID().name + " will not be animated");
     } else {
       animEngine.addObject(o.getID().name, o);
     }
   }
 }
 public void checkMouse(int mx, int my, RenderCamera camera) {
   Vector2 curMousePos =
       new Vector2(mx, my)
           .add(0.5f)
           .mul(2)
           .div(camera.viewportSize.x, camera.viewportSize.y)
           .sub(1);
   if (curMousePos.x != lastMousePos.x || curMousePos.y != lastMousePos.y) {
     if (selectedManipulator != null && currentObject != null) {
       applyTransformation(selectedManipulator, camera, currentObject, lastMousePos, curMousePos);
       scene.sendEvent(new SceneTransformationEvent(currentObject.sceneObject));
     }
     lastMousePos.set(curMousePos);
   }
 }
  /**
   * Update the camera's transformation matrix in response to user input.
   *
   * <p>Pairs of keys are available to translate the camera in three direction oriented to the
   * camera, and to rotate around three axes oriented to the camera. Mouse input can also be used to
   * rotate the camera around the horizontal and vertical axes. All effects of these controls are
   * achieved by altering the transformation stored in the SceneCamera that is referenced by the
   * RenderCamera this controller is associated with.
   *
   * @param et time elapsed since previous frame
   */
  public void update(double et) {
    Vector3 motion = new Vector3();
    Vector3 rotation = new Vector3();

    if (Keyboard.isKeyDown(Keyboard.KEY_W)) {
      motion.add(0, 0, -1);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_S)) {
      motion.add(0, 0, 1);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
      motion.add(-1, 0, 0);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_D)) {
      motion.add(1, 0, 0);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT)) {
      motion.add(0, -1, 0);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_SPACE)) {
      motion.add(0, 1, 0);
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_E)) {
      rotation.add(0, 0, -1);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_Q)) {
      rotation.add(0, 0, 1);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) {
      rotation.add(-1, 0, 0);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_UP)) {
      rotation.add(1, 0, 0);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT)) {
      rotation.add(0, -1, 0);
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_LEFT)) {
      rotation.add(0, 1, 0);
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_O)) {
      orbitMode = true;
    }
    if (Keyboard.isKeyDown(Keyboard.KEY_F)) {
      orbitMode = false;
    }

    boolean thisFrameButtonDown =
        Mouse.isButtonDown(0)
            && !(Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)
                || Keyboard.isKeyDown(Keyboard.KEY_RCONTROL));
    int thisMouseX = Mouse.getX(), thisMouseY = Mouse.getY();
    if (thisFrameButtonDown && prevFrameButtonDown) {
      rotation.add(0, -0.1f * (thisMouseX - prevMouseX), 0);
      rotation.add(0.1f * (thisMouseY - prevMouseY), 0, 0);
    }
    prevFrameButtonDown = thisFrameButtonDown;
    prevMouseX = thisMouseX;
    prevMouseY = thisMouseY;

    RenderObject parent = rEnv.findObject(scene.objects.get(camera.sceneObject.parent));
    Matrix4 pMat = parent == null ? new Matrix4() : parent.mWorldTransform;
    if (motion.lenSq() > 0.01) {
      motion.normalize();
      motion.mul(5 * (float) et);
      translate(pMat, camera.sceneObject.transformation, motion);
    }
    if (rotation.lenSq() > 0.01) {
      rotation.mul((float) (100.0 * et));
      rotate(pMat, camera.sceneObject.transformation, rotation);
    }
    scene.sendEvent(new SceneTransformationEvent(camera.sceneObject));
  }