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);
     }
   }
 }
  /**
   * Build a tree of RenderObjects that mirrors the tree of SceneObjects in <scene>.
   *
   * <p>After the objects are created and linked up using the RenderObject.parent and
   * RenderObject.children fields, the frame-to-world transformations of all objects are computed.
   *
   * @param scene
   * @param env
   */
  public static void buildTree(Scene scene, RenderEnvironment env) {
    // Clear Out Any Old Data
    env.cameras.clear();
    env.lights.clear();

    // Pass 1: Create The Render Object Mapping
    HashMap<String, RenderObject> dict = new HashMap<>();
    for (SceneObject so : scene.objects) {
      RenderObject ro;

      if (so instanceof SceneCamera) {
        ro = new RenderCamera(so, env.viewportSize);
        env.cameras.add((RenderCamera) ro);
      } else if (so instanceof SceneLight) {
        ro = new RenderLight(so);
        env.lights.add((RenderLight) ro);
      } else {
        ro = new RenderObject(so);
      }
      dict.put(so.getID().name, ro);
    }

    // Pass 2: Create Parent-Children Bindings
    for (SceneObject so : scene.objects) {
      if (so.parent != null) {
        // Get The Child
        RenderObject o = dict.get(so.getID().name);
        if (o != null) {
          // Get The Parent
          RenderObject p = dict.get(so.parent);
          if (p != null) {
            // Bind Child And Parent
            p.children.add(o);
            o.parent = p;
          }
        }
      }
    }

    // Pass 3: Find A Root Node If It Exists
    env.root = dict.get("World");
    rippleTransformations(env);

    // Set Up Render State
    env.linkObjectResources();
  }
  public void checkPicking(Renderer renderer, RenderCamera camera, int mx, int my) {
    if (camera == null) return;

    // Pick An Object
    renderer.beginPickingPass(camera);
    renderer.drawPassesPick();
    if (currentObject != null) {
      // Draw Object Manipulators
      GL11.glClearDepth(1.0);
      GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);

      DepthState.DEFAULT.set();
      BlendState.OPAQUE.set();
      RasterizerState.CULL_NONE.set();

      drawPick(camera, currentObject, renderer.pickProgram);
    }
    int id = renderer.getPickID(Mouse.getX(), Mouse.getY());

    selectedManipulator = manips.get(id);
    if (selectedManipulator != null) {
      // Begin Manipulator Operations
      System.out.println(
          "Selected Manip: " + selectedManipulator.type + " " + selectedManipulator.axis);
      return;
    }

    SceneObject o = scene.objects.get(id);
    if (o != null) {
      System.out.println("Picked An Object: " + o.getID().name);
      if (scenePanel != null) {
        scenePanel.select(o.getID().name);
        propWindow.tabToForefront("Object");
      }
      currentObject = rEnv.findObject(o);
    } else if (currentObject != null) {
      currentObject = null;
    }
  }